本文主要是介绍struts2和spring mvc,孰优孰劣,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
最近我在将APDPlat升级到Java8,发现最新版本的struts2不支持Java8,同时由于之前有很多的同学希望我把APDPlat的struts2替换为spring mvc,所以我就决定试试看。本文我们看两个转换前后的例子:
1、下拉列表服务,此类比较简单,只涉及一个方法store:
使用struts2:
03 | @Namespace ( "/dictionary" ) |
04 | public class DicAction extends ExtJSSimpleAction<Dic> { |
06 | private DicService dicService; |
09 | private boolean justCode; |
13 | * 此类用来提供下拉列表服务,主要有两种下列类型: |
16 | * @return 不需要返回值,直接给客户端写数据 |
19 | public String store(){ |
20 | Dic dictionary=dicService.getDic(dic); |
22 | LOG.info( "没有找到数据词典 " +dic); |
25 | if ( "true" .equals(tree)){ |
26 | String json = dicService.toStoreJson(dictionary); |
27 | Struts2Utils.renderJson(json); |
29 | List<Map<String,String>> data= new ArrayList<>(); |
30 | for (DicItem item : dictionary.getDicItems()){ |
31 | Map<String,String> map= new HashMap<>(); |
33 | map.put( "value" , item.getCode()); |
35 | map.put( "value" , item.getId().toString()); |
37 | map.put( "text" , item.getName()); |
40 | Struts2Utils.renderJson(data); |
45 | public void setJustCode( boolean justCode) { |
46 | this .justCode = justCode; |
49 | public void setTree(String tree) { |
53 | public void setDic(String dic) { |
使用spring mvc:
03 | @RequestMapping ( "/dictionary" ) |
04 | public class DicAction extends ExtJSSimpleAction<Dic> { |
06 | private DicService dicService; |
10 | * 此类用来提供下拉列表服务,主要有两种下拉类型: |
19 | @RequestMapping ( "/dic!store.action" ) |
20 | public String store( @RequestParam (required= false ) String dic, |
21 | @RequestParam (required= false ) String tree, |
22 | @RequestParam (required= false ) String justCode){ |
23 | Dic dictionary=dicService.getDic(dic); |
25 | LOG.info( "没有找到数据词典 " +dic); |
28 | if ( "true" .equals(tree)){ |
29 | String json = dicService.toStoreJson(dictionary); |
32 | List<Map<String,String>> data= new ArrayList<>(); |
33 | dictionary.getDicItems().forEach(item -> { |
34 | Map<String,String> itemMap= new HashMap<>(); |
35 | if ( "true" .equals(justCode)){ |
36 | itemMap.put( "value" , item.getCode()); |
38 | itemMap.put( "value" , item.getId().toString()); |
40 | itemMap.put( "text" , item.getName()); |
43 | String json = JSONArray.fromObject(data).toString(); |
从上面我们可以看到,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:
03 | @Namespace ( "/dictionary" ) |
04 | public class DicItemAction extends ExtJSSimpleAction<DicItem> { |
06 | private DicService dicService; |
13 | public String store() { |
18 | if (node.trim().startsWith( "root" )){ |
19 | dic = dicService.getRootDic(); |
21 | int id=Integer.parseInt(node); |
22 | dic = dicService.getDic(id); |
26 | String json = dicService.toJson(dic); |
27 | Struts2Utils.renderJson(json); |
32 | public void setNode(String node) { |
使用spring mvc:
03 | @RequestMapping ( "/dictionary" ) |
04 | public class DicItemAction extends ExtJSSimpleAction<DicItem> { |
06 | private DicService dicService; |
14 | @RequestMapping ( "/dic-item!store.action" ) |
15 | public String store( @RequestParam (required= false ) String node) { |
20 | if (node.trim().startsWith( "root" )){ |
21 | dic = dicService.getRootDic(); |
23 | int id=Integer.parseInt(node); |
24 | dic = dicService.getDic(id); |
28 | String json = dicService.toJson(dic); |
34 | @RequestMapping ( "/dic-item!query.action" ) |
35 | public String query( @RequestParam (required= false ) Integer start, |
36 | @RequestParam (required= false ) Integer limit, |
37 | @RequestParam (required= false ) String propertyCriteria, |
38 | @RequestParam (required= false ) String orderCriteria, |
39 | @RequestParam (required= false ) String queryString, |
40 | @RequestParam (required= false ) String search){ |
41 | super .setStart(start); |
42 | super .setLimit(limit); |
43 | super .setPropertyCriteria(propertyCriteria); |
44 | super .setOrderCriteria(orderCriteria); |
45 | super .setQueryString(queryString); |
46 | super .setSearch( "true" .equals(search)); |
50 | @RequestMapping ( "/dic-item!retrieve.action" ) |
51 | public String retrieve( @ModelAttribute DicItem model) { |
53 | return super .retrieve(); |
56 | @RequestMapping ( "/dic-item!delete.action" ) |
57 | public String delete( @RequestParam String ids) { |
59 | return super .delete(); |
62 | @RequestMapping ( "/dic-item!create.action" ) |
63 | public String create( @ModelAttribute DicItem model) { |
65 | return super .create(); |
68 | @RequestMapping ( "/dic-item!updatePart.action" ) |
69 | public String updatePart( @ModelAttribute DicItem model) { |
71 | 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中将!改成/:
02 | @RequestMapping ( "query.action" ) |
03 | public String query( @RequestParam (required= false ) Integer start, |
04 | @RequestParam (required= false ) Integer limit, |
05 | @RequestParam (required= false ) String propertyCriteria, |
06 | @RequestParam (required= false ) String orderCriteria, |
07 | @RequestParam (required= false ) String queryString, |
08 | @RequestParam (required= false ) String search){ |
09 | super .setStart(start); |
10 | super .setLimit(limit); |
11 | super .setPropertyCriteria(propertyCriteria); |
12 | super .setOrderCriteria(orderCriteria); |
13 | super .setQueryString(queryString); |
14 | setSearch( "true" .equals(search)); |
19 | @RequestMapping ( "retrieve.action" ) |
20 | public String retrieve( @ModelAttribute T model) { |
26 | @RequestMapping ( "delete.action" ) |
27 | public String delete( @RequestParam String ids) { |
33 | @RequestMapping ( "create.action" ) |
34 | public String create( @ModelAttribute T model) { |
40 | @RequestMapping ( "updatePart.action" ) |
41 | public String updatePart( @ModelAttribute T model) { |
关于第二个问题,在struts2中,注入Action的参数,要使用model.id这样的方式,model是Action的一个字段,而在spring mvc中,这样是不行的,需要做一个转换,在父类中增加如下代码以使spring mvc能适应struts2参数注入方式:
2 | * 前端向后端传递模型参数的时候都有model.前缀 |
6 | public void initBinder(WebDataBinder binder) { |
7 | binder.setFieldDefaultPrefix( "model." ); |
经过上面的改进,数据字典服务 使用spring mvc的代码升级为:
03 | @RequestMapping ( "/dictionary/dic-item/" ) |
04 | public class DicItemAction extends ExtJSSimpleAction<DicItem> { |
06 | private DicService dicService; |
14 | @RequestMapping ( "store.action" ) |
15 | public String store( @RequestParam (required= false ) String node) { |
20 | if (node.trim().startsWith( "root" )){ |
21 | dic = dicService.getRootDic(); |
23 | int id=Integer.parseInt(node); |
24 | dic = dicService.getDic(id); |
28 | String json = dicService.toJson(dic); |
这篇关于struts2和spring mvc,孰优孰劣的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!