struts2和spring mvc,孰优孰劣

2024-09-04 04:32

本文主要是介绍struts2和spring mvc,孰优孰劣,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近我在将APDPlat升级到Java8,发现最新版本的struts2不支持Java8,同时由于之前有很多的同学希望我把APDPlat的struts2替换为spring mvc,所以我就决定试试看。本文我们看两个转换前后的例子:

1、下拉列表服务,此类比较简单,只涉及一个方法store:

使用struts2:

01 @Scope("prototype")
02 @Controller
03 @Namespace("/dictionary")
04 public class DicAction extends ExtJSSimpleAction<Dic> {
05     @Resource
06     private DicService dicService;
07     private String dic;
08     private String tree;
09     private boolean justCode;
10      
11     /**
12      
13      * 此类用来提供下拉列表服务,主要有两种下列类型:
14      * 1、普通下拉选项
15      * 2、树形下拉选项
16      * @return 不需要返回值,直接给客户端写数据
17      
18      */
19     public String store(){
20         Dic dictionary=dicService.getDic(dic);
21         if(dictionary==null){
22             LOG.info("没有找到数据词典 "+dic);
23             return null;
24         }
25         if("true".equals(tree)){
26             String json = dicService.toStoreJson(dictionary);
27             Struts2Utils.renderJson(json);
28         }else{
29             List<Map<String,String>> data=new ArrayList<>();
30             for(DicItem item : dictionary.getDicItems()){
31                 Map<String,String> map=new HashMap<>();
32                 if(justCode){
33                     map.put("value", item.getCode());
34                 }else{
35                     map.put("value", item.getId().toString());
36                 }
37                 map.put("text", item.getName());
38                 data.add(map);
39             }
40             Struts2Utils.renderJson(data);
41         }
42         return null;
43     }
44  
45     public void setJustCode(boolean justCode) {
46         this.justCode = justCode;
47     }
48  
49     public void setTree(String tree) {
50         this.tree = tree;
51     }
52  
53     public void setDic(String dic) {
54         this.dic = dic;
55     }
56 }

使用spring mvc:

01 @Scope("prototype")
02 @Controller
03 @RequestMapping("/dictionary")
04 public class DicAction extends ExtJSSimpleAction<Dic> {
05     @Resource
06     private DicService dicService;
07      
08     /**
09      
10      * 此类用来提供下拉列表服务,主要有两种下拉类型:
11      * 1、普通下拉选项
12      * 2、树形下拉选项
13      * @param dic
14      * @param tree
15      * @param justCode
16      * @return 返回值直接给客户端
17      */
18     @ResponseBody
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);
24         if(dictionary==null){
25             LOG.info("没有找到数据词典 "+dic);
26             return "";
27         }
28         if("true".equals(tree)){
29             String json = dicService.toStoreJson(dictionary);
30             return json;
31         }else{
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());
37                 }else{
38                     itemMap.put("value", item.getId().toString());
39                 }
40                 itemMap.put("text", item.getName());
41                 data.add(itemMap);
42             });
43             String json = JSONArray.fromObject(data).toString();
44             return json;
45         }
46     }
47 }


从上面我们可以看到,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:

01 @Scope("prototype")
02 @Controller
03 @Namespace("/dictionary")
04 public class DicItemAction extends ExtJSSimpleAction<DicItem> {
05     @Resource
06     private DicService dicService;
07     private String node;
08  
09     /**
10      * 返回数据字典目录树
11      * @return 
12      */
13     public String store() {
14         if (node == null) {
15             return null;
16         }
17         Dic dic=null;
18         if(node.trim().startsWith("root")){
19             dic = dicService.getRootDic();
20         }else{
21             int id=Integer.parseInt(node);
22             dic = dicService.getDic(id);
23         }
24          
25         if (dic != null) {
26             String json = dicService.toJson(dic);
27             Struts2Utils.renderJson(json);
28         }
29         return null;
30     }
31  
32     public void setNode(String node) {
33         this.node = node;
34     }
35 }

