Struts使用总结

搭建Struts2环境
1.找到开发Struts2应用需要使用到的jar文件
2.编写Struts的配置文件
3.在web.xml中写入

开发Struts2最少要用到的jar包
struts2-core-2.xx.jar     Struts2的核心类库
xwork-2.xx.jar     xwork类库,struts在其之上构建
ognl-3.0x.jar    对象图导航语言,struts2框架通过其读写对象的的属性
freemarker-2.x.x.jar     struts2的ui标签模版使用FreeMarke编写
commons-logging-1.1x ASF触屏的日志包,Struts2框架使用这个日志包来支持log4g和JSK1.4的日志记录
commons-fileupload-1.x.x文件上传逐渐.2.1.6版本后必须加入此文件

struts框架是通过Servlet启动的.在struts2中,struts框架是通过filter启动的
在web.xml中写入

<filter>
<filter-name>struts2</filter-name>
<filterclass>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
通过StrutsPrepareAndExecuteFilter类的init 完成初始化;

在strtus.xml中写入
  <package name="default" namespace="/" extends="struts-default">
     <action name= "index" class ="action.HelloWorldAction" method= "execute">
          <result name= "success">/WEB-INF/page/hello.jsp </result>
     </action>

action名称搜索的顺序
1.首选寻找namespace为请求路径,找不到就找上一层目录,知道顶层,然后在找默认namespace,
                                                                                      默认的就是没有namespace="";或不写
action配置中的各项默认值
1.如果没有为action指定class,默认是ActionSupport.
2.如果没有为action指定method,那么默认执行action中的execute()方法.
3.如果没有指定result的name,默认值为success


result 常用的类型有:type="dispatcher"(默认)         内部请求转发
                              redirect                                   重定向
username =URLEncoder.encode("刘坤笔记如果没有为" , "UTF-8");
<action name="index" class= "action.HelloWorldAction" method="execute">
    <result name= "success" type ="redirect"> /redirect.jsp?username =${username}</result >     ognl表达式 
</action>
java.net.URLDecoder
<%=URLDecoder.decode(new String(request.getParameter("username" ).getBytes("ISO-8859-1"), "UTF-8"),"UTF-8" )
        %>
                              redirectAction                         重定向Action
       
        <action name= "redirectAction">
               <result type= "redirectAction">index</result >
        </action>
      
        <actoin name= "redirectAction2">          <!--action在别的包的时候要用的代码-->
               <result type= "redirectAction">
                      <param name= "actionName">xxx </param>
                      <param name= "namespace">/action/ </param>
               </result>
        </actoin>
                           plainText                    以源码的方式返回给用户,不执行代码
<!-- 以源代码方式返回给用户 -->
        <action name= "plainText">
               <result type= "plainText">
                      <param name= "location">/index.jsp </param>
                      <param name= "charSet">UTF-8</param >
               </result>
        </action>
                         全局视图
    <global-results >
       <result name="message"> /index.jsp</result >
    </global-results >
多个package  都可以使用了
<package name= "base" extends ="struts-default">
        <global-results>
       <result name="message"> /index.jsp</result >
    </global-results >
        </package>
    <package name="defaultx" namespace="/" extends="base">

为Action属性注入值
在Action 对应的类里面有和name的值  相同的属性
<param name="savaPath">/image</param>

指定Struts2 处理的请求的后缀
在package 外面  ,可以是多个  由逗号进行分割
< constant name ="struts.action.extension" value ="do,action"/>

常用的常量
指定默认编码集,作用于HttpServletRequest的setCharacterEncoding方法和freemarker...
< constant name ="struts.i18n.encoding" value ="UTF-8"/>

struts2的处理流程                              strtus2内置的拦截器
用户请求-->strutsPrepareAndExecuteFilter--->interceptor-->Action---->Result---->jsp/html--->响应

为应用程序指定多个struts2配置文件
<struts>
     <include file="struts-user.xml"/>
     <include file="struts-order.xml"/>
</struts>


动态方法调用和通配符定义action

在action名的后面加!方法名.action
/default!addUI.action
如果不想使用动态方法调用,我么可以使用常量来关闭
<constant name="struts.enable.DynamicMethodInvocation" value="false" />

通配符定义action     都可以用{1}代替这是可选的,用的最多的就是method里面
<action name="list_*" class="action.{1}HelloWorldAction" method="{1}">
     <result name="success">/{1}.jsp</result>
</action>

接受请求参数
get方法
/default!addUI.action?id=12334&user=liukun
在action 对应类里面提供 同名的属性就OK了  要提供set方法
在视图(也就是页面中调用)
直接${id}   ${name}               要提供get方法

post方法
同上
post方法可以使用对象的方式存储
<form action="<%=request.getContextPath()%>/index_execute.action" method="post"
<input type="text" name="user.id">     要有无参构造器
${user.id}    视图中

自定义类型转换器
局部     定义一个类型转换器,注册在Action类所在的包下放置ActionClassName-conversion.properties
          actionClass的属性=包名+转换器的类
       
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;

import com.opensymphony.xwork2.conversion.impl.DefaultTypeConverter;

public class DateDefaultTypeConverter extends DefaultTypeConverter {
        @Override
        public Object convertValue(Map<String, Object> context, Object value, Class toType) {
              SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd" );
               try {
                      if(toType == Date.class){//当字符串向Date类型转换时
                           String[] params = (String[]) value; // request.getParameterValues()
                            return dateFormat.parse(params[0]);
                     } else if (toType == String.class){ //当Date转换成字符串时
                           Date date = (Date) value;
                            return dateFormat.format(date);
                     }
              } catch (ParseException e) {}
               return null;
       }
}
全局
      和上面一样,不过注册在WEB-INF/classes下放置xwork-conversion.properties 文件的中内容类是
                         java.util.Date= cn.itcast.conversion.DateConverter

