`
ccii
  • 浏览: 54861 次
  • 性别: Icon_minigender_1
  • 来自: 成都
社区版块
存档分类
最新评论

Struts2

阅读更多
一、Struts2概述
  Struts2 是Apache软件基金会(ASF)赞助的一个开源项目,使用Struts2的目的是为了帮助我们减少在运用MVC设计模型来开发Web应用的时间。如果我们想混合使用Servlets和JSP的优点来建立可扩展的应用,Struts2是一个不错的选择。

二、Struts2工作原理

如图,Struts2工作原理大概分为以下几个步骤:
1.客户端初始化一个指向Servlet容器(例如Tomcat)的请求。
2.这个请求经过一系列的过滤器(Filter)(ActionContextCleanUp,SiteMesh,etc等)。
3.接着FilterDispatcher被调用,FilterDispatcher询问ActionMapper来决定这个请求调用那个Action。
4.FilterDispatcher将控制权委派给ActionProxy,ActionProxy通过Configuration Manager读取框架的配置文件,然后创建一个ActionInvocation实例。
5.ActionInvocation调用Action,Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果。返回结果通常是(但不总是,也可能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。

三、Struts2相对于Struts1的改进
1.在Action的实现方面
  Struts1要求必须统一扩展自Action类,而Struts2中可以是一个普通的POJO。
2.线程模型方面
  Struts1的Action是单实例的,一个Action的实例处理所有的请求。Struts2的Action是一个请求对应一个实例(每次请求时都新new出一个对象),没有线程安全方面的问题。
3.Servlet依赖方面
  Struts1的Action依赖于Servlet API,比如Action的execute方法的参数就包括request和response对象。这使程序难于测试。Struts2中的Action不再依赖于Servlet API,有利于测试,并且实现TDD。
4.封装请求参数
  Struts1中强制使用ActionForm对象封装请求的参数。Struts2可以选择使用POJO类来封装请求的参数,或者直接使用Action的属性。
5.表达式语言方面
  Struts1中整合了EL,但是EL对集合和索引的支持不强,Struts2整合了OGNL(Object Graph NavigationLanguage)。绑定值到视图技术
  Struts1使用标准的JSP,Struts2使用“ValueStack”技术。
6.类型转换
  Struts1中的ActionForm基本使用String类型的属性。Struts2中使用OGNL进行转换,可以更方便的使用。Struts1中支持覆盖validate方法或者使用Validator框架。Struts2支持重写validate方法或者使用XWork的验证框架。
7.Action执行控制的对比
  Struts1支持每一个模块对应一个请求处理,但是模块中的所有Action必须共享相同的生命周期。Struts2支持通过拦截器堆栈为每一个Action创建不同的生命周期。

四、Struts2开发示例
1. Struts2的下载
  官方下载地址:http://struts.apache.org/download.cgi
  Struts2完整版结构如下:apps(应用示例),docs(帮助文档,API),lib(核心类库),src(全部源码)

2. 导入struts2核心类库到项目
  基本包包括:antlr-2.7.2.jar,commons-fileupload-1.3.jar,commons-io-2.0.1.jar,commons-logging-1.1.3.jar,commons-lang3-3.1.jar,freemarker-2.3.19.jar,javassist-3.11.0.GA.jar,ognl-3.0.6.jar,struts2-core-2.3.15.3.jar,
xwork-core-2.3.15.3.jar,如需使用Struts2的更多特性,则需导入其它jar包

3. 在web.xml中配置Struts2的核心Filter

    <!-- 定义Struts2的核心Filter -->
    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
    </filter>
    <!-- 让Struts2的核心Filter拦截所有请求 -->
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

4. 创建登陆页面login.jsp,测试Struts2

<script type="text/javascript">
    function regist(){
        //获取页面的第一个表单
        targetForm = document.forms[0];
        //动态修改表单的action属性
        targetForm.action = "regist";
    }
</script>
<body bgcolor="pink">
    <center>
        用户登陆<br><hr>
        <form action="login">
            账 号:<input type="text" name="username"><br>
            密 码:<input type="text" name="password"><br>
            <input type="submit" value="登陆">
            <input type="submit" value="注册" onclick="regist();">
        </form>
    </center>
</body>

5. 为Struts2添加配置文件struts.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
<!-- 指定Struts 2配置文件的根元素 -->
<struts>
    <!-- 指定全局国际化资源文件 -->
    <constant name="struts.custom.i18n.resources" value="mess"/>
    <!-- 指定国际化编码所使用的字符集 -->  
    <constant name="struts.i18n.encoding" value="GBK"/>
    <!-- 所有的Action定义都应该放在package下 -->
    <package name="userManager" extends="struts-default">
        <!-- 不配置method属性,交给默认的execute()方法处理 -->
        <action name="login" class="test.action.LoginAction">
            <!-- 定义三个逻辑视图和物理资源之间的映射 -->      
            <result name="input">/login.jsp</result>
            <result name="error">/error.jsp</result>
            <result name="success">/welcome.jsp</result>
        </action>
        <!-- 配置method属性,交给regist()方法处理 -->
        <action name="regist" class="test.action.LoginAction" method="regist">
            <result name="success">/welcome.jsp</result>
        </action>
    </package>
    <!-- 导入其它完整的配置文件 -->
    <include file="struts-xxx.xml"></include>
</struts>

6. 编写Action处理类BaseAction.java,LoginAction.java

/////////////////// 1.BaseAction
package test.action;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;

public class BaseAction extends ActionSupport {
    
    private transient HttpServletRequest request = null;
    private transient HttpServletResponse response = null;
    private transient ServletContext servletContext = null;
    private transient HttpSession session = null;
    
    public void setRequest(HttpServletRequest request) {
        this.request = request;
    }
    public void setResponse(HttpServletResponse response) {
        this.response = response;
    }
    public void setServletContext(ServletContext servletContext) {
        this.servletContext = servletContext;
    }
    public void setSession(HttpSession session) {
        this.session = session;
    }
    public HttpServletRequest getRequest(){
        if(request != null){
            return request;
        }
        return ServletActionContext.getRequest();
    }
    public HttpServletResponse getResponse(){
        if(response != null){
            return response;
        }
        return ServletActionContext.getResponse();
    }
    public ServletContext getServletContext(){
        if(servletContext != null){
            return servletContext;
        }
        return ServletActionContext.getServletContext();
    }
    public HttpSession getSession(){
        if(session != null){
            return session;
        }
        return getRequest().getSession();
    }
}


///////////////// 2. LoginAction
package test.action;

public class LoginAction extends BaseAction{
    //定义封装请求参数的username和password属性
    private String username;
    private String password;
    
    public String getUsername(){
        return username;
    }
    public void setUsername(String username){
        this.username = username;
    }
    public String getPassword(){
        return password;
    }
    public void setPassword(String password){
        this.password = password;
    }
    //注册Action
    public String regist() throws Exception {
        System.out.println(this.getRequest().getAttribute(&quot;username&quot;));
        this.getRequest().setAttribute(&quot;username&quot;, &quot;regist&quot;);
        return SUCCESS;
    }
    //默认的登陆Action
    public String execute() throws Exception {
        // 1. 通过request对象得到表单的值
        System.out.println(this.getRequest().getParameter(&quot;username&quot;));
        // 2. 直接通过getter和setter得到表单的值
        if (getUsername().equals(&quot;a&quot;)&amp;&amp; getPassword().equals(&quot;a&quot;)){
            // 3. 设置、得到session的值
            this.getSession().setAttribute(&quot;username&quot;, &quot;ok&quot;);
            System.out.println(this.getSession().getAttribute(&quot;username&quot;));
            // 4. 设置响应的字符串
            this.getResponse().setCharacterEncoding(&quot;UTF-8&quot;);
            this.getResponse().getWriter().print(&quot;ccccc&quot;);
            return SUCCESS;
        } else {
            return ERROR;
        }
    }
}


7. 其它跳转页面welcome.jsp

<body>
      登陆成功!<%=request.getAttribute("username")%><br>
      <a href="login.jsp">退出</a><hr>
</body>

五、Struts2的文件上传和下载
Struts2的文件上传:
1. 测试文件上传页面upload.jsp
  此处使用Struts2标签来生成上传文件的表单,为了让浏览器采用二进制数据的方式把数据发送到服务器,我们必须把表单的method设置为POST,将enctype设置为multipart/form-data。jsp代码如下:

<body>
<s:form action="uploadPro" method="post" enctype="multipart/form-data">
    <s:file name="upload" label="选择文件"/><br />
    <s:submit value="上传"/>
</s:form>
</body>

2. 实现文件上传的Action(UploadAction.java)
  Action实现类其实非常简单,只需要定义三个属性接收文件参数即可,一是类型为File的xxx封装文件内容,二是String类型的xxxFileName封装文件名,三是String类型的xxxContentType封装文件类型。代码如下:
package test;
import com.opensymphony.xwork2.ActionSupport;
import java.io.*;
public class UploadAction extends ActionSupport{
    //封装上传文件域
    private File upload;
    //封装上传文件类型
    private String uploadContentType;
    //封装上传文件名
    private String uploadFileName;
    public void setUpload(File upload) {
        this.upload = upload;
    }
    public File getUpload(){
        return (this.upload);
    }
    public void setUploadContentType(String uploadContentType){
        this.uploadContentType = uploadContentType;
    }
    public String getUploadContentType(){
        return (this.uploadContentType);
    }
    public void setUploadFileName(String uploadFileName){
        this.uploadFileName = uploadFileName;
    }
    public String getUploadFileName(){
        return (this.uploadFileName);
    }
    @Override
    public String execute() throws Exception{
        //将文件写入服务器,没有此文件时新建
        File file = new File("h:\\AAA\\"+getUploadFileName());
        FileOutputStream fos = new FileOutputStream(file);
        FileInputStream fis = new FileInputStream(getUpload());
        byte[] buffer = new byte[1024];
        int len = 0;
        while ((len = fis.read(buffer)) > 0){
            fos.write(buffer , 0 , len);
        }
        fos.close();
        return SUCCESS;
    }
}


3. 配置文件上传的Action(struts.xml)

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">   
<struts>
    <constant name="struts.custom.i18n.resources" value="mess"/>
    <!-- 设置该应用使用的解码集 -->
    <constant name="struts.i18n.encoding" value="GBK"/>
    <package name="lee" extends="struts-default">
        <!-- 配置处理文件上传的Action -->
        <action name="uploadPro" class="test.UploadAction">
            <!-- 配置Struts 2默认的视图页面 -->
            <result>/upload.jsp</result>   
        </action>
    </package>
</struts>

4. 实现文件过滤
  方法一:直接在Action中判断文件的类型是否为允许类型
  方法二:拦截器实现文件过滤,如下:

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">   
<struts>
    <constant name="struts.custom.i18n.resources" value="mess"/>
    <!-- 设置该应用使用的解码集 -->
    <constant name="struts.i18n.encoding" value="GBK"/>
    <package name="lee" extends="struts-default">
        <!-- 配置处理文件上传的Action -->
        <action name="uploadPro" class="org.crazyit.app.action.UploadAction">
            <!-- 配置fileUpload的拦截器 -->
            <interceptor-ref name="fileUpload">
                <!-- 配置允许上传的文件类型 -->
                <param name="allowedTypes">image/png,image/gif,image/jpeg</param>
                <!-- 配置允许上传的文件大小 -->
                <param name="maximumSize">2000</param>
            </interceptor-ref>
            <!-- 配置系统默认的拦截器 -->
            <interceptor-ref name="defaultStack"/>
            <!-- 配置Struts 2默认的视图页面 -->
            <result>/WEB-INF/content/succ.jsp</result>
        </action>
    </package>
</struts>

Struts2的文件下载:
1. 测试文件下载jsp页面

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

2. 实现文件下载的Action(FileDownloadAction.java)

package test;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.*;
public class FileDownloadAction extends ActionSupport {
    //该属性可以在配置文件中动态指定该属性值
    private String inputPath;
    //依赖注入该属性值的setter方法
    public void setInputPath(String value){
        inputPath = value;
    }
    /*
     * 定义一个返回InputStream的方法,该方法将作为被下载文件的入口,
     * 且需要配置stream类型结果时指定inputName参数,inputName参数的值就是方法去掉get前缀、首字母小写的字符串
     */
    public InputStream getTargetFile() throws Exception {
        //ServletContext提供getResourceAsStream()方法返回指定文件对应的输入流
        return ServletActionContext.getServletContext().getResourceAsStream(inputPath);
    }
}


3. 配置文件下载的Action(struts.xml)

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
    <constant name="struts.custom.i18n.resources" value="mess"/>
    <constant name="struts.i18n.encoding" value="GBK"/>
    <package name="lee" extends="struts-default">
        <action name="download" class="test.FileDownloadAction">
            <param name="inputPath">\images\aaa.jpg</param>
            <!-- 配置结果类型为stream的结果 -->
            <result name="success" type="stream">
                <!-- 指定下载文件的文件类型 -->
                <param name="contentType">image/jpg</param>
                <!-- 指定由getTargetFile()方法返回被下载文件的InputStream -->
                <param name="inputName">targetFile</param>
                <param name="contentDisposition">filename="hap.jpg"</param>
                <!-- 指定下载文件的缓冲大小 -->
                <param name="bufferSize">4096</param>
            </result>
        </action>
    </package>
</struts>

六、Struts2返回JSON数据示例
1. 导包
  除导入Struts2基本包以外还要导入struts2-json-plugin-2.3.15.3.jar

2. 实现Action(JSONExample.java)
package test;
import java.util.HashMap;
import java.util.Map;
import com.opensymphony.xwork2.Action;
import org.apache.struts2.json.annotations.JSON;
public class JSONExample{
    //模拟处理结果的属性
    private int[] ints = {10, 20};
    private Map<String , String> map = new HashMap<String , String>();
    private String customName = "顾客";
    //封装请求参数的三个属性
    private String field1;
    //'transient'修饰的属性不会被序列化
    private transient String field2;
    //没有setter和getter方法的字段不会被序列化
    private String field3;
    public String execute(){
        field2 = "333";
        map.put("name", "疯狂Java讲义");
        return Action.SUCCESS;
    }
    //使用注释语法来改变该属性序列化后的属性名
    @JSON(name="newName")
    public Map getMap(){
        return this.map;
    }
    //customName属性的setter和getter方法
    public void setCustomName(String customName){
        this.customName = customName;
    }
    public String getCustomName(){
        return this.customName;
    }
    //field1属性的setter和getter方法
    public void setField1(String field1){
        this.field1 = field1;
    }
    public String getField1(){
        return this.field1;
    }
    //field2属性的setter和getter方法
    public void setField2(String field2){
        this.field2 = field2;
    }
    public String getField2(){
        return this.field2;
    }
    //field3属性的setter和getter方法
    public void setField3(String field3){
        this.field3 = field3;
    }
    public String getField3(){
        return this.field3;
    }
}


3. 配置Action(struts.xml)

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.1.7//EN"
    "http://struts.apache.org/dtds/struts-2.1.7.dtd">
<struts>
    <constant name="struts.i18n.encoding" value="UTF-8"/>
    <package name="example"  extends="json-default">
        <action name="JSONExample" class="test.JSONExample">
            <!-- 配置类型的json的Result -->
            <result type="json">
                <!-- 为该Result指定参数 -->
                <param name="noCache">true</param>
                <param name="contentType">text/html</param>
                <!-- 设置只返回Action的map属性 -->
                <!--  param name="root">map</param -->
            </result>
        </action>
    </package>
</struts>

4. 测试返回结果
  浏览器输入: http://localhost:8080/TestStrutsJSON/example/JSONExample(项目路径+Action配置文件包名+Action名)测试得到的JSON数据。
  • 大小: 121.5 KB
分享到:
评论

相关推荐

    struts1和struts2的区别

    struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别struts1和struts2的区别...

    Struts2视频教程

    Struts2是一套非常优秀的Java WEB应用框架,实现优雅、功能强大、使用简洁。目前已有大量的企业项目采用Struts2来作为Web框架进行开发,掌握Struts2是每个进行Web开发的Java程序员的一项必备技能。 本视频对Struts2...

    struts2-core.jar

    struts2-core-2.0.1.jar, struts2-core-2.0.11.1.jar, struts2-core-2.0.11.2.jar, struts2-core-2.0.11.jar, struts2-core-2.0.12.jar, struts2-core-2.0.14.jar, struts2-core-2.0.5.jar, struts2-core-2.0.6.jar,...

    Struts2_s2-016&017&ognl2.6.11_patch漏洞补丁

    -- 为修复struts2 s2-016、s2-017漏洞,重写DefaultActionMapper --&gt; &lt;bean type="org.apache.struts2.dispatcher.mapper.ActionMapper" name="myDefaultActionMapper" class=...

    struts2 chm 帮助文档

    struts2 chm 程序包 org.apache.struts2 接口概要 接口 说明 StrutsStatics Constants used by Struts. 类概要 类 说明 RequestUtils Request handling utility class. ServletActionContext Web-specific ...

    Struts2开发常用jar包

    包含struts2-core-2.5.10.1.jar,struts2-jfreechart-plugin-2.5.10.1.jar,struts2-json-plugin-2.5.10.1.jar,struts2-junit-plugin-2.5.10.1.jar,struts2-bean-validation-plugin-2.5.10.1.jar,struts2-cdi-...

    最新版本的Struts2+Spring4+Hibernate4框架整合

    整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6。 此外,还有:log4j、slf4j、junit4、ehcache等知识点。 项目...

    struts2 总结工程大全

    struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全struts2 总结工程大全...

    struts2环境搭建+struts2 新闻发布系统+struts2 留言板

    struts2环境搭建+struts2 新闻发布系统+struts2 留言板 struts2环境搭建:基础框架搭建,简单易上手,适合新手,比你看书强多了,实践源于理论而高于理论,贵在实践 朋友。 struts2 新闻发布系统:struts2+jsp 功能不...

    Struts2漏洞检查工具2019版 V2.3.exe

    Struts2漏洞检查工具2019版 警告: 本工具为漏洞自查工具,请勿非法攻击他人网站! ==漏洞编号==============影响版本=========================官方公告==========================================影响范围====...

    struts2技术内幕+struts2权威指南

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》以Struts2的源代码为依托,通过对Struts2的源代码的全面剖析深入探讨了Struts2的架构设计、实现原理、设计理念与设计哲学,对从宏观上和微观上去了解Struts2...

    Struts2漏洞检查工具Struts2.2019.V2.3

    Struts2漏洞检查工具Struts2.2019.V2.3

    论坛系统项目(Struts 2+Hibernate+Spring实现)

    论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts...

    struts2 技术内幕——深入解析struts2架构设计

    《Struts2技术内幕:深入解析Struts2架构设计与实现原理》由国内极为资深的Struts2技术专家(网名:downpour)亲自执笔,iteye兼CSDN产品总监范凯(网名:robbin)以及51CTO等技术社区鼎力推荐。  本书以Struts2的...

    struts2实例 学生信息管理系统

    struts2实现的学生信息管理系统 &lt;?xml version="1.0" encoding="UTF-8"?&gt; &lt;!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" ...

    struts2 资料struts2 资料struts2 资料struts2 资料

    struts2 资料struts2 资料struts2 资料struts2 资料

    Struts2实战.pdf

    资深开发人员深入剖析Struts2核心概念和组件 学习Struts不可不读 作者简介 作者:(美国)Donald Brown (美国)Chad Michael Davis (美国)Scott Stanlick 译者:马召 等 Donald Brown,Atlassian软件系统公司托管...

    Struts 2 远程代码执行漏洞(s2-045\s2-046)修复所用到的包

    struts2-convention-plugin-2.3.32.jar struts2-core-2.3.32.jar struts2-spring-plugin-2.3.32.jar xwork-core-2.3.32.jar --来源 ...

    struts2(1-7)源码 struts2学习入门 源码学习

    struts 初步认识Struts2并部署验证 struts2 将要进行自定义类型转换的点数据从1个增加到3个 struts3 进行全局的类型转换 struts4 使用Struts2中内部类中的方法进行自定义类型转换,用到的类StrutsTypeConverter ...

    Struts2工作流程图

    虽然Struts2号称是一个全新的框架,但这仅仅是相对Struts 1而言。Struts 2 与Struts 1相比,确实有很多革命性的改进,但它并不是新发布的新框架,而是在另一个赫赫有名的框架:WebWork基础上发展起来的。从某种程度...

Global site tag (gtag.js) - Google Analytics