最近我在将APDPlat升级到Java8,由于之前有很多的同学希望我把APDPlat的struts2替换为spring mvc,所以我就决定试试看。
本次我把APDPlat的struts2改造为spring mvc的目标是:99.99%不改动JS、HTML、JSP等前端代码,只改JAVA代码!所以大家要先理解我的目标,然后再来看我的做法。
本文我们看两个转换前后的例子:
1、下拉列表服务,此类比较简单,只涉及一个方法store:
使用struts2:
@Scope("prototype") @Controller @Namespace("/dictionary") public class DicAction extends ExtJSSimpleAction<Dic> { @Resource private DicService dicService; private String dic; private String tree; private boolean justCode; /** * * 此类用来提供下拉列表服务,主要有两种下列类型: * 1、普通下拉选项 * 2、树形下拉选项 * @return 不需要返回值,直接给客户端写数据 * */ public String store(){ Dic dictionary=dicService.getDic(dic); if(dictionary==null){ LOG.info("没有找到数据词典 "+dic); return null; } if("true".equals(tree)){ String json = dicService.toStoreJson(dictionary); Struts2Utils.renderJson(json); }else{ List<Map<String,String>> data=new ArrayList<>(); for(DicItem item : dictionary.getDicItems()){ Map<String,String> map=new HashMap<>(); if(justCode){ map.put("value", item.getCode()); }else{ map.put("value", item.getId().toString()); } map.put("text", item.getName()); data.add(map); } Struts2Utils.renderJson(data); } return null; } public void setJustCode(boolean justCode) { this.justCode = justCode; } public void setTree(String tree) { this.tree = tree; } public void setDic(String dic) { this.dic = dic; } }
使用spring mvc:
@Scope("prototype") @Controller @RequestMapping("/dictionary") public class DicAction extends ExtJSSimpleAction<Dic> { @Resource private DicService dicService; /** * * 此类用来提供下拉列表服务,主要有两种下拉类型: * 1、普通下拉选项 * 2、树形下拉选项 * @param dic * @param tree * @param justCode * @return 返回值直接给客户端 */ @ResponseBody @RequestMapping("/dic!store.action") public String store(@RequestParam(required=false) String dic, @RequestParam(required=false) String tree, @RequestParam(required=false) String justCode){ Dic dictionary=dicService.getDic(dic); if(dictionary==null){ LOG.info("没有找到数据词典 "+dic); return ""; } if("true".equals(tree)){ String json = dicService.toStoreJson(dictionary); return json; }else{ List<Map<String,String>> data=new ArrayList<>(); dictionary.getDicItems().forEach(item -> { Map<String,String> itemMap=new HashMap<>(); if("true".equals(justCode)){ itemMap.put("value", item.getCode()); }else{ itemMap.put("value", item.getId().toString()); } itemMap.put("text", item.getName()); data.add(itemMap); }); String json = JSONArray.fromObject(data).toString(); return json; } } }
从上面我们可以看到,struts2和spring mvc的区别非常明显,struts2使用原型,spring mvc使用单例。
单例一定比原型快吗?创建一个对象的开销可以忽略吗?这个问题需要在自己的场景中考虑,不过大多时候我们是可以忽略的。
APDPlat之前使用struts2,每一个请求都会对应一个全新的Action,所以请求的参数就可以作为Action的字段来自动注入,言下之意就是Action中的所有方法都可以共用字段,而现在换成spring mvc了,不同的方法需要各自获取请求中的参数。
对比以上代码,我个人还是认为spring mvc的方式更好一些,对于Action(spring mvc叫Controller)来说,单例、无状态是比较理想的。
2、数据字典服务,此类比较复杂,涉及的方法有create、delete、updatePart、retrieve、query、store:
使用struts2:
@Scope("prototype") @Controller @Namespace("/dictionary") public class DicItemAction extends ExtJSSimpleAction<DicItem> { @Resource private DicService dicService; private String node; /** * 返回数据字典目录树 * @return */ public String store() { if (node == null) { return null; } Dic dic=null; if(node.trim().startsWith("root")){ dic = dicService.getRootDic(); }else{ int id=Integer.parseInt(node); dic = dicService.getDic(id); } if (dic != null) { String json = dicService.toJson(dic); Struts2Utils.renderJson(json); } return null; } public void setNode(String node) { this.node = node; } }
使用spring mvc:
@Scope("prototype") @Controller @RequestMapping("/dictionary") public class DicItemAction extends ExtJSSimpleAction<DicItem> { @Resource private DicService dicService; /** * 返回数据字典目录树 * @param node * @return */ @ResponseBody @RequestMapping("/dic-item!store.action") public String store(@RequestParam(required=false) String node) { if (node == null) { return "[]"; } Dic dic=null; if(node.trim().startsWith("root")){ dic = dicService.getRootDic(); }else{ int id=Integer.parseInt(node); dic = dicService.getDic(id); } if (dic != null) { String json = dicService.toJson(dic); return json; } return "[]"; } @ResponseBody @RequestMapping("/dic-item!query.action") public String query(@RequestParam(required=false) Integer start, @RequestParam(required=false) Integer limit, @RequestParam(required=false) String propertyCriteria, @RequestParam(required=false) String orderCriteria, @RequestParam(required=false) String queryString, @RequestParam(required=false) String search){ super.setStart(start); super.setLimit(limit); super.setPropertyCriteria(propertyCriteria); super.setOrderCriteria(orderCriteria); super.setQueryString(queryString); super.setSearch("true".equals(search)); return super.query(); } @ResponseBody @RequestMapping("/dic-item!retrieve.action") public String retrieve(@ModelAttribute DicItem model) { super.model = model; return super.retrieve(); } @ResponseBody @RequestMapping("/dic-item!delete.action") public String delete(@RequestParam String ids) { super.setIds(ids); return super.delete(); } @ResponseBody @RequestMapping("/dic-item!create.action") public String create(@ModelAttribute DicItem model) { super.model = model; return super.create(); } @ResponseBody @RequestMapping("/dic-item!updatePart.action") public String updatePart(@ModelAttribute DicItem model) { super.model = model; return super.updatePart(); } }
从上面可以看到,从struts2转换为spring mvc之后,代码一下子就增加了,父类的create、delete、updatePart、retrieve、query这5个方法对于spring mvc就无效了,而且模型注入的方式也不起作用了,下面我们要解决这两个问题。
要解决第一个问题,我们首先要改变struts2的URL调用方式,在struts2中,我们是这么调用Action的方法的,!后面是Action的方法名称:
http://localhost:8080/APDPlat_Web-2.6/dictionary/dic-item!query.action
如果我们不改变调用方式,上面刚说的那5个方法就无法抽象到父类中了,改变方式也挺简单,只需要把!改成/就可以了,在父类中增加如下代码并在前端JS中将!改成/:
@ResponseBody @RequestMapping("query.action") public String query(@RequestParam(required=false) Integer start, @RequestParam(required=false) Integer limit, @RequestParam(required=false) String propertyCriteria, @RequestParam(required=false) String orderCriteria, @RequestParam(required=false) String queryString, @RequestParam(required=false) String search){ super.setStart(start); super.setLimit(limit); super.setPropertyCriteria(propertyCriteria); super.setOrderCriteria(orderCriteria); super.setQueryString(queryString); setSearch("true".equals(search)); return query(); } @ResponseBody @RequestMapping("retrieve.action") public String retrieve(@ModelAttribute T model) { this.model = model; return retrieve(); } @ResponseBody @RequestMapping("delete.action") public String delete(@RequestParam String ids) { super.setIds(ids); return delete(); } @ResponseBody @RequestMapping("create.action") public String create(@ModelAttribute T model) { this.model = model; return create(); } @ResponseBody @RequestMapping("updatePart.action") public String updatePart(@ModelAttribute T model) { this.model = model; return updatePart(); }
关于第二个问题,在struts2中,注入Action的参数,要使用model.id这样的方式,model是Action的一个字段,而在spring mvc中,这样是不行的,需要做一个转换,在父类中增加如下代码以使spring mvc能适应struts2参数注入方式:
/** * 前端向后端传递模型参数的时候都有model.前缀 * @param binder */ @InitBinder public void initBinder(WebDataBinder binder) { binder.setFieldDefaultPrefix("model."); }
经过上面的改进,数据字典服务 使用spring mvc的代码升级为:
@Scope("prototype") @Controller @RequestMapping("/dictionary/dic-item/") public class DicItemAction extends ExtJSSimpleAction<DicItem> { @Resource private DicService dicService; /** * 返回数据字典目录树 * @param node * @return */ @ResponseBody @RequestMapping("store.action") public String store(@RequestParam(required=false) String node) { if (node == null) { return "[]"; } Dic dic=null; if(node.trim().startsWith("root")){ dic = dicService.getRootDic(); }else{ int id=Integer.parseInt(node); dic = dicService.getDic(id); } if (dic != null) { String json = dicService.toJson(dic); return json; } return "[]"; } }
相关推荐
struts1工作原理 struts2工作原理 struts1和struts2比较 spring mvc工作原理 struts和spring mvc比较
spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 ...
struts2+spring+springstruts2+spring+springstruts2+spring+spring
整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6。 此外,还有:log4j、slf4j、junit4、ehcache等知识点。 项目...
struts2和spring和Hibernate的整合包,在MyEclipse中自动导入老是有冲突包。
主要将讲解什么是MVC设计模式?Struts2核心组件解释,Struts2的工作原理,SpringMvc各个组件的解释,Springmvc工作原理
struts2、 spring4、 spring mvc、 hibernate4、 mybatis的三大框架(三套)
Struts2整合Spring3.0,Spring虽然有自己的MVC,但是由于繁琐的配置,并不理想,Struts2可以和Spring完美结合,来完成MVC的实现。
含例子 转载自疯芒毕露的专栏 刚开始用spring mvc 做web开发时 经常会不知道如何合适绑定页面数据 用惯struts2的朋友更认为spring mvc 绑定数据不如struts2方便 本人最开始也是这么认为 经过一段时间的应用和测试 ...
有关Struts2+Spring+Hibernate和Struts2+Spring+Ibatis的整合实例demo 原创,完全基于eclipse开发
Struts2+Spring3+HibernateBBS源码.rar请同时下载Struts2+Spring3+HibernateBBS源码lib1.rar ,Struts2+Spring3+HibernateBBS源码.rar lib2.rar此为jar包。
必备软件 学习struts2项目struts2+spring4+hibernate 必备
spring-webmvc-struts.jar对Struts和Spring整合时需要用到的包
struts2-spring-plugin.jar :struts,spring插件。有了这个插件,spring容器才能在全应用中适用。 在我们集成struts2+spring+hibernate,也就是所谓的S2SH,不可避免的要引入struts2-spring-plugin.jar插件。 本文...
maven构建项目,简单的struts2、spring、mybatis结构实现,页面展示用的easyui
对于Struts和Spring两种MVC框架的比较
struts2,spring4,spring mvc,hibernate4,mybatis的三大框架(三套)
Hibernate与Struts2和Spring组合开发实例
JSP SSH耗材进销存管理系统 是一套完善的WEB设计系统,对理解JSP java struts2 hibernate spring MVC编程开发语言有帮助,系统具有完整的源代码和数据库,系统主要采用B/S模式开发。 应用技术:java|jsp+mysql 开发...
struts2+Spring2.5+Spring3.2)实现登录.struts2+Spring2.5+Spring3.2)实现登录.struts2+Spring2.5+Spring3.2)实现登录。