struts2随笔

1、struts.properties配置常量等同于struts.xml中配置(置于类加载路径下面)
struts.multipart.maxSize文件上传最大大小
struts.action.extension默认struts处理的请求后缀
struts.enable.DynamicMethodInvocation是否支持动态方法调用,默认为true支持
struts.devMode开启开发模式
struts.ui.theme指定视图标签默认的视图主题
struts.custom.i18n.resources指定struts应用所需要的国际化资源文件如果有多个国际化资源,则多个资源文件名以,隔开
2、struts.xml、struts.properties、web.xml文件均能配置常量
3、在struts.xml文件中,通过<include file="">来包含其它配置文件,避免配置文件臃肿
4、在action中系统不会严格区分哪个是封装请求参数的属性,哪个是封装处理结果的属性,这两个都是平等的。
同样,在jsp中输出action属性时,它也不会严格区分该属性是封装请求参数的属性还是封装请求结果的属性。
struts2的action接口中定义了5个字符串常量,分别是:INPUT、SUCCESS、ERROR、NONE、LOGIN
5、如果用户没有配置action的class属性,那么系统自动使用ActionSupport类作为处理类。


6、Action访问Servlet API的方法:
struts2提供了一个ActionContext类,struts2的action可以通过该类访问Servlet API。下面是常见方法:
1)static ActionContext getContext()   //静态方法,访问系统的ActionContext实例
2)Object get(Object key)//类似于HttpServletRequest的getAttribute(String name)方法。
3)Map getApplication()//返回一个Map对象,该对象模拟了该应用的ServletContext实例
4)Map getParameters()//类似于HttpServletRequest的getParameterMap()方法。
5)Map getSession()//返回一个Session对象
6)void setApplication()//设置一个Application实例
7)void setSession()//设置一个Session实例
7、Action直接访问Servlet API
为了实现该功能,struts2提供了几个接口:
1)ServletContextAware,实现该接口的action可以访问Web应用的ServletContext实例
2)ServletRequestAware,实现该接口的action可以访问Web应用的ServletRequest实例
3)ServletResponseAware,实现该接口的action可以访问Web应用的ServletResponse实例
8、通过ServletActionContext工具类静态方法访问:
1)static PageContext getPageContext()//获取web应用的PageContext对象
2)static HttpServletRequest getRequest()//获取HttpServletRequest对象
3)static HttpServletResponse getResponse()//获取HttpServletResponse对象
4)static ServletContext getServletContext()//获取ServletContext对象

9、struts.xml中的命名空间
命名空间有一个级别,假设请求的url为"/bookservice/search/get.action",系统将先在/bookservice/search下面寻找名为get的action,如果查找不到的话
则直接去默认命名空间里面查找,而不会在/bookservice下面继续查找,如果默认命名空间查找不到的话,则直接报错。
10、配置默认Action
<package>
<default-action-ref name="xx" />
<action name="" class="xx" >

</action>
</package>
11、struts2的result元素
2种结果:
1)全局result   将<result..作为<global-results../>的子元素配置
2)局部result 将<result...作为<action.../>子元素配置
struts2支持的结果类型:
chain 结果类型,Action链式处理的结果类型
dispatcher 默认结果类型
freemarker 指定freemarker模板作为视图的结果类型
httpheader 用于控制特殊的http行为的结果类型
redirect 用于直接跳转到其它url的结果类型
redirecAction 用于跳转到其它action的结果类型
stream 用于向浏览器返回一个InputStream(一般用于文件下载)
velocity 用于指定vecolity模板作为视图的结果类型
xslt 用于与xml/xslt整合的结果类型
plainText 用于显示某个页面原始代码的结果类型

<result name="xxx" type="xxx">
<param name="location" >/xxx.jsp</param>
<param name="parse" >true</param>
</result>

dispatcher结果类型参数:location指定视图资源parse指定是否允许使用OGNL表达式
plainText结果类型包含参数:location指定视图资源charSet指定页面输出时使用的字符集
redirect包含参数:同dispatcher

12、使用Action的属性值决定物理视图资源
<action name="save_*" class="com.action.SaveAction">
<result name="success" >/${target}.jsp</result>
<result type="redirect" name="input">edit.action?skillName=${currentSkill.name}</result>
</action>

