strust2相关知识

本菜鸟开始写博客啦......


一、Struts2的主要组建

  1. FilterDispatcher:中央控制作用的过滤器

  2. Action:处于Model层的Action,调用JavaBean实现业务逻辑

  3. struts.xml:核心配置文件,配置有Action、Result等

  4. result:与forward类似,转发的目的地,支持多种视图技术。


二、Struts2的Action访问web对象

Action是一个普通的POJO对象,与web的四大内置对象未耦合在一起,便于单独测试Action

访问这些web内部对象有2种方式:

1. 直接访问Web对象

Struts2框架提供org.apache.struts2.ServletActionContext辅助类来获得web对象。

HttpServletRequest request = ServletActionContext.getRequest();
HttpServletResponse response = ServletActionContext.getResponse();
HttpSession session = request.getSession();
ServletContext application = ServletActionContext.getServletContext();

2. Action访问ActionContext

com.opensymphony.xwork2.ActionContext是一个Action执行的上下文,Action执行期间所用到的对象都保存在ActionContext中,例如session、参数等,并且ActionContext是一个局部线程变量,不用担心Action的线程安全。

ActionContext context = ActionContext.getContext();
ActionContext中的常用方法
Object get(Object key):    使用key来查找当前ActionContext中的值
Map getApplication():    返回一个Application范围的Map
static ActionContext getContext()    :获得当前线程的ActionContext实例
Map getParameters():    Map类型的所有HttpServletRequest的参数
Map getSession():    Map类型的HttpSession值
ValueStack getValueStack():    返回一个ValueStack类型OGNL值栈
void put(Object key,Object value):    向当前ActionContext存入值,等于在HttpServletRequest中加入值
void setApplication(Map application):    设置application上下文
void setSession(Map session):    设置session值,参数为Map实例
这种方法使用的所有对象和Web对象没有直接联系,所以在测试的时候也是很方便的。


三、Action的分类


1. 继承ActionSupport实现Action

通过继承ActionSupport来实现Action是我们的推荐做法,因为ActionSupport中提供了输入验证、国际化、execute等常用方法,使得编写Action时代码很简单。


2. 模型驱动(ModelDriven)的Action

Struts2的Action属于model层,Action中的方法代表业务逻辑,Action中的属性代表请求中的参数,当页面请求参数较多的时候,把过多的参数对象的属性定义在Action中不太符合Struts所倡导的松耦合原则,所以我们推荐单独用JavaBean来封装参数,在Action中为JavaBean赋值,这就是ModelDriven的Action。模型驱动的Action要求Action实现ModelDriven接口,假如登录页面需要传输参数username和userpass,我们把这2个参数封装在一个数据的JavaBean中,然后在Action中定义该JavaBean为Model即可,代码如下:

UserInfo.java

package po;
//用户名和密码封装对象
public class UserInfo {
    private String username;
    private String userpass;
    get...;
    set...;
}

UserAction.java

import com.opensymphony.xwork2.ActionSupport; 
import com.opensymphony.xwork2.ModelDriven;

public class UserAction extends ActionSupport implements ModelDriven<Userinfo> {
    private Userinfo model = new Userinfo();
    @Override public String execute() throws Exception { 
        // TODO Auto-generated method stub return SUCCESS; 
    } 
    //返回模型对象的实例
    public Userinfo getModel() { 
        // TODO Auto-generated method stub 
        return model; 
    } 
}

当请求该Action的时候,请求中的参数会自动填充到模型Userinfo的属性中,当然需要参数名和属性名一样,到跳转的页面上利用Struts2标签<s:property value="username" />可以取出模型Userinfo中的属性username。在ModelDriven接口中的方法getModel()必须实现,通过它告诉系统模型的具体对象是什么。


3. 多方法的Action

Action中的方法代表业务逻辑,那么一个模块中的多个业务逻辑如何用Action来处理呢?我们有2种办法来处理这个问题:

1. 一个Action对应一个业务逻辑,实现方便,但是Action数量多,struts.xml中需要配置的内容也多,这种方法不推荐;

2. 一个Action对应多个业务逻辑,例如表的CRUD操作,含有多个业务逻辑,我们只写一个Action来实现,Action的数量没有增加,struts.xml的配置也简单,所以这种方法是我们推荐的做法。

Action中自定义方法的声明和execute方法一样,方法的调用路径为“Action名称!方法名称.action”。

以用户表Userinfo的CRUD操作为例,看一下多方法Action的代码:

import po.Userinfo;
import service.UserService;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;
import com.opensymphony.xwork2.ModelDriven;