使用spring mvc:

01 @Scope("prototype")
02 @Controller
03 @RequestMapping("/dictionary")
04 public class DicItemAction extends ExtJSSimpleAction<DicItem> {
05     @Resource
06     private DicService dicService;
07  
08     /**
09      * 返回数据字典目录树
10      * @param node
11      * @return 
12      */
13     @ResponseBody
14     @RequestMapping("/dic-item!store.action")
15     public String store(@RequestParam(required=false) String node) {
16         if (node == null) {
17             return "[]";
18         }
19         Dic dic=null;
20         if(node.trim().startsWith("root")){
21             dic = dicService.getRootDic();
22         }else{
23             int id=Integer.parseInt(node);
24             dic = dicService.getDic(id);
25         }
26          
27         if (dic != null) {
28             String json = dicService.toJson(dic);
29             return json;
30         }
31         return "[]";
32     }
33     @ResponseBody
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));
47         return super.query();
48     }
49     @ResponseBody
50     @RequestMapping("/dic-item!retrieve.action")
51     public String retrieve(@ModelAttribute DicItem model) {
52         super.model = model;
53         return super.retrieve();
54     }
55     @ResponseBody
56     @RequestMapping("/dic-item!delete.action")
57     public String delete(@RequestParam String ids) {
58         super.setIds(ids);
59         return super.delete();
60     }
61     @ResponseBody
62     @RequestMapping("/dic-item!create.action")
63     public String create(@ModelAttribute DicItem model) {
64         super.model = model;
65         return super.create();
66     }
67     @ResponseBody
68     @RequestMapping("/dic-item!updatePart.action")
69     public String updatePart(@ModelAttribute DicItem model) {
70         super.model = model;
71         return super.updatePart();
72     }
73 }

从上面可以看到,从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中将!改成/:

01 @ResponseBody
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));
15     return query();
16 }
17  
18 @ResponseBody
19 @RequestMapping("retrieve.action")
20 public String retrieve(@ModelAttribute T model) {
21     this.model = model;
22     return retrieve();
23 }
24  
25 @ResponseBody
26 @RequestMapping("delete.action")
27 public String delete(@RequestParam String ids) {
28     super.setIds(ids);
29     return delete();
30 }
31  
32 @ResponseBody
33 @RequestMapping("create.action")
34 public String create(@ModelAttribute T model) {
35     this.model = model;
36     return create();
37 }
38  
39 @ResponseBody
40 @RequestMapping("updatePart.action")
41 public String updatePart(@ModelAttribute T model) {
42     this.model = model;
43     return updatePart();
44 }


关于第二个问题,在struts2中,注入Action的参数,要使用model.id这样的方式,model是Action的一个字段,而在spring mvc中,这样是不行的,需要做一个转换,在父类中增加如下代码以使spring mvc能适应struts2参数注入方式:

1 /**
2  * 前端向后端传递模型参数的时候都有model.前缀
3  * @param binder
4  */
5 @InitBinder
6 public void initBinder(WebDataBinder binder) {
7     binder.setFieldDefaultPrefix("model.");
8 }


经过上面的改进,数据字典服务 使用spring mvc的代码升级为:

view source
print ?
01 @Scope("prototype")
02 @Controller
03 @RequestMapping("/dictionary/dic-item/")
04 public class DicItemAction extends ExtJSSimpleAction<DicItem> {
05     @Resource
06     private DicService dicService;
07  
08     /**
09      * 返回数据字典目录树
10      * @param node
11      * @return 
12      */
13     @ResponseBody
14     @RequestMapping("store.action")
15     public String store(@RequestParam(required=false) String node) {
16         if (node == null) {
17             return "[]";
18         }
19         Dic dic=null;
20         if(node.trim().startsWith("root")){
21             dic = dicService.getRootDic();
22         }else{
23             int id=Integer.parseInt(node);
24             dic = dicService.getDic(id);
25         }
26          
27         if (dic != null) {
28             String json = dicService.toJson(dic);
29             return json;
30         }
31         return "[]";
32     }
33 }