13、PreResultListener接口——它可以在Action完成逻辑处理之后,系统转入实际物理视图资源之前调用
可以在任意Action类的方法中添加:
ActionInvocation invocation = ActionContext.getContext().getActionInvocation();
invocation.addPreResultListener(new PreResultListener(){
public void beforeResult(ActionInvocation invocation,String resultCode){    //resultCode即为逻辑视图名称,如success,input等
System.out.println(resultCode);
}
});


14、struts2的异常处理
Struts2的异常处理机制是在struts.xml文件中配置<exception-mapping../>元素完成的。该元素包含两个属性:
->exception:指定异常类型
->result:指定逻辑视图名
根据<exception-mapping.../>元素出现的位置不同,异常映射又分为全局映射、局部映射:
->局部异常映射:在<action.../>元素的子元素中配置,仅对所在action有效
->全局映射:在<global-exception-mappings.../>中作为子元素配置,对所有action均有效

15、struts2环境下,在页面中输出异常信息:
<s:property value="exception" />:输出异常对象本身,等同于<s:property value="exception.message" />,因为exception对象内置了message属性
<s:property value="exceptionStack" />:输出异常堆栈信息

16、使用struts2的国际化
struts2中加载全局资源文件的方式:
<constant name="strust.custom.i18n.resources" value="baseName" />
struts2访问国际化消息有如下3种方式:
1)为了在jsp中输出国际化消息,应该使用struts2的<s:text  name="" .../>标签,该标签中可以指定一个name属性,其属性值对应于国际化资源文件中的key
2)为了在action中访问国际化消息,可以使用ActionSupport的getText方法,该方法可以接受一个name参数,该参数对应于国际化资源文件中的key
3)为了在该表单元素的其它标签里输出国家化消息,可以为表单标签指定一个key属性,该key对应于国际化资源文件中的key
mess_en_US.properties//该国际化资源文件的baseName为mess,属于美国英语的资源文件
mess_zh_CN.properties//简体中文的资源文件(对于包含非西欧字符的国际化资源文件必须使用native2ascii工具进行处理)
....
提供了上面的资源文件后,系统会根据浏览者所在的Locale来加载对应的语言资源文件
资源文件内容举例,实际就是一些键值对,以简体中文为例:
loginPage = 登录界面
errorPage = 错误界面
succPage = 成功界面
failTip = 对不起,您不能登录!
succTip = 欢迎,您已成功登录!
user = 用户名
pass = 密  码
login = 登录

17、输出带占位符的国际化消息,这些占位符一般由参数来代替
failTip = {0},Sorry,you can not log in!
succTip = {0},Welcome,you has logged in!
welcomeMsg = {0},Hello,now is{1}!

在action中:ctx.getSession.put("tip",getText("sucTip"),new String[]{getUserName()});  //也可以使用list对象实现
在jsp中:
<jsp:useBean id="d" class="java.util.Date" scope="page" />
<s:text name="welcomeMsg">
<s:param><s:property name="username"/></s:param>   //username为action中的属性
<s:param>${d}</s:param>
</s:text>

18、struts2加载资源文件的方式
struts2还提供包括包范围、Action范围、临时指定资源文件的方式加载资源文件

19、struts2的标签库
<%@ taglib prefix="s" uri="/strusts-tags" %>
分类:UI标签(表单标签+非表单标签)、非UI标签(数据访问标签+逻辑控制标签)、Ajax标签

20、OGNL表达式
使用OGNL表达式,在传统的OGNL求值中,系统会假设只有一个”根“对象,假设为bar,如下:
#bar.blash //返回bar.getBlash()
#foo.blash //foo.getBlash()
blash //默认执行bar.getBlash(),因为bar为”根“对象,只有”根“对象才可以直接省略#访问
struts2使用标准的Context来进行OGNL表达式的求值,OGNL的顶级对象是一个Context,这个Context是一个Map实例,其根对象就是一个ValueStack,如果需要访问
ValueStack里面属性,直接通过${bar}即可,当系统创建好action实例后,该action实例已经被封装到ValueStack中,因此无需书写#,可以直接访问。
除此之外,struts2的一些命名对象,非”根“对象:
parameters:相当于HttpServletRequest的getParameter("user")
request对象:相当于HttpServletRequest的getAttribute("user")
session对象:相当于HttpSession的getAttribute("user")
application对象:相当于ServletContext的getAttribute("user")
attr对象:该对象依次搜索如下对象中的属性:PageContext、HttpServletRequest、HttpSession、ServletContext


