public String testByAction() {
        // dataMap 中的数据将会被 Struts2 转换成 JSON 字符串,所以这里要先清空其中的数据
        dataMap.clear();
        User user = new User();
        user.setId("123");
        user.setName("JSONActionStruts2");
        user.setPassword("123");
        user.setSay("Hello world !");
        dataMap.put("user", user);
        // 放入一个是否操作成功的标识
        dataMap.put("success", true);
        // 返回结果
        return SUCCESS;
    }struts.xml 中 action 的配置:<package name="json" extends="json-default" namespace="/test">
        <action name="testByAction"
            class="cn.ysh.studio.struts2.json.demo.action.UserAction" method="testByAction">
            <result type="json">
                <!-- 这里指定将被 Struts2 序列化的属性,该属性在 action 中必须有对应的 getter 方法 -->
                <param name="root">dataMap</param>
            </result>
        </action>
</package>凡是使用 Struts2 序列化对象到 JSON 的 action,所在的 package 必须继承自 json-default,注意,这里唯一的 result,没有指定 name 属性。

解决方案 »

  1.   

    看着么多分,我来说下,我把我项目的部分源代码给你看看,也不多说了,都比较简单,实在看不懂我们私聊吧,希望给全分,谢谢。主要是structs配置(回传客户端),转json(简单的json转换)那里。如下:首先,你要回传值给前台,那structs里结果类型就要配置一个plainText,我们才能回写东西回去
    <action name="menuAction" class="menuAction">
    <result type="plainText" />
    </action>然后再你Action里,将你的list先转换为json格式的字符串,然后回写到客户端,buildObjListToJson,toWrite这两个方法你可以自己写,没有任何难度。//这是我的action,分发方式和你的不一样,但是result都是一样,继承execute的返回值任意字符串就行。
    public void getIllusionComments() {
    message = illusionCommentService.getIllusionComments(request
    .getParameterMap());//业务处理,结果是经过封装的list
    String strData = JsonBuilder.getInstance().buildObjListToJson(
    (long) message.getExtendInt1(),
    (List<IllusionComment>) message.getObj(), true);//将list转换为json格式的字符串,方法见下
    toWrite(strData);//回写客户端,方法见下
    }/**
     * 为分页列表提供Json封装
     * 
     * @param count
     *            记录总数
     * @param entities
     *            实体列表
     * @param excludes
     *            在json生成时需要排除的属性名称
     * @return
     */
    public String buildObjListToJson(Long count,
    Collection<? extends Object> records, boolean listJson) {
    try {
    StringBuffer pageJson = null;
    if (listJson) {
    pageJson = new StringBuffer("{totalCount:" + count + ","
    + "rows" + ":");
    } else {
    pageJson = new StringBuffer("");
    }
    // 序列化配置项
    // MAP中的key如果对应的value为null则不参与json输出
    // logger.debug("into buildPageJson..."); StringWriter w = new StringWriter();
    JsonHolder.mapper.configure(
    SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    JsonHolder.mapper.writeValue(w, records);
    pageJson.append(w);
    w.close(); if (listJson) {
    pageJson.append("}");
    } else {
    pageJson.append("");
    }
    return pageJson.toString();
    } catch (Exception ex) {
    ex.printStackTrace();
    return null;
    }
    }       /**
     * 将数据写出到前台 默认为UTF-8编码
     * 
     * @param contents
     */
    protected void toWrite(String contents) {
    response.setContentType("text/html;charset=UTF-8");
    if (ObjectUtils.isNotNull(response)) {
    Writer writer = null;
    try {
    response.setCharacterEncoding("utf-8");
    writer = response.getWriter();
    writer.write(contents);
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    log.debug("write into response, contents is : " + contents);
    try {
    writer.flush();
    writer.close();
    response.flushBuffer();
    } catch (IOException e) {
    e.printStackTrace();
    }
    }
    }
    }
      

  2.   

    Struts2.x很久没用了,先顶顶吧。
      

  3.   

    我已经写好public class Tree {
        private int id;
        private String text;
        private boolean leaf;
        private String cls;
        private List<Menu> children;TreeDAOImpl.java
    public List<Tree> findAllRole() {
    String hql = "from Tree";
    return (List<Tree>)this.getHibernateTemplate().find(hql);
    }
    在Action 里如果不连接数据库取数就这样,所以想把下面的改成可以取数据库的方式
     public String execute() {        menus = new ArrayList<Menu>();
           
            Menu benz = new Menu();
            benz.setText("广东");
            benz.setCls("folder");
            benz.setLeaf(false);
            benz.setId(10);
            menus.add(benz);
           
            List<Menu> benzList = new ArrayList<Menu>();
            benz.setChildren(benzList);
           
            Menu menu;
            menu = new Menu();
            menu.setText("广州");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(11);
            benzList.add(menu);
            menu = new Menu();
            menu.setText("深圳");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(12);
            benzList.add(menu);
           
            Menu bmw = new Menu();
            bmw.setText("广西");
            bmw.setCls("folder");
            bmw.setLeaf(false);
            bmw.setId(20);
            menus.add(bmw);
           
            List<Menu> bmwList = new ArrayList<Menu>();
            bmw.setChildren(bmwList);
           
            menu = new Menu();
            menu.setText("桂林");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(21);
            bmwList.add(menu);
           
            menu = new Menu();
            menu.setText("北海");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(22);
            bmwList.add(menu);
           
            JSONArray jsonObject = JSONArray.fromObject(menus);
            try {
                menuString = jsonObject.toString();
            } catch (Exception e) {
                menuString = "ss";
            }
            
            System.out.println("output menuString: " + menuString);        return "success";
        }
      

  4.   

    数据取到后自己转json 也可以
      

  5.   

    打印出来的menuString这个是你想要的么,如果是参考我的toWrite(),回写到客户端就可以了
    另外,把逻辑写在action里?不推荐这样,搞个服务也逻辑,action应该像我那样一个请求10行以内的代码,
    message = illusionCommentService.getIllusionComments(request
                    .getParameterMap());//业务处理
    这里面不但有大量的数据库操作,还可能包括邮件、外部接口等异步操作,所以MVC这种模式还是要严格遵守的。
      

  6.   

    现在是不知道怎把下面的改成去读数据库的,在DAO里改或者action里改都行
    public String execute() {        menus = new ArrayList<Menu>();
           
            Menu benz = new Menu();
            benz.setText("广东");
            benz.setCls("folder");
            benz.setLeaf(false);
            benz.setId(10);
            menus.add(benz);
           
            List<Menu> benzList = new ArrayList<Menu>();
            benz.setChildren(benzList);
           
            Menu menu;
            menu = new Menu();
            menu.setText("广州");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(11);
            benzList.add(menu);
            menu = new Menu();
            menu.setText("深圳");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(12);
            benzList.add(menu);
           
            Menu bmw = new Menu();
            bmw.setText("广西");
            bmw.setCls("folder");
            bmw.setLeaf(false);
            bmw.setId(20);
            menus.add(bmw);
           
            List<Menu> bmwList = new ArrayList<Menu>();
            bmw.setChildren(bmwList);
           
            menu = new Menu();
            menu.setText("桂林");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(21);
            bmwList.add(menu);
           
            menu = new Menu();
            menu.setText("北海");
            menu.setCls("file");
            menu.setLeaf(true);
            menu.setId(22);
            bmwList.add(menu);
           
            JSONArray jsonObject = JSONArray.fromObject(menus);
            try {
                menuString = jsonObject.toString();
            } catch (Exception e) {
                menuString = "ss";
            }
            
            System.out.println("output menuString: " + menuString);        return "success";
        }
      

  7.   

    其实楼主可以直接将json字符串写入到输出流给客户端的, 输出流通过response.getOutputStream()获取, Extjs的树加载会获取这个流返回的json数据, 之前我的项目中返回json数据都是用的这种方法, 感觉用json-lib.jar不是那么方便
      

  8.   

    接上楼:
    这个方法应该能帮到你
    public void outputResult(HttpServletResponse res,
    Map<String, Object> map) {
    PrintWriter out = null;
    try {
    res.setCharacterEncoding("UTF-8");
    out = res.getWriter();
    logger.info("进入输出结果到前台的界面的方法");
    // 输出到前台
    ObjectMapper mapper = new ObjectMapper();
    try {
    mapper.writeValue(out, map);
    } catch (JsonGenerationException e) {
    logger.info(e.getStackTrace());
    } catch (JsonMappingException e) {
    logger.info(e.getStackTrace());
    } catch (IOException e) {
    logger.info(e.getStackTrace());
    }
    } catch (IOException e) {
    e.printStackTrace();
    } finally {
    out.flush();
    out.close();
    }
    }
      

  9.   

    理解错了,我想是读数据库的数据,然后转成[{"id":"0",text:'广东11',"cls":"folder","leaf":false,"children":[{"text":"广州22","cls":"file","leaf":true,"children":[],"id":11},{"text":"深圳","cls":"file","leaf":true,"children":[],"id":12}],"id":10},{"text":"广西","cls":"folder","leaf":false,"children":[{"text":"桂林","cls":"file","leaf":true,"children":[],"id":21},{"text":"北海","cls":"file","leaf":true,"children":[],"id":22}],"id":20}] 是读取数据这部分不知道怎样写
      

  10.   

    看你用的是hibernate,你不是都写了一个dao了么findAllRole这个,就按这种方式去你的库里查Menu啊,得到你要List<Menu>就OK了啊,然后转成json格式字符串 回写到前台。
    功能非常基础,关键考验你数据库的设计,做菜单的话一般要考虑很多RBAC权限方面的问题以及菜单层次的问题。
    我不知道你怎么配的hibernate,我使用spring托管hibernate以及hibernateTemplate,和你实现方式不一样,但是大体没什么出入,都是对象化的查询。如下:
    hibernateTemplate.find("from " + clazz.getName());
    这些都是hibernate的基础,非常非常简单,网上一堆资料。
      

  11.   

    理解错了,我想是读数据库的数据,然后转成[{"id":"0",text:'广东11',"cls":"folder","leaf":false,"children":[{"text":"广州22","cls":"file","leaf":true,"children":[],"id":11},{"text":"深圳","cls":"file","leaf":true,"children":[],"id":12}],"id":10},{"text":"广西","cls":"folder","leaf":false,"children":[{"text":"桂林","cls":"file","leaf":true,"children":[],"id":21},{"text":"北海","cls":"file","leaf":true,"children":[],"id":22}],"id":20}] 是读取数据这部分不知道怎样写
    通过父子关系去构造一个树,而不是把他们全取出来。比如根据广西,获取广西下面的市。有个children属性是该节点下面的子节点是这部分不知道怎写
      

  12.   


    通过父子关系去构造一个树,而不是把他们全取出来。比如根据广西,获取广西下面的市。有个children属性是该节点下面的子节点是这部分不知道怎写
      

  13.   

    多种方式,我只能帮你到这了,我觉得你的数据库设计也有问题,tree一个表就可以了为何搞这样,没见过有系统的菜单表是这么设计的,你要的方案如下:1.可以直接传where条件:
    whereStr = " name = '广西' ";//这个当然是作为参数的,不是写死的
     hibernateTemplate.find("from " + clazz.getName() + " where "
    + whereStr);2.hibernate基础,一对多。我是用的注解写的例子,ErNoBillItem是子表,配置文件也一样:
    @Entity
    @Table(name = "ER_BASE")
    @org.hibernate.annotations.Table(appliesTo = "ER_BASE", comment = "报销单信息表")
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    public class ErBase extends BsBase {
    @Id
    @Column(length = 90)
    private String bsId;
    // 补助报销明细集合
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "BSID")
    @OrderBy("inOrder")
    private Set<ErNoBillItem> erNoBillItems = new HashSet<ErNoBillItem>();}}
      

  14.   

    我有一个简单的方法,你是不是 想说,数据库里都好多条数据,通过parentid 数据之间会有父子关系,然后把他们转换成有父子关系的json字符串,我这边的方法是  后台写了一个递归的算法,很短,但是不好理解,然后 用fastJson 包下的方法转换成了你要的格式,我现在代码不在身边,如果需要,给我发邮件说明你的问题,我把代码发给你 [email protected]
      

  15.   


    这样取数我知道,我想要的是取数据库的数据的shuodehao