这篇关于struts2和spring mvc,孰优孰劣的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1134999

相关文章

Java 实用工具类Spring 的 AnnotationUtils详解

《Java实用工具类Spring的AnnotationUtils详解》Spring框架提供了一个强大的注解工具类org.springframework.core.annotation.Annot... 目录前言一、AnnotationUtils 的常用方法二、常见应用场景三、与 JDK 原生注解 API 的

Java controller接口出入参时间序列化转换操作方法(两种)

《Javacontroller接口出入参时间序列化转换操作方法(两种)》:本文主要介绍Javacontroller接口出入参时间序列化转换操作方法,本文给大家列举两种简单方法,感兴趣的朋友一起看... 目录方式一、使用注解方式二、统一配置场景:在controller编写的接口,在前后端交互过程中一般都会涉及

Java中的StringBuilder之如何高效构建字符串

《Java中的StringBuilder之如何高效构建字符串》本文将深入浅出地介绍StringBuilder的使用方法、性能优势以及相关字符串处理技术,结合代码示例帮助读者更好地理解和应用,希望对大家... 目录关键点什么是 StringBuilder?为什么需要 StringBuilder?如何使用 St

使用Java将各种数据写入Excel表格的操作示例

《使用Java将各种数据写入Excel表格的操作示例》在数据处理与管理领域,Excel凭借其强大的功能和广泛的应用,成为了数据存储与展示的重要工具,在Java开发过程中,常常需要将不同类型的数据,本文... 目录前言安装免费Java库1. 写入文本、或数值到 Excel单元格2. 写入数组到 Excel表格

Java并发编程之如何优雅关闭钩子Shutdown Hook

《Java并发编程之如何优雅关闭钩子ShutdownHook》这篇文章主要为大家详细介绍了Java如何实现优雅关闭钩子ShutdownHook,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起... 目录关闭钩子简介关闭钩子应用场景数据库连接实战演示使用关闭钩子的注意事项开源框架中的关闭钩子机制1.

Maven中引入 springboot 相关依赖的方式(最新推荐)

《Maven中引入springboot相关依赖的方式(最新推荐)》:本文主要介绍Maven中引入springboot相关依赖的方式(最新推荐),本文给大家介绍的非常详细,对大家的学习或工作具有... 目录Maven中引入 springboot 相关依赖的方式1. 不使用版本管理(不推荐)2、使用版本管理(推

Java 中的 @SneakyThrows 注解使用方法(简化异常处理的利与弊)

《Java中的@SneakyThrows注解使用方法(简化异常处理的利与弊)》为了简化异常处理,Lombok提供了一个强大的注解@SneakyThrows,本文将详细介绍@SneakyThro... 目录1. @SneakyThrows 简介 1.1 什么是 Lombok?2. @SneakyThrows

在 Spring Boot 中实现异常处理最佳实践

《在SpringBoot中实现异常处理最佳实践》本文介绍如何在SpringBoot中实现异常处理,涵盖核心概念、实现方法、与先前查询的集成、性能分析、常见问题和最佳实践,感兴趣的朋友一起看看吧... 目录一、Spring Boot 异常处理的背景与核心概念1.1 为什么需要异常处理?1.2 Spring B

如何在 Spring Boot 中实现 FreeMarker 模板

《如何在SpringBoot中实现FreeMarker模板》FreeMarker是一种功能强大、轻量级的模板引擎,用于在Java应用中生成动态文本输出(如HTML、XML、邮件内容等),本文... 目录什么是 FreeMarker 模板?在 Spring Boot 中实现 FreeMarker 模板1. 环

SpringMVC 通过ajax 前后端数据交互的实现方法

《SpringMVC通过ajax前后端数据交互的实现方法》:本文主要介绍SpringMVC通过ajax前后端数据交互的实现方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价... 在前端的开发过程中,经常在html页面通过AJAX进行前后端数据的交互,SpringMVC的controll