21、OGNL中的集合操作
创建list集合:{e1,e2,...}
创建Map集合:#{key1:value1,key2:value2,...}
取得子集操作符:
? 取出所有符合选择逻辑的元素
^ 取出符合选择逻辑的第一个元素
$ 取出符合选择逻辑的最后一个元素
如:person.relatives.{?  #this.gender == 'male'}  //取出person下的relative,条件是gender为male,?表示取出所有,#this代表当前集合中的元素

22、struts2的局部类型转换器(非自定义)
局部类型转换文件应该命名为ActionName-conversion.properties,其中ActionName是Action的类名,后面的-conversion.properties是固定部分。类型转换文件应该放在和Action的
类文件相同的位置下面。
List集合在局部类型转换文件中的写法:Element_<ListPropName> = <ElementType>
Map集合在局部类型转换文件中的写法(Map类型需要在里面同时指定key&value):key:Map_<MapPropName> = <KeyType>  value:Element_<MapPropName> = <ValueType>

23、自定义类型转换器
OGNL提供的类型转换器接口TypeConverter接口,实现类为DefaultTypeConverter,复写其中的convertValue(Map context,Object value,Class toType)方法
context,类型转化的上下文环境
value,需要转换的参数
toType,转换后的目标类型

实现了类型转换器类还不够,还必须在web应用中注册该类型转换器:
1)注册局部类型转换器:局部类型转换器仅对,某个action的属性起作用
在局部类型转换文件中添加一行:<propName> = <ConverterClass>,局部类型转换文件命名同上:ActionName-conversion.properties,且要在同一个包下面

2)注册全局类型转换器:对所有action的属性均起作用
全局类型转换文件命名:xwork-conversion.properties,文件放在类加载路径下面。
文件中可以添加多行:<propName> = <ConverterClass>,这时属性名、转换器类都要使用完整类名,包括包名。

3)使用JDK1.5用注释方式来注册类型转换器


24、DefaultTypeConverter类的子类——StrutsTypeConverter类
DefaultTypeConverter做转换时只有一个convertValue方法,该方法内部需要进行toType类型判断,而StrutsTypeConverter类是DefaultTypeConverter的子类,该类已经实现了
DefaultTypeConverter的convertValue,它将两个不同的转换方向替换成了两个不同的方法,分别是:Object convertFromString(Map context,String[] values,Class toType)、
String convertToString(Map context,Object o)方法。


25、struts2类型转换中的错误处理
Struts 2提供了一个名为conversionError的拦截器,该拦截器被注册在默认的拦截器栈中,查看struts-default.xml文件如下:
<interceptor-stack name="defaultStack">
<!-- 省略其它拦截器 -->
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" >
<param name="excludeMethods" >input,back,cancel,browse</param> 
</interceptor-ref>
</interceptor-stack>
上面的默认拦截其中提供了conversionError拦截器的引用,如果struts类型转换出现错误,该拦截器会将对应的错误封装成表单域错误(FieldError),并将这些错误信息放入ActionContext中。
如果出现转换错误,则struts2自动转入名为input的逻辑视图。为了让struts的类型转换错误处理机制生效,都必须让action类继承ActionSupport基类,因为ActionSupport负责收集类型转换错误、
输入校验错误,并将它们封装成为FieldError对象,添加到ActionContext中。
在input逻辑视图对应的实际视图中使用:<s:fielderror />标签会输出形如Invalid field value for field xxx的错误提示信息,xxx是Action的属性名。

26、Struts 2的输入校验
Action中的属性进行校验,编写校验文件ActionName-validation.xml文件,该文件包含一个根元素<validators.../>,而根元素下面包含多个
字段校验器(字段优先)
<validators>
<field name="propName">
<field-validator type="int">
<param name="xx"></param>
<param name="xx"></param>
<message>字段出错提示</message>
</field-validator>
<field-validator>
...
</field-validator>
</field>

