JavaWeb开发知识总结(七)-(struts2_文件上传_Ajax)

来源:互联网 发布:mac 用appleid 登陆 编辑:程序博客网 时间:2024/05/19 20:18

JavaWeb开发知识总结(struts2-文件上传-Ajax)

1. Struts2文件上传

struts2中文件上传也需要遵循文件上传的三要素:

  1. form表单的提交方式必须是<form method="post">
  2. 必须要有文件上传项<input type="file" name="upload">,并且必须要有name属性值;
  3. form表单的enctype属性必须为multipart/form-date。

注意事项:action中上传文件属性的定义及配置参见struts-default.xml文件中fileUpload拦截器对应的org.apache.struts2.interceptor.FileUploadInterceptor 类中的解释该拦截的使用方式中的示例配置。

1.1 上传单个文件

上传文件前端页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">    <input type="file" name="upload" />    <input type="submit" value="上传" /></form></body></html>

自定义上传文件的Action:

/** * 文件上传的action */public class UploadAction extends ActionSupport {    private static final long serialVersionUID = 1L;    // 文件上传的步骤    // 1. 定义三个变量    // 文件名称,和form表单中的文件项的name属性相同    private File upload;     // 文件的MIMETYPE类型,名称是form表单的文件项的name属性值+ContentType,ContentType首字母必须大写    private String uploadContentType;     // 上传文件的名称,名称是form表单中文件项的name属性值+FileName,FileName的首字母必须大写    private String uploadFileName;     // 2. 为三个属性提供get/set方法    public File getUpload() {        return upload;    }    public void setUpload(File upload) {        this.upload = upload;    }    public String getUploadContentType() {        return uploadContentType;    }    public void setUploadContentType(String uploadContentType) {        this.uploadContentType = uploadContentType;    }    public String getUploadFileName() {        return uploadFileName;    }    public void setUploadFileName(String uploadFileName) {        this.uploadFileName = uploadFileName;    }    /**     * 3. 文件上传的方法     */    public String fileUpload() {        // 4. 调用struts2中提供的文件读写的方法保存文件到本地磁盘        // 定义文件上传保存的路径        String path = ServletActionContext.getServletContext().getRealPath(                "/upload"); // 项目根目录下的upload文件夹中        // 创建保存的文件        File destFile = new File(path, uploadFileName);        try {            // 调用工具类保存文件            FileUtils.copyFile(upload, destFile);        } catch (IOException e) {            e.printStackTrace();            // 出现异常,文件未保存成功,返回error            return ERROR;        }        return SUCCESS;    }}

配置文件:采用分开的配置方式

<!--struts.xml配置文件--><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    "http://struts.apache.org/dtds/struts-2.3.dtd"><struts>    <!-- 设置为开发模式 -->    <constant name="struts.devMode" value="true"></constant>    <!-- 设置全局的编码格式,解决post提交中文乱码问题 -->    <constant name="struts.i18n.encoding" value="UTF-8"></constant>    <include file="fileupload.xml" /></struts><!--fileupload.xml配置文件--><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    "http://struts.apache.org/dtds/struts-2.3.dtd"><struts>    <!-- 设置为开发模式 -->    <constant name="struts.devMode" value="true"></constant>    <!-- 设置全局的编码格式,解决post提交中文乱码问题 -->    <constant name="struts.i18n.encoding" value="UTF-8"></constant>    <!-- 配置全局的上传文件最大值的常量,默认值是2097152 -->    <!--<constant name="struts.multipart.maxSize" value="2097152000" /> -->    <!--         文件上传时,默认的上传文件的大小限制为2097152(2m),要改变上传文件大小的限制,        可以通过一下配置方式解决:        1.配置全局的上传文件的最大值,针对的是所有的action有效;        2.上传文件是由fileUpload拦截器实现的,            可以通过更改拦截器源码中的上传文件的大小设置来修改上传文件的最大值,针对配置的action有效 -->    <package name="fileupload" namespace="/" extends="struts-default">        <action name="upload" class="com.fileupload.action.UploadAction"            method="fileUpload">            <!-- 配置上传文件出现问题时,跳转到的页面,系统自动跳转 -->            <result name="input">/error.jsp</result>            <!-- 设置上传文件成功的页面视图 -->            <result name="success">/success.jsp</result>            <!-- 设置上传文件失败的页面视图 -->            <result name="error">/error.jsp</result>            <!-- 通过配置action的fileupload拦截器中上传文件的最大值                注意事项:设置局部的上传文件的大小,必须比全局的要小,当全局的没有配置时,全局的默认是2M -->            <interceptor-ref name="fileUpload">                <param name="maximumSize">20971510</param>            </interceptor-ref>            <!-- 手动配置拦截器后,默认的拦截器不起作用,需要手动配置默认的拦截器 -->            <interceptor-ref name="defaultStack"></interceptor-ref>        </action>    </package></struts>

1.2 上传多个文件

前台jsp页面:

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><body><form action="${pageContext.request.contextPath}/uploadMany" method="post" enctype="multipart/form-data">    <!-- 上传多个文件时,文件项的name属性必须相同 -->    <input type="file" name="upload" />    <input type="file" name="upload" />    <input type="submit" value="上传"/></form></body></html>

定义实现多个文件上传的Action:

/** * 上传多个文件的action * @date: 2017年6月15日 下午8:36:38 */public class UploadManyAction extends ActionSupport {    // 上传多个文件时,上传文件的三个属性需要使用数组或集合的方式    // 1.上传的文件的集合或数组    private List<File> upload;    // 2.上传文件的MIME类型    private List<String> uploadContentType;    // 3.上传文件的名称    private List<String> uploadFileName;    // 4. 提供get/set方法    public List<File> getUpload() {        return upload;    }    public void setUpload(List<File> upload) {        this.upload = upload;    }    public List<String> getUploadContentType() {        return uploadContentType;    }    public void setUploadContentType(List<String> uploadContentType) {        this.uploadContentType = uploadContentType;    }    public List<String> getUploadFileName() {        return uploadFileName;    }    public void setUploadFileName(List<String> uploadFileName) {        this.uploadFileName = uploadFileName;    }    /**     * 上传多个文件的方法     */    public String manyFileUpload() {        // 获取文件存储的路径        String path = ServletActionContext.getServletContext().getRealPath("/upload");        // 遍历上传的文件,将文件保存到磁盘        for (int i = 0; i < upload.size(); i++) {            try {                FileUtils.copyFile(upload.get(i), new File(path, uploadFileName.get(i)));            } catch (IOException e) {                e.printStackTrace();                return ERROR;            }        }        return SUCCESS;    }}

配置文件:使用分模块的配置文件方式

<!--struts2.xml配置文件--><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    "http://struts.apache.org/dtds/struts-2.3.dtd"><struts>    <!-- 设置为开发模式 -->    <constant name="struts.devMode" value="true"></constant>    <!-- 设置全局的编码格式,解决post提交中文乱码问题 -->    <constant name="struts.i18n.encoding" value="UTF-8"></constant>    <include file="fileupload.xml" /></struts><!-- fileupload.xml配置文件 --><?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    "http://struts.apache.org/dtds/struts-2.3.dtd"><struts>    <!-- 设置为开发模式 -->    <constant name="struts.devMode" value="true"></constant>    <!-- 设置全局的编码格式,解决post提交中文乱码问题 -->    <constant name="struts.i18n.encoding" value="UTF-8"></constant>    <!-- 配置全局的上传文件最大值的常量,默认值是2097152 -->    <constant name="struts.multipart.maxSize" value="2097152000" />    <!--         文件上传时,默认的上传文件的大小限制为2097152(2m),要改变上传文件大小的限制,        可以通过一下配置方式解决:        1.配置全局的上传文件的最大值,针对的是所有的action有效;        2.上传文件是由fileUpload拦截器实现的,            可以通过更改拦截器源码中的上传文件的大小设置来修改上传文件的最大值,针对配置的action有效 -->    <package name="fileupload" namespace="/" extends="struts-default">        <action name="uploadMany" class="com.itheima.fileupload.action.UploadManyAction"             method="manyFileUpload">            <!-- 配置上传文件出现问题时,跳转到的页面,系统自动跳转 -->            <result name="input">/error.jsp</result>            <!-- 设置上传文件成功的页面视图 -->            <result name="success">/success.jsp</result>            <!-- 设置上传文件失败的页面视图 -->            <result name="error">/error.jsp</result>        </action>    </package></struts>

2. struts2中Ajax

2.1 json数据工具

​ json简单说就是javascript中的对象和数组,所以这两种结构就是对象和数组两种结构,通过这两种结构可以表示各种复杂的结构。

  1. 对象:对象在js中表示为“{}”括起来的内容,数据结构为 {key:value,key:value,…}的键值对的结构,在面向对象的语言中,key为对象的属性,value为对应的属性值,所以很容易理解,取值方法为对象.key 获取属性值,这个属性值的类型可以是数字、字符串、数组、对象几种。

  2. 数组:数组在js中是中括号“[]”括起来的内容,数据结构为[“java”,”javascript”,”vb”,…],取值方式和所有语言中一样,使用索引获取,字段值的类型可以是数字、字符串、数组、对象几种。

    经过对象、数组2种结构就可以组合成复杂的数据结构了。

fastjson工具类使用:推荐使用

​ fastjson是阿里巴巴旗下的开源的json数据转换工具。使用简单方便。fastjson使用需要导入jar包:fastjson-1.2.9.jar

/** * 用户的实体类  User */public class User {    private String username;    private String password;    @JSONField(format="yyyy-mm-dd")  // 通过配置注解的方式解决日期格式化问题    private Date birthday;    get/set方法}/** * fastjson的功能测试类 * fastjson工具类,处理json数据 * fastjson需要导入jar包:fastjson-1.2.9.jar */public class FastJsonDemo {    @Test    // 1.将对象或Map集合数据转化为json数据,使用的JSONObject类    public void demo() {        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        // 1. 将对象或Map集合数据转换为json数据,使用的JSONObject对象        String json = JSONObject.toJSONString(user);        System.out.println(json);         // {"birthday":1497532102793,"password":"sunmos","username":"somnus"}    }    @Test    // 2. 将List集合数据转化为json数据,使用的JSONArray类    public void demo2() {        // 2.将list集合数据转换为json数据,使用的        List<User> list = new ArrayList<User>();        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        User user2 = new User();        user2.setUsername("somnus");        user2.setPassword("sunmos");        user2.setBirthday(new Date());        list.add(user);        list.add(user2);        String json1 = JSONArray.toJSONString(list);        System.out.println(json1);        // [{"birthday":1497532378161,"password":"sunmos","username":"somnus"},        // {"birthday":1497532378161,"password":"sunmos","username":"somnus"}]        // 当在user类的birthday属性添加@JSONField(format="yyyy-mm-dd"),进行日期的格式化显示    }    @Test    // 3. 过滤对象中某些属性不出现在json数据中    public void demo3() {        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        // 自定义过滤对象中字段是否出现在json数据中        SerializeFilter filter = new PropertyFilter() {            @Override            /**             * @param arg0  要转换为json数据对象             * @param arg1 对象的属性名称             * @param arg2 对象属性的值             */            public boolean apply(Object arg0, String arg1, Object arg2) {                if(arg0.equals("username")) { // 只过滤username不出现在json数据中                    return false; // 代表该字段不在json数据中出现                }                return true; // 代表可以出现在json数据中            }        };        String json = JSONObject.toJSONString(user, filter);        System.out.println(json); // {"birthday":"2017-30-15","password":"sunmos","username":"somnus"}    }}

Jackson工具类:

/** * 用户的实体类  User */@JsonIgnoreProperties({"username","birthday"}) // 过滤某些属性不出现在json中@JsonFilter("filter") // 使用注册过滤器的方式过滤某些属性不出现在json中public class User {    private String username;    private String password;    @JsonIgnore    private Date birthday;    get/set方法}/** * Jackson工具的测试类 * Jackson工具类的使用:是springmvc框架底层使用的技术 * Jackson使用需要导入jar包:jackson-all-1.9.0.jar */public class JacksonDemo {    @Test    // 1. 将对象或Map集合数据转换为json数据,使用的ObjectMapper对象    public void demo1(){        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        // 将对象转换为json数据        ObjectMapper mapper = new ObjectMapper();        try {            String json = mapper.writeValueAsString(user);            System.out.println(json);            // {"username":"somnus","password":"sunmos","birthday":1497534200710}        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    // 2. 将对象或Map集合数据转换为json数据,使用的ObjectMapper对象    // 日期类型的转换    public void demo2(){        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        // 将对象转换为json数据        ObjectMapper mapper = new ObjectMapper();        try {            // 设置日期类型的转换格式            mapper.setDateFormat(new SimpleDateFormat("yyyy-mm-dd"));            // {"username":"somnus","password":"sunmos","birthday":"2017-51-15"}            String json = mapper.writeValueAsString(user);            System.out.println(json);            // {"username":"somnus","password":"sunmos","birthday":1497534200710}        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    // 3. 将对象或Map集合数据转换为json数据,使用的ObjectMapper对象    // 过滤对象的某些属性不出现在json数据中    // 可以在对象的类上加注解:@JsonIgnoreProperties({"username","birthday"})    // 可以在不需要出现的属性上加注解:@JsonIgnore    public void demo3(){        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        // 将对象转换为json数据        ObjectMapper mapper = new ObjectMapper();        try {            // 设置日期类型的转换格式            mapper.setDateFormat(new SimpleDateFormat("yyyy-mm-dd"));            String json = mapper.writeValueAsString(user);            System.out.println(json); // {"password":"sunmos"}        } catch (IOException e) {            e.printStackTrace();        }    }    @Test    // 4. 将对象或Map集合数据转换为json数据,使用的ObjectMapper对象    // 过滤对象的某些属性不出现在json数据中    // 通过实现过滤器,需要在对象的类上加上注解:    public void demo4(){        User user = new User();        user.setUsername("somnus");        user.setPassword("sunmos");        user.setBirthday(new Date());        // 将对象转换为json数据        ObjectMapper mapper = new ObjectMapper();        try {            // 设置日期类型的转换格式            mapper.setDateFormat(new SimpleDateFormat("yyyy-mm-dd"));            // 设置过滤属性,确定某些属性出现在json数据中,filter是过滤属性类的名称,需要添加在对象的注解中            FilterProvider filterProvider = new SimpleFilterProvider().addFilter                    ("filter", SimpleBeanPropertyFilter.filterOutAllExcept("username","birthday"));            // 设置过滤某些属性,确定某些属性不出现在json数据中            // FilterProvider filterProvider2 = new SimpleFilterProvider().addFilter            //      ("filter", SimpleBeanPropertyFilter.serializeAllExcept("username","birthday"));            // 设置过滤器            mapper.setFilters(filterProvider);            String json = mapper.writeValueAsString(user);            System.out.println(json);        } catch (IOException e) {            e.printStackTrace();        }    }}

2.2 struts2框架中Ajax

​ 在struts2中框架中可以通过原始的response对象进行Ajax的请求响应数据,同样struts2框架也提供了特有的响应Ajax请求的方式。推荐使用传统的方式进行Ajax请求的响应(操作稍微简单些)。

使用传统response方式进行Ajax请求的响应:要注意设置响应数据的编码格式(防止中文数据乱码)

注册案例:输入用户名,当输入框失去焦点时,显示输入的用户名是否可用,使用的Jackson工具类完成数据转换为json格式。

前端jsp页面:

<title>注册页面</title><script type="text/javascript" src="/struts2-day03/js/jquery-1.8.3.js"></script><script type="text/javascript">    function checkUsername(){        //1.获取文本框中的信息        var usernameValue=$("#username").val();        //2.向服务器发送请求        $.post("/struts2-day03/checkUsername",{"username":usernameValue},function(data){            //date的json数据  {"flag":true,"message":"用户名可用"}             var jsonObject=eval(data); //将data转换成js对象                       var html="";            if(jsonObject.flag){                //可以使用                html="<font color='green'>"+jsonObject.message+"</font>";            }else{                //不可以使用                html="<font color='red'>"+jsonObject.message+"</font>";            }            $("#username_msg").html(html);        },"json");    }</script>

服务器端处理Ajax请求:

/** * 处理Ajax请求的action中的方法 */public void checkUsername() {    // 处理响应数据中文乱码    ServletActionContext.getResponse().setCharacterEncoding("utf-8");    // 1.获取请求参数username    String username = ServletActionContext.getRequest().getParameter("username");    // 2.判断username是否可用    // 3.根据上述判断,向浏览器响应json数据    Result result = new Result();    if ("tom".equalsIgnoreCase(username)) {        // 不可以使用        result.setFlag(false);        result.setMessage("用户名已经被占用");    } else {        // 可以使用        result.setFlag(true);        result.setMessage("用户名可以使用");    }    // 将result转换成json---适合使用jackson完成操作    ObjectMapper mapper = new ObjectMapper();    try {        // String json = mapper.writeValueAsString(result);        // 通过response响应数据到浏览器        // ServletActionContext.getResponse().getWriter().write(json);        mapper.writeValue(ServletActionContext.getResponse().getWriter(), result);    } catch (IOException e) {        e.printStackTrace();    }}/** * 响应数据的封装类 */public class Result {    private boolean flag; // 描述是否可用    private String message; // 描述信息    get/set方法}

使用struts2中内置的响应Ajax的json插件:了解

使用struts2内置的json工具类响应Ajax请求的步骤:需要引入jar包:struts2-json-plugin-2.3.24.jar

  1. 将项目下的struts.xml配置文件中package继承的包改为< package extends=”json-default”>;
  2. 处理Ajax请求的Action的返回视图< result name=”” type=”json”> type类型设置为json-default中定义的result-type的name属性值json;
  3. 配置上面两步后,struts2框架会将valueStack中的栈顶元素转换成json响应到浏览器。

案例:前台页面通过Ajax请求商品的数据并显示

服务器端处理:

public class ProductAction {    public String showProduct() {        // 1.将数据得到List<Product>        Product p1 = new Product();        p1.setId(1);        p1.setName("电视机");        p1.setPrice(2000);        Product p2 = new Product();        p2.setId(2);        p2.setName("电冰箱");        p2.setPrice(3000);        List<Product> ps = new ArrayList<Product>();        ps.add(p1);        ps.add(p2);        // 2.将List<Product>压入到valueStack栈顶        ActionContext.getContext().getValueStack().set("ps", ps);        return "success";    }}

struts.xml配置文件的配置:商品的所有属性值均会被转换为json数据

<struts>    <package name="default" namespace="/" extends="json-default">        <action name="showProduct" class="cn.action.ProductAction" method="showProduct">            <result name="success" type="json"></result>        </action>    </package></struts>

响应的json数据的处理–方式1:弊端是所有的action通过Ajax获取商品数据均没有被注解掉的属性值

// 在商品的实体类中的属性的get方法上添加注解,则该字段就不会出现在json数据中@JSON(serialize = false)public Date getReleaseDate() {  return releaseDate;}

响应的json数据的处理–方式2:通过配置文件设置,org.apache.struts2.json.JSONResult类中有两个属性可以设置属性是否出现在json数据中。

<struts>    <package name="default" namespace="/" extends="json-default">        <action name="showProduct" class="cn.action.ProductAction" method="showProduct">            <result name="success" type="json">                <!--设置响应的数据中是否包含或不包含属性  其中的特殊字符需要进行转义-->                <!--设置不包含在json中的字段-->                <param name="excludeProperties">ps\[\d+\]\.releaseDate</param>                <!--设置包含在json中的字段-->                <param name="includeProperties">ps\[\d+\]\.id,ps\[\d+\]\.name</param>            </result>        </action>    </package></struts>

响应的json数据的处理–方式3:org.apache.struts2.json.JSONResult类中还有个属性root,可以通过设置root的属性来设置属性是否出现在json数据中

<!--设置root:root是json插件源码中的一个属性值;    没有设置root前返回的json结构:ps:[{},{}];    设置root它的根为ps后的返回的json结构: [{},{}],不能出现ps去引用其中的字段--><struts>    <package name="default" namespace="/" extends="json-default">        <action name="showProduct" class="cn.action.ProductAction" method="showProduct">            <result name="success" type="json">                <!--设置root属性为存储在值栈中响应数据的名称-->                <param name="root">ps</param>                <!--设置不包含在json中的字段-->                <param name="excludeProperties">\[\d+\]\.releaseDate</param>                <!--设置包含在json中的字段-->                <!-- <param name="includeProperties">ps\[\d+\]\.id,ps\[\d+\]\.name</param> -->            </result>        </action>    </package></struts>

前端页面:

<script type="text/javascript" src="/struts2-day03/js/jquery-1.8.3.js"></script><script type="text/javascript">    //页面加载完成后操作    $(function() {        $("#a").toggle(function() {            //1.向服务器发送请求,获取商品信息            $.post("/struts2-day03/showProduct",function(data) {                //2.将响应回的json数据转换成html代码,在div中展示                var html = "<table border='1'><tr><td>编号</td><td>名称</td><td>价格</td></tr>";                //[{"id":1,"name":"电视机","price":2000.0},{"id":2,"name":"电冰箱","price":3000.0}]                var jsonObj = eval(data);                for (var i = 0; i < jsonObj.length; i++) {                    html += "<tr><td>"+ jsonObj[i].id+ "</td><td>"+ jsonObj[i].name                            + "</td><td>"+ jsonObj[i].price+ "</td></tr>";                }                html += "</table>";                $("#productMsg").html(html);            }, "json");        }, function() {            $("#productMsg").html("");        });    });</script></head><body>    <a href="javascript:void(0)" id="a">显示商品信息</a>    <div id="productMsg"></div></body>

3. struts2注解开发

​ struts2注解开发需要引入jar包:struts2-convention-plugin-2.3.24.jar ,注解开发与非注解开发中struts.xml配置文件是相互对应的。

@Namespace("/")  // 相当于  <package  namespace="/">@ParentPackage("struts-default") // <package extends="struts-default">public class HelloAction {    // <action name="hello" class=""  method="">    //<result name="" type="">/success.jsp</result>    @Action(value="hello",results={@Result(name="success",location="/success.jsp")})    public String sayHello() {        System.out.println("hello world");        return "success";    }}
注解与配置文件的对应关系:# @Namespace来代替<package  namespace=””># @ParentPackage来代替<package extends=””># @Action来描述关于配置中的<action>配置# value属性描述action配置中的<action name=””>的name属性值,指示该方法的访问路径名称# 使用@Action的results来描述关于结果类型的配置<result name=”” type=””># @Action(results={@Result(name=””,type=””,location=””)})

其他注解:

# @Actions  通过多个映射路径来访问统一action中的方法    public class HelloWorld extends ActionSupport {        @Actions({            @Action("/different/url"), 访问路径1            @Action("/another/url") 访问路径2        })        public String execute() {            return SUCCESS;        }    }# @Results  配置全局的结果视图    @Results({        @Result(name="failure", location="fail.jsp")    })    public class HelloWorld extends ActionSupport {...}# @InterceptorRef  配置拦截器    public class HelloWorld extends ActionSupport {          @Action(value="action1", interceptorRefs=@InterceptorRef("validation"))          public String execute() {                return SUCCESS;          }    }

struts2注解中action被识别的并执行的原理:

​ 在struts2的插件包(struts2-convention-plugin-2.3.24.jar)中的struts-plugin.xml配置文件中定义了全局的变量<constant name="struts.convention.package.locators" value="action,actions,struts,struts2"/> ,当自定义的action所在的包包含这几个单词action/actions/struts/struts2的包下时,struts2会扫描注解action类;可以通过修改这个全局的变量,使得使用注解的action能被识别。