分类:
2008-07-18 21:37:13
该属性的作用是读取用户session中的locale属性并显示出来。比如用户使用的是zh-CN,那么,生成的页面代码将如下所示:
不过,从Struts1.2开始,该属性被lang所取代。原因是locale属性当其值为true时,会读取session中的locale信息。但是当HttpSession不存在时,它会强制创建一个新的session并将HTTP请求中的locale信息放入session中去。这种方式时显并不合理,因此,从Struts1.2开始,locale属性被lang属性所取代
当使用lang属性后,若没有session对象时,就根据Http请求中的locale信息来输出相应的语言信息。
当经过Web容器编译后,会生成如下的一段标记。
这也就是本网页的实际的URL地址。请记住,base标记将不会被显式的显示在网页上,只有通过查看生成的 html源代码才可以看得见。其实,base标记的含义不仅是生成本网页的URL,它更重要的功能是为该页面内的所有其它链接提供相对的位置。例如,在本网页使用了
这张图片的实际URL就是:
http://localhost:8080/taglib1/image/image.gif
新浪网
以上代码经编译后会生成如下html代码:
当需要从同一个应用中的某个网页链接到另一个网页时,可以使用page属性,代码如下:
首页
当需要向所链接的页面传输某些参数时,可以将参数直接加在请求的尾部就可以了。例如,下面的代码示例将向测试页面传递一个字符串参数和一个整型参数:
测试页面
由它生成的页面html代码如下所示:
下面的链接是一个测试,它向测试页面传递两个参数,一个是testString,它的值为"a new string",另一个是testInt,它的值为10000。
在Struts的struts-config.xml文件中定义了
回到主页
生成的页面html代码如下所示:
在创建链接时常常需要访问一些页面的变量,将它们的值作为参数传递给将要链到的网页。
如果仅需传递单个参数,可以使用paramID与paramName这两个属性。以下为代码示例
<%
String test1 = "testABC";
request.setAttribute("stringtest",test1);
%>
测试页面
在这段程序中,首先定义一个变量为test1它的值为testABC。然后将它存入request对象中,命名为stringtest。接着,使用
如果需要传递的参数有多个,则可使用
<%
HashMap para_map = new HashMap();
para_map.put("testString","testABC");
para_map.put("testInt",new Integer(10000));
request.setAttribute("map1",para_map);
%>
在上面的代码中,首先在页面上声明一个HashMap类型的变量para_map用来存储将要传递的参数,接着,向 para_map中存入两个对象。然后再将该对象存入页面的request对象中。使用
它生成的html如下:
/struts/test.do?testString=testABC
可以看出,它输出的内容只是实际URL中除去协议,主机地址和端口号以后的部分。实际的URL应为:
它也可以使用paramId和paramName等属性,如下面的例子:
<%
String str = "testABC";
request.setAttribute("test1",str);
%>
实际生成的html代码如下所示:
/struts/test.do?testString=testABC
下面的例子将演示当有多个参数要传递时
<%
HashMap para_map = new HashMap();
para_map.put("testString","testABC");
para_map.put("testInt",new Integer(10000));
request.setAttribute("map1",para_map);
%>
实际生成的html代码如下所示:
/struts/test.do?testString=testABC&testInt=10000
这里有一点需要注意的,当从网页源代码上看生成的多参数链接时,在多个参数间连接符并不是简单的& 而是一个&,在html代码中它就代表&。
此处值得注意的一点是,在page属性后图片的路径并没有因为设定了
可以看到,在普通的form标记后的action属性的值是一个Servlet(当然也可以是一个JSP文件),而使用了
其中action属性后跟的是一个在struts-config.xml文件中定义的Action,而这个Action也必定要对应一个ActionForm才能完成其应有的功能。所以,对每个
输入字符串testString:
提交:
这段代码将在页面上显示一个文本框和一个提交按钮,当用户在文本框中输入一个字符串后并点击按钮,将会触发test这个Action。在初始化这个JSP页面时,JSP引擎在初始化
此处值得注意的一点是,在
输入字符串testString:
输入整数testInt:
通常,
可以看到,
private String testString = null;
public void setTestString(String testString){
this.testString = testString;
}
public String getTestString(){
return testString;
}
从上面的代码可以看出用户在提交表单后,Struts会自动将property="testString"的
上面的代码中将一个
在
运行效果如下所示,虽然只有短短的一个字符串,但可以看出标记还是把testString的value打印出来了。
hiddenString
它会生成如下的html代码
另外,
当用户选中其中的几项并点击提交后,ActionForm中的testStringArray数组就会被赋上相应的值。这里有一点值得注意,例如用户选择了"中国"和"英国"两项,ActionForm中testStringArray的值就会是{"中国","英国"}。
它有一个value属性,用来指定当选中该单选框时ActionForm中对应的属性的值。下面是另一种单选框的用法:
在上面的代码中,单选框一共有三个,这三个单选框组成一个单选框组,只能选取其中一个。无论选中哪一个,它的值在提交表单后都将赋给ActionForm中相对应的属性,如果三个单选框一个都没有选中,那么该属性的值将为一个空串。
运行效果如下所示:
Choice1
Choice2
Choice3
<:html:submit property="submit" value="提交"/>
其中,property表示该选择列表与ActionForm中对应的属性名。当用户点击提交后,会在测试页面看到用户所选中的选项的值。以下是代码的运行效果:
以下是multiple="true"和size="8"例子
当multiple属性为true时,在ActionForm中对应的属性应是一个数组类型以便同时向其赋上用户选中的多个值。
一个选项有两部分重要的内容。第一就是它所显示给用户的内容,这可以通过以下方式来指定:
可以看出,使用两个
另一个重要的内容就是它所传递给ActionForm的值。这是由标记的value属性指定的。如上面的例子中,value的值分别为 value1,value2和value3,当用户选中某个标记时,JSP页面就会将该标记所对应的value传给ActionForm中相应的属性。
以下是运行效果:
<%
ArrayList list = new ArrayList();
list.add(new org.apache.struts.util.LabelValueBean("Show value1","value1"));
list.add(new org.apache.struts.util.LabelValueBean("Show value2","value2"));
list.add(new org.apache.struts.util.LabelValueBean("Show value3","value3"));
list.add(new org.apache.struts.util.LabelValueBean("Show value4","value4"));
pageContext.setAttribute("valuelist",list);
%>
这是一段
在四个对象都存入list对象后,程序把list对象放入pageContext中。这样做的目的是为了让
以下是代码实际运行效果:
private TestPageBean [] pagebean = new TestPageBean[4];
public TestBean2 ()
{
super();
for (int i=0;i<4;i++){
pagebean[i]=new TestPageBean("name" + i,"value" + i);
}
}
在ActionForm中,定义一个叫做pagebean的数组对象,它的类型是TestPageBean,这个Bean只有两个属性,value和label。接下来,在ActionForm调用构造函数进行初始化时将这个pagebean数组对象进行初始化,存入四个TestPageBean类型的对象。这四个对象的value和label分别从value1到value4以及name1到name4。以下是TestPageBean的代码:
public class TestPageBean {
private String name = "";
private String value = "";
public TestPageBean(String n, String v){
name = n;
value = v;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
以下是
可以从代码中看到,
以下是以上代码的运行效果,若用户选择了name1则可在测试页面上看到与其对应的value1。
1. 文件存储于客户端的机器上,因此在服务器端不能使用获得文件路径的方式来获取文件对象。
2. 由于使用GET方式提交表单时,可提交的串长度受到限制,所以,在上传文件时必须使用POST方式。
文件上传是一项从页面开始的工作,下面首先看一下页面上的代码:
您上传的文件是:
它的大小为:
上面的代码中使用了
public class UploadBean extends ActionForm{
private FormFile file = null;
private String filename = "";
private String size = "";
public UploadBean(){
}
public FormFile getFile() {
return file;
}
public void setFile(FormFile file) {
this.file = file;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
}
在上面的代码中,定义了一个FormFile类型的对象file。这个FormFile类是Struts提供的专门用于文件上传的类。在这个ActionForm 中,FormFile类的对象file的名称与网页上
用户点击上传按钮后执行的是upload的操作,这个操作与后台的UploadAction关联。以下是UploadAction的代码:
public class UploadAction extends Action {
public ActionForward execute(ActionMapping mapping,ActionForm form,HttpServletRequest request,HttpServletResponse response) throws Exception {
UploadBean filebean = (UploadBean) form;
FormFile file = filebean.getFile();
if (file == null){
return mapping.findForward("input");
}
String filename = file.getFileName();
filebean.setFilename(filename);
String size = Integer.toString(file.getFileSize()) + "bytes";
filebean.setSize(size);
InputStream is = file.getInputStream();
String store_path = servlet.getServletContext().getRealPath("/fileupload");
System.out.println(store_path);
OutputStream os = new FileOutputStream(store_path + "/" + filename);
int bytes = 0;
byte [] buffer = new byte[8192];
while ((bytes = is.read(buffer,0,8192))!=-1){
os.write(buffer,0,bytes);
}
os.close();
is.close();
file.destroy();
return mapping.findForward("input");
}
}
上面的代码首先从表单ActionForm中获取FormFile对象,然后创建输入流读取文件内容,再创建一个输出流,将上传的文件保存到工程目录下的fileupload目录中。最后关闭输出流和输入流,并将与客户端的文件连接断开。整个过程非常清楚,简单。其中,有两句代码分别将文件名和文件大小保存到UploadBean中去,这是为了在JSP页面上可以显示出文件名和文件大小。在上面的页面代码中可以看到这样两句:
您上传的文件是:
它的大小为:
这里使用了Struts Bean标记库的标签来显示与页面相关的ActionForm的变量值。
以下是程序的运行效果,用户可以在/tablig/fileupload目录下看到上传的文件。
这里使用到的代码如下所示:
选择框:
错误信息是通过什么方式添加的呢,
另外,除了在ActionForm的validate()方法中可以添加ActionErrors外,在Action中也可以添加。通过查看struts-config.xml文件可以知道,与这个表单相关联的ActionForm和Action分别是ErrBean和ErrAction。以下先看看ErrBean的代码:
public class ErrBean extends ActionForm{
private boolean checkbox1;
public boolean isCheckbox1() {
return checkbox1;
}
public void setCheckbox1(boolean checkbox1) {
this.checkbox1 = checkbox1;
}
public void reset(ActionMapping mapping, HttpServletRequest request){
this.setCheckbox1(false);
}
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request){
ActionErrors errors = new ActionErrors();
if (checkbox1){
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionError("html.errors.error1"));
errors.add("checkbox1",new ActionError("html.errors.error2"));
}
return errors;
}
}
在
在ErrBean的validate()方法中,首先初始化一个ActionErrors对象,然后判断checkbox1是否被选中。若选中,则向ActionErrors 对象中添加两个ActionError。添加ActionError时采用的是ActionErrors的add()方法。该方法有两个参数,第一个参数是所添加ActionError 的key,然后是ActionError的值。这样做的原因是因为在ActionErrors内部保存了一个HashMap,以此来将所有的ActionError保存。其中,添加第一个ActionError的代码如下:
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionError("html.errors.error1"));
这里的ActionMessages.GLOBAL_MESSAGE的值是"org.apache.struts.action.GLOBAL_MESSAGE",它是一个常量,表示全局消息。对于每一个key来说,都可以存入多个ActionError。这是因为ActionErrors的内置的HashMap中并不是仅仅存入一个简单的ActionError 对象,而是存入一个List对象,再将多个ActionError对象存入该List中。ActionError的构造函数中的参数是资源文件中的key值,将来在页面上就将显示该key值对应的value。下面是添加第二个ActionError的代码:
errors.add("checkbox1",new ActionError("html.errors.error2"));
这个ActionError的key值为checkbox1,它表示和特定的表单元素相关的错误信息。在页面中的
通过上面的代码可以看到,用户在提交表单时由ActionForm产生了错误信息,然后转交回页面。此时,就该由页面上的
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionErrors errors = new ActionErrors();
errors.add(ActionMessages.GLOBAL_MESSAGE,new ActionError("html.errors.error3"));
saveErrors(request,errors);
return mapping.findForward("input");
}
在Action类中提供了一个saveErrors()方法,可以将ActionErrors对象存入request中。通过这个方法
前面已经看到了页面上显示的代码,下面就来讲解一下
标记可以放在网页上的任何位置,它有以下三个比较重要的属性:
name属性:它指定了存放在request或session属性中的错误对象的值。我们知道,在request或session中,对象的存储一般都以键/值对的方式来进行。ActionErrors对象在request或session中的key默认为Globals.ERROR_KEY。
property属性:用于指定与ActionError对应的key值,如前面例中的checkbox1。
bundle属性:用于指定资源文件,即显示ActionErrors信息时去哪个资源文件中读取相应的消息文本。例如在taglib1中,struts-config.xml 文件中有这样一句代码:
则在页面的
以下是几个代码示例:
上面的代码表示显示所有的错误信息。
上面的代码表示显示所有的全局消息,也就是在向ActionErrors中添加ActionError对象时,选用ActionMessages.GLOBAL_MESSAGE 做为该ActionError的key的对象。
到目前为止,所有有关
1. 将代码中使用到ActionError类的地方换为ActionMessage类。
2. 将除了在ActionForm的validate()方法以外使用到ActionErrors类的地方都替换为ActionMessages。
这样做的主要原因是,ActionError是ActionMessage的子类,而ActionErrors是ActionMessages的子类。开发者认为一个错误消息也是消息的一种,并没有必要专门将其分开存放。只需要使用Globals.MESSAGE_KEY,Globals.ERROR_KEY来进行区分就分。
例如,在ErrAction中,若要使其支持Struts1.2,则可将代码改为如下形式:
public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
ActionMessages messages = new ActionMessages();
messages.add(ActionMessages.GLOBAL_MESSAGE,new ActionMessage("html.errors.error3"));
saveErrors(request,messages);
return mapping.findForward("input");
}