<field name="propName">
<field-validator type="int">
<param name="xx"></param>
<param name="xx"></param>
<message>字段出错提示</message>
</field-validator>
<field-validator>
...
</field-validator>
</field>
...
</validators>

非字段校验器(校验器优先)
<validators>
<validator type="int">
<param name="fieldName">name</param>
<param name="trim">true</param>
<message key="name.min">5</message>
</validator>
<validator type="int">
...
</validator>
...
</validators>


struts2的输入校验错误同类型转换,同样将错误信息封装至FieldError,并放入StackContext中,失败时同样返回input逻辑视图。
客户端校验只需要在<s:form../>元素中添加validate="true"属性
添加短路校验器(即一个字段有多种校验方式时会有多种提示信息,如果一种校验没有通过,只会显示该校验下的message错误提示,不会全部显示):
只要在<validator.../>或者<field-vaklidator.../>添加属性short-circuit="true"即可。

struts 2校验器type:
1)required,必填校验器 <param name="fieldName"/>username</param>
 <message></message>
2)requiredstring,必填字符串校验器,比required多了<param name="trim"></param>
3)int、long、short,整数校验器,param中name值:fieldName、min、max
4)date,日期校验器,param中:fieldName、min、max
5)expression,表达式校验器,属于非字段校验器,不能用于字段校验器。param中包含:expression属性,指定表达式。
6)fieldexpression,字段表达式校验器,param中包含:fieldName、expression。
7)email,邮件地址校验器
8)url,网址校验器
9)visitor,符合类型校验器,例如action中的User类型校验
10)stringlength,字符串长度校验器,param包含:fieldName、minLength、maxLength
11)regex,正则表达式校验器,param包含:fieldName、expression、caseSensitive(是否区分大小写)


27、手动完成校验
重写ActionSupport继承类中的validateXxx()方法,其中Xxx为Action下面的xxx方法名。
在方法中可以使用addFieldError("userError","您的用户名必须包含.org"),通过这种方式添加的FieldError不会自动显示,必须通过<s:fielderror/>标签来显示。

28、struts 2文件上传
<s:form action="upload" enctype="multipart/form-data">
<s:file name="upload" label="choose file" /> 
</s:form>


Action中写法:
private File upload;//上传文件name属性
private String uploadFileName;
private String uploadContentType;
private String savePath;