访问或添加几个属性
     ActionContext ctx = ActionContext.getContext();

        public String execute(){
              ActionContext ctx = ActionContext. getContext();
              ctx.getApplication().put( "application", "application范围" );
              ctx.getSession().put( "Session", "session范围" );
              ctx.put( "req", "request范围" );
               return "success" ;
       }

        public String rsa(){
              HttpServletRequest request = ServletActionContext. getRequest();
              ServletContext ser = ServletActionContext.getServletContext();
              ser.getRealPath("");
              HttpSession  session = request.getSession();
              HttpServletResponse response = ServletActionContext.getResponse();
               return "success" ;
       }


上传文件
在action对应类中添加     属性名要和 提交表单的name值一样,
private File uploadimage;//
private String uploadimageFileName;// 表单name值+FileName; 文件名
private String uploadimageContextType;//文件类型
        public String execute() throws IOException{
              String realpath = ServletActionContext.getServletContext().getRealPath( "/image");
              System. out.println(realpath);
               if(image !=null){
                     File savefile = new File(new File(realpath), imageFileName);
                      if(!savefile.getParentFile().exists()){
                           savefile.getParentFile().mkdirs();
                     }
                     FileUtils. copyFile(image, savefile);
                     ActionContext. getContext().put("message", "完成上传" );
              }
               return "success" ;
       }

文件上传默认最大2M ,可以通过常量修改
< constant name ="struts.multipart.maxSize" value ="10701096"/>
多文件上传,把 类里面的file 变成 file数组 就行

自定义拦截器

public class interceptorX implements Interceptor {
        @Override
        public void destroy() {}

        @Override
        public void init() {}

        @Override
        public String intercept(ActionInvocation invocation) throws Exception {
              Object user = ActionContext. getContext().get("user");
               if(user!=null ) return invocation.invoke();
              ActionContext. getContext().put("message", "你没有执行劝你权限" );
               return "message" ;
       }
}

<struts>
        <package name= "defaultx" namespace ="/" extends="struts-default">
        <interceptors>
               <interceptor name= "interce" class="action.interceptorX" ></interceptor>
               <interceptor-stack name= "interce_stack">
                     <interceptor-ref name= "defaultStack"/>
                      <interceptor-ref name= "interce"/>
               </interceptor-stack>
        </interceptors>
        <default-interceptor-ref name= "interce"/>
        <global-results>
               <result name= "message">message.jsp </result>
        </global-results>
               <action name= "inter" class ="action.Hello" method= "execute">
                      <interceptor-ref name= "interce_stack"></interceptor-ref >
               </action>
        </package>
</struts>


对Action中所有的方法进行输入校验
通过重写validate()方法实现,validate()方法会校验Action中所有与execute方法签名相同的方法,当
某个数据校验失败时,我们应该调用addfieldError()方法往系统的fieldError添加失败信息(为了使用
addfieldError方法(),Action可以继承ActionSupport,如果系统的fieldErrors包含失败信息,struts会
将请求转发到名为input的 result.在input 视图中可以通过<s:fielderror/>显示失败信息
public class ActionUser extends ActionSupport {
        @Override
        public void validate() {   //对action中的所有方法进行校验
               if(user ==null || user.trim().equals( "")){
                      this.addFieldError("user", "用户名不能为空" );     //以键值对的方式存值
              }
               if(phone ==null || phone.trim().equals( "")){
                      this.addFieldError("phone", "手机不能为空" );
              } else if(!Pattern.compile( "^1[358]\\d{9}$").matcher(phone ).matches()){
                      this.addFieldError("phone", "手机号格式不正确" );
              }
       }
< result name ="input">/index.jsp </result>
<%@ taglib uri ="/struts-tags" prefix ="s"%>
<s:fielderror name=""/>    //不写name属性  默认全部都拿到    

在Action指定方法进行校验
public void validateUpdate() {   //对action中的 update 进行校验


输入校验的流程
1.类型转换器对请求参数执行类型转换,并把转换后的值附给action中的属性.
2.如果在执行类型转换的过程过出现异常,系统会不异常信息保存到ActionContext,
ContextError拦截器将异常信息添加到fieldErrors里,不管类型转换是否异常都会
执行地3步
3.系统过过反射技术先调用action中的validateXxx方法().Xxx为方法名,
4.在调用Action中的validate()方法.
5.记过上面4补,如果系统中的fieldErrors存在错误信息,(即存放错误信息的集合的size大于0),
系统自动将请求转发至名称为input的视图.如果系统中的fieldError没有任何错误信息,系统将
执行action中的处理方法.

基于xml配置方式,校验
在和action类同一个包中放入xml文件,文件的格式为:ActionClassName-validation.xml

国际化
准备资源文件,资源文件的格式
baseName_zh_CN.properties
baseName_en_US.properties
第一个存放中文,如welcome=你好世界
第二个存放英语(美国),welcome=Hello World
在struts.xml中通过
<constant name="strtus.custom.i18n.resources" value="baseName"/>  //基名和资源文件格式

在jsp上面可以使用 <s:text name=""/> 标签输出国际化信息
在Action类中,可以继承ActionSupport,使用getText()方法得到国际化信息
在表单标签中可以通过key.
<s:textfield name="" key=""/>

输入带有占位符的国际化信息
welcome={0}你好世界{1}     在资源文件中
welcome={0}你好世界{1}
在jsp页面
<s:text name="">
     <s:param>xxx</s:param>     占位符0
     <s:param>xxx</s:param>     占位符1
</s:text>
在Action中
getText("",new String[]{"",""});











猜你喜欢

转载自xp-p.iteye.com/blog/2204043