学习技术方面由浅入深的层次步骤:
了解:入门,如何去使用这门技术 掌握:具体,它的原理是什么 熟悉:规则实践,在理解原理的基础上,如何去模仿, 精通:解决问题 专家:觉悟,扩展创新,如何去进一步演化
一、SpringMVC 框架
spring是一个轻型容器(light-weight Container),其核心是Bean工厂(Bean Factory),用以构造我们所需要的M(Model)。在此基础之上,Spring提供了AOP(Aspect-Oriented Programming, 面向层面的编程)的实现,用它来提供非管理环境下申明方式的事务、安全等服务;对Bean工厂的扩展ApplicationContext更加方便我们实现J2EE的应用;DAO/ORM的实现方便我们进行数据库的开发;Web MVC和Spring Web提供了Java Web应用的框架或与其他流行的Web框架进行集成。
1)开源框架 2)IoC(控制反转),将类的创建和依赖关系写在配置文件里,由配置文件注入,实现了松耦合 3)AOP 将安全,事务等于程序逻辑相对独立的功能抽取出来,利用spring的配置文件将这些功能插进去,实现了按照方面编程,提高了复用性
springmvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。 springmvc是一个基于mvc的web框架。
Spring MVC框架根据不同的角色定义了很多接口,但是它最大的问题也是依赖于Servlet API
Spring MVC Framework有这样一些特点: 1、它是基于组件技术的.全部的应用对象,无论控制器和视图,还是业务对象之类的都是java组件.并且和Spring提供的其他基础结构紧密集成. 2、不依赖于Servlet API(目标虽是如此,但是在实现的时候确实是依赖于Servlet的) 3、可以任意使用各种视图技术,而不仅仅局限于JSP 4、支持各种请求资源的映射策略 5、它应是易于扩展的
SpringMVC属于Spring Framework的后续产品,已经融合到Spring Web Flow中。SpringMVC基于Model2而实现,利用处理器分离了模型对象、视图、控制,达到了松散耦合的效果,提高了系统的可重用性、可维护性以及可扩展性。其功能与Struts类似,只是实现原理和方式上有所不同。
优点:
- 使用简单,学习成本低
- 功能强大,很容易写出性能优秀的程序
- 十分灵活,并且可与Spring无缝衔接
二、SpringMVC入门1:Controller使用注解
使用maven创建SpringMCV工程就很简单,可以使用IDE插件来创建。
项目整体结构:
代码语言:javascript复制srpingmvc-test
- pom.xml
- src/main
- java
|
- resources
| |
| -applicationContext.xml//做一些初始化配置
| |
| -mapper
| | - UserMapper.xml
- webapp
|
-WEB-INF
| - web.xml //主要配置是前端控制器
| - apiserer-serlet.xml //springmvc配置
-index.jsp
1、.SpringMvc POM依赖:
在项目的pom.xml导入Spring MVC的Maven依赖
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd ">
<modelVersion>4.0.0</modelVersion>
<groupId>demo.springmvc.test</groupId>
<artifactId>demo-springmvc-test</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>demo-springmvc-test</name>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.4.RELEASE</version>
</dependency>
</dependencies>
</project>
3 配置web.xml
在web.xml中主要配置的是前端控制器,前端控制器的作用是:通过用户的url请求路径查找到匹配该请求的handler,在将用户的请求交由相应的handler处理。
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- 加载Spring配置文件: start -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<!-- 加载Spring配置文件: end -->
<!-- 配置核心控制器 -->
<servlet>
<servlet-name>apiserver</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:apiserver-servlet.xml</param-value>
</init-param>
-->
<!--
DispatcherServlet对象创建时间问题
1)默认情况下,第一次访问该Servlet的创建对象,意味着在这个时间才去加载apiserver-servlet.xml
2)可以改变为在项目启动时候就创建该Servlet,提高用户访问体验。
<load-on-startup>1</load-on-startup>
数值越大,对象创建优先级越低! (数值越低,越先创建)
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>apiserver</servlet-name>
<url-pattern>/apiserver/*</url-pattern>
</servlet-mapping>
</web-app>
根据<servlet-name>servlet.xml的配置,查找HandlerMapping
init-param面对应的参数名和值,是给servlet在初始化执行init()方法的时候(servlet有doGet doPost 在这之前还有init()方法 )。 可以dao在init()方法里调用这个参数的值,如:System.out.println(this.getInitParameter("param1")); 就会输出这个servlet里 打印init-name 名为"param1"的值。
配置说明
- DispathcerServlet是Spring MVC提供的核心控制器,这是一个Servlet程序,该Servlet会接收所有请求。
- 核心控制器会读取一个springmvc.xml配置,加载Spring MVC的核心配置。
- <url-pattern>配置/apiserver/*,代表只拦截/apiserver/*的请求,可以进行更改。
- <load-on-startup>代表在项目启动时实例化DispathcerServlet,如果没有配置,则在第一次访问Servlet时进行实例化。
4、apiserver-serlet.xml的配置
即在默认路径下,springmvc的配置文件的名字格式是 <servlet-name>-servlet.xml. 因为是在默认路径下,所以web.xml文件中就无需配置路径信息了。
代码语言:javascript复制<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd">
<!-- 配置自定扫描的包 -->
<context:component-scan base-package="com.demo" />
<!-- 配置视图解析器: 如何把 handler 方法返回值解析为实际的物理视图 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
5. 控制代码
在SpringMVC 中提供了一个非常简便的定义Controller 的方法,你无需继承特定的类或实现特定的接口,只需使用@Controller 标记一个类是Controller ,然后使用@RequestMapping 和@RequestParam 等一些注解用以定义URL 请求和Controller 方法之间的映射,这样的Controller 就能被外界访问到。
@Controller 是标记在类UserController上面的,所以类UserController就是一个SpringMVC Controller 对象了。@RequestMapping(“/user”) 标记在UserController类上,表示当请求*/user/* 的时候访问的是UserController的相关方法。 @RequestMapping(“/abc”) 标记在UserController类方法test上,该方法返回了一个String对象。
代码语言:javascript复制package com.demo.springmvc.controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/user")
public class UserController {
@RequestMapping("/")
@ResponseBody
public String index() {
return "Hello world";
}
@RequestMapping("/abc")
@ResponseBody
public String test() {
System.out.println("------------TestController-----------");
return "Hello test";
}
}
6. 打包访问传到tomcat运行:
maven:mvn clean package
Maven打包web项目报错Error assembling WAR: webxml attribute is required (or pre-existing WEB-INF/web.xml if 原因分析:maven的web项目默认的webroot是在srcmainwebapp。如果在此目录下找不到web.xml就抛出以上的异常。 解决办法:1、将webroot修改为webapp 2、在pom.xml中指定web.xml,如下: <build> <plugins> <plugin> <artifactId>maven-war-plugin</artifactId> <!--<configuration>--> <!--<webXml>${basedir}/src/main/webapp/WEB-INF/web.xml</webXml>--> <!--</configuration>--> </plugin> </plugins> </build>
把项目部署到Tomcat,war包名为:demo-springmvc-test.war ,然后启动或者重启Tomcat运行项目:
三、SpringMVC入门2:实现Controller接口
通过实现org.springframework.web.servlet.mvc.Controller接口,这种配置比较繁杂,而且一个url只能对应一个controller。
其实类似直接使用HttpServlet接口。
1、在web.xml里面配置DispatcherServlet:
代码语言:javascript复制<servlet>
<servlet-name>apiserver2</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>apiserver2</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2、配置处理器映射
apiserver2-servlet.xml的文件是用来配置处理器映射、控制器的定义、视图解析器等。URL处理映射的方式有三种
1) BeanNameUrlHandlerMapping:通过url名字,找到对应的bean的name的控制器
代码语言:javascript复制<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
<bean name="/demo1.do" class="com.demo.springmvc.controller.DemoController"></bean>
2). SimpleUrlHandlerMapping 【简单得URL处理映射】 通过key找到bean的id的控制器
代码语言:javascript复制<!--第二种:SimpleUrlHandlerMapping 【简单得URL处理映射】 通过key找到bean的id的控制器 -->
<bean name="demoController" class="com.demo.springmvc.controller.DemoController"></bean>
<bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/demo2.do">demoController</prop>
<prop key="/demo3.do">demoController</prop>
</props>
</property>
</bean>
3). ControllerClassNameHandlerMapping 【控制器的类名处理映射】 不用配置访问路径,默认的访问路径就是类名首字母大写变小写,加.do后缀
代码语言:javascript复制<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!--1.控制器的类名处理映射-->
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/>
<!--2.配置控制器处理适配器-->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!--3.配置控制器 相当于配置了一个访问路径 1.name="/demo.do" 2.id="DemoController" -->
<bean class="com.demo.springmvc.controller.DemoController"></bean>
3、代码实现Controller接口
代码语言:javascript复制package com.demo.springmvc.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class DemoController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest arg0, HttpServletResponse response) throws Exception {
ModelAndView mav = new ModelAndView("demo");
response.setCharacterEncoding("utf-8");
response.setContentType("text/html");
mav.addObject("message", "spring MVC");
return mav;
}
}
4)、srcmainwebappWEB-INFdemo.jsp页面:
代码语言:javascript复制<%@ page contentType="text/html; charset=UTF-8"%>
<body>
message:${message}
</body>
5)、打包部署测试
三种URL处理映射的方式分别打三个包:demo1.war, demo2.war, demo3.war, 部署到tomcat访问:
jsp页面中文乱码:
在jsp页面指定第一行指定JSP页面编码采用UTF-8 <%@ page language="java" pageEncoding="UTF-8"%> <body> 这是一个demo示例::${message} </body> 刷新后:
四、SpringMVC框架基本流程
SpringMVC框架主要由四个接口组成: 1)、DispatcherServlet前端控制器、 2)、HandlerMapping请求处理器映射器、 3)、Controller、 4)、ViewResolver
1、工作流程
1)、启动流程:
当web程序启动的时候,ContextLoaderServlet会把对应的配置文件信息读取出来,通过注射去初始化控制器DispatchServlet.
代码语言:javascript复制<!-- 配置核心控制器 -->
<servlet>
<servlet-name>apiserver</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--<init-param>-->
<!--<param-name>contextConfigLocation</param-name>-->
<!--<param-value>classpath:applicationContext.xml</param-value>-->
<!--</init-param>-->
<load-on-startup>1</load-on-startup>
</servlet>
2、处理请求流程(我们使用接口的流程来说明)
1)、请求提交给DispatcherServlet: 将客户端请求http://localhost:8080/demo1/demo1.do,首先被在web.xml中配置的前端控制器DispatcherServlet拦截到。
2)、根据<servlet-name>servlet.xml的配置,查找HandlerMapping: 在apiserver2-servlet.xml中查找能执行demo1.do请求的映射处理器,若发现没有能处理此请求的映射处理器,这时便使用默认的映射处理器BeanNameUrlHandlerMapping。我们还需注意:这种后端控制器的bean Name必须以“/”开头,并且要结合DispatcherServlet的映射配置。同时beanName支持通配符配置。比如如果配置:<bean name="/d*.do" class="com.demo.springmvc.controller.DemoController" /> 时,当访问demo.do时也可以成功访问到DemoController类。
3)、HandlerMapping根据请求URL找到处理请求的具体Controller(Handler) BeanNameUrlHandlerMapping处理器,会查找在spring容器中是否在名为“demo1.do”的bean实例。当查找到此实例后,则把此bean作为处理此请求的后端控制器。同时把自身加到映射处理器链上,并向处理器链传递此请求。
4)、后端控制器进行处理: DispatcherServletd调用处理器适配器去执行Controller,Controller调用业务逻辑处理(DispatchServlet会在调用选定的Controller的handlerRequest方法)
5)、处理完成之后,返回ModelAndView对象给DispatcherServlet 框架通过ViewResolver找到负责显示的具体View 由View的render方法将结果渲染到客户端
五、常用注解
- @Controller:声明Action组件,负责注册bean到Spring上下文
- @RequestMapping:用于为控制器指定可以处理的url请求
- @RequestParam:用于指定参数的name属性
- @RequestBody:用于读取Request请求的body部分数据
- @ResponseBody:用于将控制器方法返回的对象写入到Response对象的body数据区
- @PathVariable:用于指定url作为参数
- @Resource用于注入,( 由j2ee提供 ) 默认按名称装配
- @Autowired用于注入,(由spring提供) 默认按类型装配
- @ExceptionHandler:用于异常处理的方法
- @ControllerAdvice:用于使控制器成为全局的异常处理类
- @ModelAttribute:用于优先调用被注解的方法,或注解参数中的隐藏对象
1、@RequestMapping注解
使用@RequestMapping注解来映射Request 请求与处理器:
可以使用@RequestMapping 来映射URL到控制器类,或者是到Controller 控制器的处理方法上。当@RequestMapping 标记在Controller 类上的时候,里面使用@RequestMapping 标记的方法的请求地址都是相对于类上的@RequestMapping 而言的;当Controller 类上没有标记@RequestMapping 注解时,方法上的@RequestMapping 都是绝对路径。这种绝对路径和相对路径所组合成的最终路径都是相对于根路径“/ ”而言的。
2、使用 @RequestParam 绑定 HttpServletRequest 请求参数到控制器方法参数
代码语言:javascript复制@RequestMapping ( "requestParam" )
public String testRequestParam( @RequestParam(required=false) String name, @RequestParam ( "age" ) int age) {
return "requestParam" ;
}
在上面代码中利用@RequestParam 从HttpServletRequest 中绑定了参数name 到控制器方法参数name ,绑定了参数age 到控制器方法参数age 。值得注意的是和@PathVariable 一样,当你没有明确指定从request 中取哪个参数时,Spring 在代码是debug 编译的情况下会默认取更方法参数同名的参数,如果不是debug 编译的就会报错。此外,当需要从request 中绑定的参数和方法的参数名不相同的时候,也需要在@RequestParam 中明确指出是要绑定哪个参数。在上面的代码中如果我访问/requestParam.do?name=hello&age=1 则Spring 将会把request请求参数name 的值hello 赋给对应的处理方法参数name ,把参数age 的值1 赋给对应的处理方法参数age 。
在@RequestParam 中除了指定绑定哪个参数的属性value 之外,还有一个属性required ,它表示所指定的参数是否必须在request 属性中存在,默认是true ,表示必须存在,当不存在时就会报错。在上面代码中我们指定了参数name 的required 的属性为false ,而没有指定age 的required 属性,这时候如果我们访问/requestParam.do而没有传递参数的时候,系统就会抛出异常,因为age 参数是必须存在的,而我们没有指定。而如果我们访问/requestParam.do?age=1 的时候就可以正常访问,因为我们传递了必须的参数age ,而参数name 是非必须的,不传递也可以。
3、使用 @CookieValue 绑定 cookie 的值到 Controller 方法参数
代码语言:javascript复制public String testCookieValue( @CookieValue ( "hello" ) String cookieValue, @CookieValue String hello) {
System. out .println(cookieValue "-----------" hello);
return "cookieValue" ;
}
在上面的代码中我们使用@CookieValue 绑定了cookie 的值到方法参数上。上面一共绑定了两个参数,一个是明确指定要绑定的是名称为hello 的cookie 的值,一个是没有指定。使用没有指定的形式的规则和@PathVariable、@RequestParam 的规则是一样的,即在debug 编译模式下将自动获取跟方法参数名同名的cookie 值。
4、使用 @RequestHeader 注解绑定 HttpServletRequest 头信息到Controller 方法参数
代码语言:javascript复制@RequestMapping ( "testRequestHeader" )
public String testRequestHeader( @RequestHeader ( "Host" ) String hostAddr, @RequestHeader String Host, @RequestHeader String host ) {
System. out .println(hostAddr "-----" Host "-----" host );
return "requestHeader" ;
}
在上面的代码中我们使用了 @RequestHeader 绑定了 HttpServletRequest 请求头 host 到Controller 的方法参数。上面方法的三个参数都将会赋予同一个值,由此我们可以知道在绑定请求头参数到方法参数的时候规则和 @PathVariable 、 @RequestParam 以及 @CookieValue 是一样的,即没有指定绑定哪个参数到方法参数的时候,在 debug 编译模式下将使用方法参数名作为需要绑定的参数。但是有一点 @RequestHeader 跟另外三种绑定方式是不一样的,那就是在使用 @RequestHeader 的时候是大小写不敏感的,即 @RequestHeader(“Host”) 和 @RequestHeader(“host”) 绑定的都是Host 头信息。记住在 @PathVariable 、 @RequestParam 和 @CookieValue 中都是大小写敏感的。
5、@RequestMapping 的一些高级应用
在RequestMapping 中除了指定请求路径 value 属性外,还有其他的属性可以指定,如params 、method 和headers 。这样属性都可以用于缩小请求的映射范围。
method 属性主要是用于限制能够访问的方法类型的 @RequestMapping (value= "testMethod" , method={RequestMethod. GET , RequestMethod. DELETE })
params 属性用于指定请求参数的 @RequestMapping (value= "testParams" , params={ "param1=value1" , "param2" , "!param3" })
使用headers 属性可以通过请求头信息来缩小@RequestMapping 的映射范围。 @RequestMapping (value= "testHeaders" , headers={ "host=localhost" , "Accept" })
六、Struts2和SpringMVC的区别
一)、框架机制
1、Struts2采用Filter(StrutsPrepareAndExecuteFilter)实现,SpringMVC(DispatcherServlet)则采用Servlet实现。 2、Filter在容器启动之后即初始化;服务停止以后坠毁,晚于Servlet。Servlet在是在调用时初始化,先于Filter调用,服务停止后销毁。
二)、拦截机制
1、Struts2 a、Struts2框架是类级别的拦截,每次请求就会创建一个Action,和Spring整合时Struts2的ActionBean注入作用域是原型模式prototype(否则会出现线程并发问题),然后通过setter,getter吧request数据注入到属性。 b、Struts2中,一个Action对应一个request,response上下文,在接收参数时,可以通过属性接收,这说明属性参数是让多个方法共享的。 c、Struts2中Action的一个方法可以对应一个url,而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了 2、SpringMVC a、SpringMVC是方法级别的拦截,一个方法对应一个Request上下文,所以方法直接基本上是独立的,独享request,response数据。而每个方法同时又何一个url对应,参数的传递是直接注入到方法中的,是方法所独有的。处理结果通过ModeMap返回给框架。 b、在Spring整合时,SpringMVC的Controller Bean默认单例模式Singleton,所以默认对所有的请求,只会创建一个Controller,有应为没有共享的属性,所以是线程安全的,如果要改变默认的作用域,需要添加@Scope注解修改。
三)、性能方面
SpringMVC实现了零配置,由于SpringMVC基于方法的拦截,有加载一次单例模式bean注入。而Struts2是类级别的拦截,每次请求对应实例一个新的Action,需要加载所有的属性值注入,所以,SpringMVC开发效率和性能高于Struts2。
四)、拦截机制
Struts2有自己的拦截Interceptor机制,SpringMVC这是用的是独立的Aop方式,这样导致Struts2的配置文件量还是比SpringMVC大。
五)、配置方面
spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。 SpringMVC可以认为已经100%零配置。
六)、设计思想
Struts2更加符合OOP的编程思想, SpringMVC就比较谨慎,在servlet上扩展。
七)、集成方面
SpringMVC集成了Ajax,使用非常方便,只需一个注解@ResponseBody就可以实现,然后直接返回响应文本即可,而Struts2拦截器集成了Ajax,在Action中处理时一般必须安装插件或者自己写代码集成进去,使用起来也相对不方便。
==============================================
Struts2是一个基于MVC设计模式的Web应用框架,它本质上相当于一个Servlet。在MVC设计模式中,Struts2作为控制器(Controller)来建立模型与视图的数据交互。Struts2是Struts的下一代产品,是在Struts1和WebWork的技术基础上进行了合并的全新的Struts2框架。其全新的Struts2的体系结构与Struts1的体系结构差别巨大。Struts2以WebWork为核心,采用拦截器的机制来处理用户的请求,这样的设计也使得业务逻辑控制器能够与ServletAPI完全脱离开,所以Struts2可以理解为WebWork的更新产品。虽然从Struts1到Struts2有着太大的变化,但是相对于WebWork,Struts2的变化很小。
Struts2在其流行的几年可谓是非常热门,不管你去哪个公司面试,都要求会SSH(Spring Struts2 Hibernate),这里的SS指的是Spring和Struts2。但是现在,曾经风靡一时的Struts2最终被SpringMVC所取代,为什么会是这样的结果呢?如果你做了五年以上的开发了,那肯定是接触过Struts2,你一定会知道Struts2的配置文件可谓是最头疼的,如果项目大了,那Servlet和配置会让人疯掉。另外,Struts还有一个通病就是他的请求是基于类的,而SpringMVC是基于方法的,请求域的范围不一样,相比之下SpringMVC要灵活得多。
随着Spring快速的发展,使用SpringMVC的人也会随之增多。从另外一个角度来看,SpringBoot大家都很熟悉吧,零XML配置,全部采用JavaBean的形式,为什么SpringBoot能够快速的代替SpringMVC的xml配置呢,就是因为他减去了xml的配置,使维护起来更加方便。Struts2相比之下则显得十分臃肿,配置项太多。
如果说SpringMVC是初步淘汰了Struts2,那么SpringBoot的崛起基本上是彻底淘汰了Struts2,除了一些老项目还在维护之外,其他的新项目基本上都在用SpringBoot,谁也不想去用一个维护复杂,配置众多的项目。
这里列出几点:
1.Struts2的安全漏洞不胜枚举,曾经传言京东数据泄漏就是Struts2搞的鬼。
2.Struts2就是一个Web控制器框架,个人感觉最不好的一点就是,对post、get参数并没有区分对待,天然不支持RESTful API,导致xss攻击的更难防御。
3.Struts2对每一个Web请求,都会创建一个Action实例,耗时耗资源。
4.对于高并发业务,传统Web容器tomcat通常是顶不住的,很多团队会自己开发异步、并行、高性能网络通信引擎,这时候Struts2通常就会比较鸡肋了,一般会根据自身业务特点自行开发控制器框架。
5.Spring MVC和Spring是无缝的。从这个项目的管理和安全上也比Struts2高(当然Struts2也可以通过不同的目录结构和相关配置做到SpringMVC一样的效果,但是需要xml配置的地方不少)。
6.由于Struts2需要针对每个request进行封装,把request,session等servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全,所以在原则上,是比较耗费内存的。
7.SpringMVC开发效率和性能高于Struts2。
......
最后总结来说,业务适合的框架才是好框架啦,Struts2被淘汰还是因为SpringMVC框架太厉害了。
"随着年龄的增长,人总会变得越来越宽容,很多事情到最后并不是真的解决了,而是【算了吧】。"
你要去做一个大人,不要回头,不要难过