FileOutputStream fos = new FileOutputStream(getSavePath() + "\\" + getUploadFileName());
FileInputStream fis = new FileInputStream(getUpload());
byte[] buffer = new byte[1024];
int len = 0;
while( (len = fis.read(buffer) > 0){
fos.write(buffer,0,len);
}
return success;


Action的属性savePath的值可在struts.xml文件中直接进行配置
<action ..>
...
<!-- 动态设定Action中的属性值 -->
<param name="savePath">/upload</param>
...
</action>


29、拦截器实现文件过滤
struts.xml文件中,在需要处理文件上传的Action下面配置fileUpload拦截器,指定参数:
->allowedTypes:指定允许上传的文件类型
->maximumSize:指定允许上传的文件大小,单位是字节


<action>
<interceptor-ref name="fileUpload">
<param name="alowedTypes">image/jpg,image/gif,image/jpeg</param>
<param name="maximumSize">200000</param>
</interceptor>
<interceptor-ref name="defaultStack"/>
<param name="savePath">/uploadFiles</param>
</action>
改变文件上传失败的提示信息(在国际化资源文件中配置):
struts.message.error.content.type.not.allowed = 您上传的文件格式不符合!
struts.message.error.file.too.large = 您上传的文件太大!


struts.multipart.maxSize属性,设置整个表单请求内容的最大字节数


30、struts实现文件下载
struts提供下载的Action与普通的Action是相同的,只不过在普通Action的基础上加了一个返回InputStream流的方法,该输入流代表了被下载文件的入口。
<action name="" class="org.cz.action.DownloadAction">
<param name="inputPath">\images\a.jpg</param>

<result name="success" type="stream">
<param name="inputName">TargetFile</param>
<param name="contentType">image/jpg</param>
<param name="contentDisposition">filename="a.jpg"</param>
<param name="bufferSize">4096</param>
</result>
</action>


private String inputPath;


public String getInputPath() {
return inputPath;
}


public void setInputPath(String inputPath) {
this.inputPath = inputPath;
}

//定义一个返回InputStream的方法,方法名为struts.xml配置文件中的inputName参数值加一个get
public InputStream getTargetFile() throws Exception{
return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
}

<body>
    <ul>
    <li>
    下载a.jpg文件:
    <a href="images/a.jpg">下载</a>
    </li>
    </ul>
  </body>

31、拦截器
<interceptor name="" class="">
...
<param name="" ..></param>
...
</interceptor>
<interceptors>
...
<interceptor name="" class="" />
...
<interceptor-stack>
...
</interceptor-stack>
...
</interceptors>
<action name="" class="">
...
<interceptor-ref name="" />
...
</action>
配置拦截器栈:
<interceptor-stack name="">
<interceptor-ref name="拦截器一" ../>
<interceptor-ref name="拦截器二" ../>
<interceptor-ref name="拦截器三" ../>
...
</interceptor-stack>
拦截器栈和拦截器作用是一模一样的,可以看成是一个大的拦截器。拦截器或拦截器栈的行为将会在Action的execute方法执行之前被执行。
为某个package配置默认拦截器(一个package中只允许出现一个默认拦截器):
在<package../>根元素中配置:<default-interceptor-ref name="" .../>

自定义拦截器:
实现interceptor接口,一般直接继承AbstractInterceptor实现类,方法:
->init()
->destroy()
->intercept(ActionInvocation invocation),invocation代表被拦截的Action的引用,可以通过该参数的invoke方法将控制权交给下个拦截器或者Action的execute方法(如果有下一个拦截器则交给拦截器,没有的话直接执行Action的execute方法),getAction()方法直接返回被拦截Action的实例,这样的话可以直接获取Action中的参数并加以修改等等。


32、拦截方法的拦截器
默认情况下,如果为Action制定拦截器后,该拦截器会拦截Action中的所有方法,如果只需要拦截Action中的特定方法,则可以使用MethodFilterInterceptor拦截器,该拦截器是AbstractInterceptor的子类,该类重写了父类中的intercept方法,但提供了一个doIntercept方法,继承该类的拦截器会实现方法拦截,然后需要在Action配置文件中指定参数:
<param name="excludeMethods">execute,haha,iawd</param>  //指定不拦截executehaha,iawd方法


33、拦截器的执行顺序
Action的方法执行之前:配置越靠前的拦截器,越先执行
Action的方法执行之后:配置越靠后的拦截器,越先执行


34、拦截结果的监听器
实现接口PreResultListener,改接口下有多个方法,如:beforeResult(ActionInvacation invocation,String resultCode), resultCode为被拦截Action的execute方法的返回值。
beforeResult中定义的操作先于invocation.invoke()方法执行之后的操作。


35、使用拦截器完成权限控制
ActionContext ac = invocation.getInvocationContext();
Map session = ac.getSession();
String user = (String)session.get("user");
if(user != null && user.equals("crazit")){
return invocation.invoke();
}else{
return Action.LOGIN;
}


36、使用struts的Ajax支持
Ajax,异步javascript和xml技术,当服务端的响应成功返回至浏览器时,浏览器使用DOM(文档对象模型)将服务端响应装载到当前页面的指定位置。


public class LoginAction implements Action{
private String user;
private String pass;
private InputStream inputstream;
...
public InputStream getResult(){
return inputStream;
}
public String execute(){
inputStream = user.equals("crazit") ? new ByteArrayInputStream("恭喜你,登录成功!".getBytes("utf-8")) : new ByteArrayInputStream("对不起,请重新登录!".getBytes("utf-8"));
return SUCCESS;
}
}


<result type="stream" name="success">
<param name="contentType">text/html</param>
<param name="inputName">result</param>
</result>

posted @ 2015-10-02 12:00  程序员小波与Bug  阅读(295)  评论(0编辑  收藏  举报