public class CrudUserAction extends ActionSupport implements ModelDriven<Userinfo> { 
    // crud业务方法
    private UserService userservice = new UserService();
    private Userinfo userinfo = new Userinfo();
    // 模型对象userinfo
    public Userinfo getModel() {
        // TODO Auto-generated method stub return userinfo;
    }
    // 增加
    public String create() throws Exception { 
        userservice.createUser(userinfo); return SUCCESS;
    }
    // 查询
    public String retrive() throws Exception {
        // 查询结果放在request中
        ActionContext.getContext().put("userlist", userservice.selectUsers());
        return "list"; 
    }
    // 修改
    public String update() throws Exception { 
        userservice.updateUser(userinfo); 
        return SUCCESS;
    }
    // 删除
    public String delete() throws Exception { 
        userservice.deleteUser(userinfo.getUsername()); 
        return SUCCESS; 
    }
    // 默认的execute
    public String execute() throws Exception {
        return SUCCESS; 
    } 
}

在struts.xml中配置如下:

<?xml version="1.0" encoding="UTF-8" ?> 
<!DOCTYPE struts PUBLIC 
    "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
    "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts> 
    <package name="actions" extends="struts-default">
        <action name="CrudUser" class="action.CrudUserAction">
            <result>/Success.jsp</result> 
            <result name="list">/UserList.jsp</result>
        </action>
    </package>
</struts>

除了以上方式,还可以在<action>标签中配置method属性,使用通配符。


四、Result类型

    Action中表示跳转的目的地使用了在struts.xml配置的字符串,格式为:<result name=”” type=””></result>,type可以有多种选择,Struts2支持各种视图技术,例如JSP、JSF、XML等,默认的是JSP。常见的type类型配置如下:

dispatcher―转发到JSP页面,默认

redirect―重定向到JSP页面

redirect-action―重定向到action,目的地为Action,配置时可以指定如下两个参数:actionName-重定向的Action名;namespace-重定向的Action所在的命名空间

chain―转发到action,形成action-chain,可以指定两个参数:actionName-重定向的Action名;namespace-重定向的Action所在的命名空间。

stream―用于向页面返回一个InputStream,原始数据直接传递给HttpServletResponse,这种结果类型在用户下载文件(例如PDF文件等)等情况下非常有意义.

plantext―用于输出目的地JSP/HTML的源代码内容,可以指定两个参数:location-目的地JSP/HTML,charSet-输出内容时使用的字符集。

除了上述类型以外,还支持如下的类型:

chart:用于整合JFreeChart的result类型;

freemarker:用于整合FreeMarker的result类型;

httpheader:用于处理特殊http行为的result类型;

jasper:用于整合JasperReport的result类型;

jsf:用于整合JSF的result类型;

titles:用于整合Titles的result类型;

velocity:用于整合Velocity的result类型;

xslt:用于整合XML/XSLT的result类型。

这些视图技术的支持,有些还需要导入相应的插件包,即Struts2提供的含有plugin字样的jar包。


、Strut2的国际化

在struts.xml中配置struts.custom.i18n.resources常量

<constant name="struts.custom.i18n.resources" value="globalMessages"/>

在src目录下建立中文和英文的资源文件


六、Struts2拦截器

    拦截器(interceptor)是Struts2框架核心组成部分。很多功能都是构建在拦截器基础之上的,例如文件的上传和下载、国际化、数据类型转换和数据有效性验证等,Struts2利用内建的拦截器,完成了框架内的大部分操作。

    拦截器就是动态拦截Action调用的对象。它提供了一种机制,使开发者可以定义一个特定的功能模块,这个模块可以在Action执行之前或之后运行,也可以在一个Action执行之前阻止Action执行。同时也提供了一种可以提取Action中可重用部分的方式。

    Struts2框架的Action被一个或者多个拦截器(拦截器栈)所包围,所有的用户请求都会被拦截器所拦截,然后交给Action处理,处理结果以逻辑视图的方式返回给用户。而这个调用的执行流程,是由Strut2的配置文件(struts.xml)来实现的。

    在前面几节中,没有明确说明拦截器,为什么可以直接调用Action呢?那是因为在Struts2框架中如果没有显式的拦截器配置,则系统会调用默认的拦截器来调用Action,在用户看来,好像没有配置拦截器一样。演示一个简单拦截器的开发:HelloWorld拦截器。假设我们需要实现这么一个功能,在调用每个Action之前都能在控制台打印出“HelloWorld”。这样的一个功能使用Struts2拦截器来实现最简单。下面介绍一个具体的实现步骤。

    HelloWorldInterceptor.java

