zoukankan      html  css  js  c++  java
  • Struts2

    Struts2中使用JSON做数据的get/post,方法有很多种,这里有一篇文章比较详细的列举出了JSON在Struts和Servlet中如何GET:

    http://yshjava.iteye.com/blog/1333104

    Servlet的不写了,也就是how to use HttpRequest和HttpResponse。主要是在Struts2身上。

    以文章所描述的方法似乎总是差了那么点东西:可以不使用那么多配置吗?

    于是研究了些时间,可以这么玩:

    1)Eclipse引用Struts2的JSON plug-in和Convertion plug-in。

    2)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>
    
        <!-- 把它设置为开发模式,发布时要设置为false -->
        <constant name="struts.devMode" value="true" />
        <!-- 设置在class被修改时是否热加载,发布时要设置为false -->
        <constant name="struts.convention.classes.reload" value="true"/>
        <!-- 自动动态方法的调用,使用这个设置后可以这样调用:action!method -->
        <constant name="struts.enable.DynamicMethodInvocation" value="true" />
        <!-- 指定jsp文件所在的目录地址 -->
        <constant name="struts.convention.result.path" value="/WEB-INF/content/" />
        <!-- 用于配置包名后缀。默认为action、actions、struts-->
        <!-- <constant name="struts.convention.package.locators" value="controller" /> -->
        <constant name="struts.convention.action.packages" value="com.my.controller"></constant>
        <!-- 用于配置类名后缀,默认为Action,设置后,Struts2只会去找这种后缀名的类做映射 -->
        <constant name="struts.convention.action.suffix" value="Controller"/>
        <!-- 设置即使没有@Action注释,依然创建Action映射。默认值是false。因为Convention-Plugin是约定优于配置的风格,
            可以不通过注解根据预先的定义就能访问相应Action中的方法 -->
        <constant name="struts.convention.action.mapAllMatches" value="true"/>
        <!-- 自定义jsp文件命名的分隔符 -->
        <constant name="struts.convention.action.name.separator" value="-" />
        <!-- 国际化资源文件名称 -->
        <constant name="struts.custom.i18n.resources" value="i18n" />
        <!-- 是否自动加载国际化资源文件  -->
        <constant name="struts.i18n.reload" value="true" />
        <!-- 浏览器是否缓存静态内容 -->
        <constant name="struts.serve.static.browserCache" value="false" />
         <!-- 上传文件大小限制设置 -->
        <constant name="struts.multipart.maxSize" value="-1" />
        <!-- 主题,将值设置为simple,即不使用UI模板。这将不会生成额外的html标签 -->
        <constant name="struts.ui.theme" value="simple" />
        <!-- 编码格式 -->
        <constant name="struts.i18n.encoding" value="UTF-8" />
        <!-- 设置默认package -->
        <constant name="struts.convention.default.parent.package" value="default"></constant>
    
        <package name="default" namespace="/" extends="json-default">
            <interceptors>
                <interceptor name="cacheInterceptor" class="com.my.interceptor.CacheInterceptor" />
                <interceptor-stack name="cacheStack">
                    <interceptor-ref name="defaultStack"></interceptor-ref>
                    <interceptor-ref name="paramsPrepareParamsStack"></interceptor-ref>
                    <interceptor-ref name="cacheInterceptor"></interceptor-ref>
                </interceptor-stack>
            </interceptors>
            <default-interceptor-ref name="cacheStack"></default-interceptor-ref>
            <default-action-ref name="index" />
            <global-results>
                <!-- <result name="error">/error.jsp</result> -->
                <result name="json" type="json">
                    <!-- 是否包括父类的属性输出,默认true. -->
                    <!-- <param name="ignoreHierarchy">false</param> -->
                    <!-- 是否输出null值的属性,默认false -->
                    <!-- <param name="excludeNullProperties">true</param> -->
                </result>
            </global-results>
            <global-exception-mappings>
                <exception-mapping exception="java.lang.Exception" result="error"/>
            </global-exception-mappings>
        </package>
    
    </struts>

    上面有两个<param/>注释了,使用方法已经有写在里头,如果需要,可以加上或在类中加入@Results。

    关键点在于把<package />中的 extends设置为json-default,以及在global-results中的这个json result。

    3)加入一个UserControl.java

    package com.my.controller;
    
    import java.io.IOException;
    import java.util.ArrayList;
    import java.util.List;
    
    import net.sf.json.JSONObject;
    
    import com.my.beans.User;
    import com.opensymphony.xwork2.ActionSupport;
    
    @SuppressWarnings("serial")
    public class UserController extends ActionSupport {
        
        private User user = new User();
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        private String json;
        public String getJson() {
            return json;
        }
    
        public void setJson(String json) {
            this.json = json;
        }
        
        private List<User> users = new ArrayList<User>();
        public List<User> getUsers() {
            return users;
        }
    
        public void setUsers(List<User> users) {
            this.users = users;
        }
    
        @Override
        public String execute() throws Exception {
            return SUCCESS;
        }
    
        public String loadModel() throws IOException {
            System.out.println("json=" + getJson());
            System.out.println("user=" + getUser().getUsername());
            System.out.println("users=" + getUsers().size());
            User userBean = new User();
            userBean.setUsername("robin");
            users.add(userBean);
            this.setJson(JSONObject.fromObject(userBean).toString());
            return "json";
        }
        
    }

    这里没有什么特别的东西,就是一些getter/setter,以及一个loadModel() action

    4)JS对JSON的提交:

    var url = "user!loadModel";
    var params = {
        "json": "json string",
        "user.username" : "zhang",
        "users[0].username" : "zhang1",
        "users[0].password" : "1",
        "users[1].username" : "zhang2",
        "users[1].password" : "2",
    };
    $.post(url, params, function callback(data) {
        console.log(data)
    });

    这里是重点。

    可以看到这段JS里的params有:json/user.username/users[X].username

    其中:

    a) json

    对应的就是上页java中的getJson/setJson,这个东东列出来是可以用于在页面与服务器之间传递JSON字符串用的。如果你需要在action中输出或提交json的字符串,它有很大作用,直接到位。但是缺点是要自己去将对象转化为json string以及json string转化为对象。

    b) user.username

    这样的写法可以在后台java中直接转化成了对象。user.username中的user就是java中的user object。

    c) users[0].username

    这可以直接转化成后台java中的List<user>对象users。

    可以看出,Struts2是可以完成将json直接转化成java object的。不过这样的写法,不是好的。因为这个JS的JSON只能称作是一个字符串拼接,不是一个JSON object


    还有一种方法,使用ModelDriven:

    package com.my.controller;
    
    import com.my.beans.User;
    import com.opensymphony.xwork2.ActionSupport;
    import com.opensymphony.xwork2.ModelDriven;
    
    @SuppressWarnings("serial")
    public class UserModelController extends ActionSupport implements
            ModelDriven<Object> {
    
        private User user = new User();
    
        @Override
        public Object getModel() {
            return user;
        }
    
        @Override
        public String execute() throws Exception {
            return SUCCESS;
        }
    
        public String load() {
            return "json";
        }
    
    }

    使用ModelDriven,可以JS直接提交JSON了:

    var url = "user-model!load";
    var params = {
        "username": "zhang1",
        "password": "123456"
    };
    $.post(url, params, function callback(data) {
        console.log(data)
    });

    这个params才是真正的JSON object,它会被ModelDriven直接转成user model。

    但是:它似乎不能提交List object。至今写文时也没有找到在ModelDriven中可以提交JSON array to List的方法。

    如果需要提交复杂的JSON到服务器,如果你用的是Struts,使用第一种方法的json的getter/setter吧。


    个人Struts2研究了些日子对它的总结:

    1)如果是使用MVC开发的,它是个非常好的选择。因为它提供了非常丰富的可配置的功能及标签。但是也正是因为这些复杂的配置,会使用得开发及维护上带来很多诟病,比如速度上、发布上、后期清理上的问题。既然MVC的理想是约定优于配置,那为什么还需要这么复杂的配置呢?

    2)它的Action在URL上的表现上让人看着不舒服,因为太不restful了,同时它的restful plug-in似乎没太多的可扩展性。说白了,如果要做rest,理应不选择它。

    3)struts它合适于使用普通的form提交开发当中(即MVC)。不合适于MVVM模式的开发。如果想使用MVVM,那么建议使用SpringMVC,而不是Struts。

    沉思:

    如果MVVM是未来的主流设计,那么struts将会有天淡去在这个舞台。

  • 相关阅读:
    省选模拟25
    有关树链剖分
    有关矩阵的一点讨论
    洛谷 P3390 【模板】矩阵快速幂
    HDU P2089
    有关动态规划(主要是数位DP)的一点讨论
    HDU P2222 Keywords Search
    普通平衡树Tyvj1728、luogu P3369 (treap)
    POJ P2104 K-th Number
    POJ 3311Hie with the Pie
  • 原文地址:https://www.cnblogs.com/HD/p/3673681.html
Copyright © 2011-2022 走看看