Spring学习笔记(3)一SpringMVC快速入门和基本流程

学习技术方面由浅入深的层次步骤:

了解:入门,如何去使用这门技术
掌握:具体,它的原理是什么
熟悉:规则实践,在理解原理的基础上,如何去模仿,
精通:解决问题
专家:觉悟,扩展创新,如何去进一步演化

 

一、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插件来创建。

项目整体结构:

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依赖

<?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处理。


<?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文件中就无需配置路径信息了。

<?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对象。

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是在src\main\webapp。如果在此目录下找不到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:

<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的控制器

<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的控制器

<!--第二种: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后缀

<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接口

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)、src\main\webapp\WEB-INF\demo.jsp页面:

<%@ 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. 

<!-- 配置核心控制器 -->
<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 请求参数到控制器方法参数

@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 方法参数

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 方法参数

@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框架太厉害了。

 

"随着年龄的增长,人总会变得越来越宽容,很多事情到最后并不是真的解决了,而是【算了吧】。"

你要去做一个大人,不要回头,不要难过

  • 6
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hguisu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值