package interceptor; 
import action.MyAction; 
import com.opensymphony.xwork2.ActionInvocation; 
import com.opensymphony.xwork2.interceptor.AbstractInterceptor; 
public class HelloWorldInterceptor extends AbstractInterceptor { 
    //拦截方法
    @Override 
    public String intercept(ActionInvocation arg0) throws Exception { 
        // 获得被调用的Action类
        Object action = arg0.getAction(); 
        // 打印HelloWorld 
        System.out.println("拦截器信息:HelloWorld!"); 
        // 执行Action或调用下一个拦截器
        String result = arg0.invoke(); 
        // 执行完action后提示
        System.out.println("Action执行完毕!");
        return result;
    }
}

在struts.xml中加入拦截器的配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC 
     "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" 
     "http://struts.apache.org/dtds/struts-2.0.dtd"> 
<struts>
     <package name="action" extends="struts-default">
          <!-- 定义拦截器 -->
          <interceptors>
               <interceptor name="helloworld" class="interceptor.HelloWorldInterceptor"/>
          </interceptors>
          <action name="test" class="action.MyAction">
              <result>Success.jsp</result> 
              <!-- action中引用默认拦截器-->
              <interceptor-ref name="defaultStack" />
              <!-- action中引用拦截器--> 
              <interceptor-ref name="helloworld"/>
          </action>
      </package>
</struts>

七、拦截器应用实例-文件上传和下载

上传单个文件

<body> 
<s:form action="fileupload" method="post" enctype="multipart/form-data"> 上传文件:<s:file name="doc"/><br> 
<s:submit value="上传"/> </s:form>
</body>

form表单的enctype属性设置为multipart/form-data。enctype用来指定表单数据的编码方式,有如下3个值。

1. application/x-www-form-urlencoded:指定该值,则表单中的数据被编码为Key-Value对,这是默认的编码方式。

2. multipart/form-data:使用mime编码,会以二进制流的方式来处理表单数据,文件上传需要使用该编码方式。

3. text/plain:表单数据以纯文本形式进行编码,其中不含任何控件和格式字符。

    file类型表单域doc用于选择上传文件,它和Action中的java.io.File类型的属性doc对应,同时上传文件的文件名对应于Action中的属性docFileName,上传文件的文件类型对应于Action中的属性docContentType。一般说来,为了上传文件,如果表单域名称为xxx,那么在Action中应建立如下3个属性来接收上传文件的信息。

private java.io.File xxx;//封装上传文件的二进制内容
private String xxxContentType;//封装上传文件的文件类型
private String xxxFileName;//封装上传文件的文件名


上传文件的过滤

上传文件的时候可以限制上传文件的类型和大小,使用拦截器来实现。文件上传的拦截器是系统拦截器,我们只要配置参数就可以了。

<struts> 
    <!-- 上传文件的临时保存目录-->
    <constant name="struts.multipart.saveDir" value="/tmp" />
       <package name="action" extends="struts-default">
            <action name="fileupload" class="action.FileUploadAction">
                <result>/Success.jsp</result> 
                <result name="input">/index.jsp</result> 
                <interceptor-ref name="fileUpload"> 
                    <!-- 允许上传的文件类型 -->
                    <param name="allowedTypes">image/bmp,image/png,image/gif,image/jpeg
                    </param>
                    <!--上传文件的最大容量单位字节-->
                    <param name="maximumSize">20000</param>
                </interceptor-ref>
                <interceptor-ref name="defaultStack" />
            </action>
        </package>
</struts>

在struts.xml中配置<constant name="struts.multipart.saveDir" value="/tmp" />用于指定上传文件保存的临时目录,上传完成后系统会自动删除临时目录中的内容。


文件下载

public class FileDownloadAction extends ActionSupport {
    private String inputpath; //下载文件路径
    private String contenttype; //文件类型
    private String filename;//文件名
    //返回一个InputStream类型
    public java.io.InputStream getInputStream() { 
        return ServletActionContext.getServletContext().getResourceAsStream(inputpath);     }
    @Override
    public String execute() throws Exception { 
        //调用相关业务逻辑方法动态设置下载信息
        inputpath = "/updfile/Bliss.jpg"; 
        contenttype = "image/jpeg"; 
        //解决下载的中文文件名问题
        filename = java.net.URLEncoder.encode("文件.jpg","utf-8");
        return SUCCESS;
    }

struts.xml中配置下载Action的result类型为stream,内容如下:

<action name="filedownload" class="action.FileDownloadAction"> 
    <result name="success" type="stream"> 
        <!-- 定义相关参数 -->
        <param name="contentType">${contenttype}</param>
        <param name="inputName">inputStream</param>
        <param name="bufferSize">4096</param>
        <param name="contentDisposition">attachment;filename=${filename}</param>
    </result>
</action>


你可能感兴趣的:(request,配置文件,过滤器,forward,result)