Spring09

SpringMVC是一种基于Java的WebMVC框架,用于简化Web层开发,实现职责解耦。它采用前端控制器DispatcherServlet,支持策略模式,提供国际化、视图解析、数据绑定等功能。文章讨论了SpringMVC的优点,如简单易用、高性能、灵活性,以及常规的开发步骤,包括配置web.xml、编写控制器和视图等,并分析了其执行流程和核心组件。
摘要由CSDN通过智能技术生成

SpringMVC

MVC模型是一种架构型的模式,只是帮助将开发的结构组织的更加合理,使展示与模型分离、流程控制逻辑、业务逻辑调用与展示逻辑分离

以Controller为核心完成对系统流程的控制管理
从请求中收集数据
对传入参数进行验证
根据请求调用相应业务逻辑完成数据处理
将处理结果返回给视图

国际化支持
针对不同视图技术提供不同的解析方案
针对jsp视图技术提供标签库
通过拦截器链实现面向方面编程完成系统级控制
对文件的上传、下载等常用功能的封装

优点:
1、可以为一个模型在运行时同时建立和使用多个视图
2、视图与控制器的可接插性,允许更换视图和控制器对象,而且可以根据需求动态的打开或关闭、甚至在运行期间进行对象替换
3、模型的可移植性。
4、潜在的框架结构

缺点:
1、增加了系统结构和实现的复杂性。
2、视图与控制器间的过于紧密的连接
3、视图对模型数据的低效率访问
4、目前,一般高级的界面工具或构造器不支持模式。改造这些工具以适应MVC需要和建立分离的部件的代价是很高的,从而造成MVC使用的困难

概念SpringMVC

Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型框架的目的就是简化开发,Spring Web MVC也是要简化日常Web开发的

如何选择MVC框架
常见的MVC框架struts2【webwork】、jsf、SpringMVC等
1、简单易用,以提高开发效率。使小部分的精力在框架上,大部分的精力放在业务上。
2、性能优秀,这是一个最能吸引眼球的话题。
3、尽量使用大众的框架(避免使用小众的、私有的框架),新招聘来的开发人员有一些这方面技术积累,减低人员流动再适应的影响
由于Spring框架的普及,目前使用最多的MVC框架就是SpringMVC

设计模式

1、前端控制器模式DispatcherServlet
2、策略模式

SpringMVC提供的支持

1、进行更简洁的Web层的开发
2、能简单的进行Web层的单元测试 Mock测试
3、天生与Spring框架集成(如IoC容器、AOP等)
4、提供强大的约定大于配置的契约式编程支持;支持灵活的URL到页面控制器的映射
5、容易与其他视图技术集成,如Velocity、FreeMarker等,因为模型数据放在一个Model里(Map数据结构实现,因此很容易被其他框架使用)
6、非常灵活的数据验证、格式化
7、数据绑定机制
8、提供一套强大的JSP标签库,简化JSP开发;事实上目前开发中已经不再推荐使用jsp视图技术
9、支持灵活的本地化、主题等解析
10、更加简单的异常处理
11、对静态资源的支持;
12、支持RESTful风格

优点:
1、Spring3 MVC使用简单,学习成本低。学习难度小于Struts2,Struts2用不上的多余功能太多
2、Spring3 MVC很容易就可以写出性能优秀的程序,Struts2要处处小心才可以写出性能优秀的程序
3、Spring3 MVC的灵活是无法想像的,Spring框架的扩展性有口皆碑,Spring3 MVC当然也不会落后,不会因使用了MVC框架而感到有任何的限制

SpringMVC应用一般开发步骤
修改pom.xml
将项目的打包方式设置为war包
添加依赖:spring-webmvc
由于目前使用的是jsp视图技术【已经不建议使用】,所以需要添加Servlet开发所需要的依赖
创建目录 src/main/webapp
在webapp下创建文件夹WEB-INF
在WEB-INF下创建web应用的核心配置文件 web.xml

1、配置web.xml,指定业务层对应的Spring配置文件,定义DispatcherServlet
SpringMVC采用了前端控制器模式,所有的用户请求都统一交给DispatcherServlet处理。依赖于DispatcherServlet
将SpringMVC框架添加到web应用

yan org.springframework.web.servlet.DispatcherServlet 1 yan *.do

2、添加Spring针对web应用的配置文件 yan-servlet.xml

3、编写处理请求的控制器。处理器

@Controller  //用于声明当前类是请求控制器
@RequestMapping("/hello.do") //将控制器和请求的URL建立对应关系,表示如果用户请求hello.do则由当前类负责进行处理
public class HelloController {
    public ModelAndView hello(){
        String res="hello SpringMVC!";  //需要在页面中显示的模型数据
        ModelAndView mv=new ModelAndView();
        mv.addObject("msg",res);//类似于request.setAttribute("名称",数据)
        mv.setViewName("show"); //设置需要跳转的视图逻辑名称
        return mv;
    }
}

4、编写视图对象 jsp视图
${msg}

5、配置Spring mvc的配置文件,使控制器,视图解析器等生效

<?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:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    <!-- 将控制器设置为受管bean -->
    <context:component-scan base-package="com.yan.action">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>
    <!-- 过去web应用相关的配置还有  handleMapping完成请求地址和控制器类的映射, handlerAdapter完成接口适配,查找并调用对应的方法。引入mvc名空间简化配置,
      添加注解驱动支持,用于识别在类和方法上添加的相关注解 -->
    <mvc:annotation-driven/>
    <!-- 添加视图解析器,完成视图逻辑名称到物理地址之间的转换.控制器中设置的是跳转视图的逻辑名称,通过这个组件将逻辑视图名转换为物理地址
        配置属性prefix就是在逻辑视图名称前添加的内容,suffix就是在逻辑视图名称后添加的内容。例如逻辑视图名称为字符串show,则添加前后缀后就是物理地址/WEB-INF/content/show.jsp
        配置属性viewClass用于指定对应的视图类型,因为SpringMVC默认提供了4种视图技术支持,并允许用户扩展
    -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/content/"
          p:suffix=".jsp" p:viewClass="org.springframework.web.servlet.view.JstlView"/>
</beans>

执行流程中的要点分析:
组件1:DispatcherServlet
DispatcherServlet是一个Servlet,采用的是前端控制器模式,充当统一访问点,进行全局的流程控制
DispatcherServlet是前置控制器,配置在web.xml文件中的。拦截匹配的请求,Servlet拦截匹配规则要自已定义,把拦截下来的请求,依据某某规则分发到目标Controller(自定义Action)来处理 <url-pattern>*.do</url-pattern>请求给SpringMVC框架处理,需配置Spring的配置文件,默认DispatcherServlet会加载WEB-INF/ [DispatcherServlet的Servlet名字] -servlet.xml配置文件

如果需要修改配置文件的名称,则需要给DispatcherServlet配置对应的参数contextConfigLocation

 <servlet>
        <!--定义Spring用于web的配置文件名称为  yan-servlet.xml  [惯例优于配置] -->
        <servlet-name>yan</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/beans.xml</param-value>
        </init-param>
        <!-- 应用启动则自动加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>

dispatcherServlet:
DispatcherServlet前端控制器设计模式的实现,提供SpringMVC的集中访问点,而且负责职责的分派,而且与IoC容器无缝集成,从而可以获得Spring的所有好处

DispatcherServlet主要用作职责调度工作,本身主要用于控制流程,主要职责:
1、文件上传解析,如果请求类型是multipart将通过MultipartResolver进行文件上传解析
2、通过HandlerMapping将请求映射到处理器(返回一个HandlerExecutionChain包括一个处理器、多个HandlerInterceptor拦截器)
3、通过HandlerAdapter支持多种类型的处理器(HandlerExecutionChain中的处理器),适配器模式
4、通过ViewResolver解析逻辑视图名到具体视图实现
5、本地化解析、渲染具体的视图等
6、如果执行过程中遇到异常将交给HandlerExceptionResolver来解析

1、客户端访问地址hello.do
2、因为后缀为.do所以DispatcherServlet生效

<servlet>
        <!--定义Spring用于web的配置文件名称为  yan-servlet.xml  [惯例优于配置] -->
        <servlet-name>yan</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <!-- 应用启动则自动加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>yan</servlet-name>
        <!-- 古老的映射方式 -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

3、执行数据校验、参数绑定等操作,然后调用SpringMVC提供的HandlerMapping和HandlerAdapter查找对应的Controller中的对应方法

 <mvc:annotation-driven/>

4、Controller/Handler组件负责处理对应的请求,并生成对应的逻辑视图名ModelAndView
5、DispatcherServlet调用SpringMVC提供的组件ViewResolver将Controller返回的view视图名称转换为物理视图,同时执行对应的视图获取返回结果

<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/content/"
          p:suffix=".jsp" p:viewClass="org.springframework.web.servlet.view.JstlView"/>

6、返回对应的View执行结果给浏览器,再由浏览器进行渲染显示

父子容器的概念

父容器就是由ContextLoaderListener负责加载的IoC容器,包含所有非web应用相关的受管bean

  <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath*:applicationContext.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>

子容器就是由DispatcherServlet复杂创建和加载的IoC容器,其中包含所有web应用相关的受管bean

 <servlet>
        <!--定义Spring用于web的配置文件名称为  yan-servlet.xml  [惯例优于配置] -->
        <servlet-name>yan</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/beans.xml</param-value>
        </init-param>
        <!-- 应用启动则自动加载 -->
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>yan</servlet-name>
        <!-- 古老的映射方式 -->
        <url-pattern>*.do</url-pattern>
    </servlet-mapping>

SpringMVC框架要求:父容器不能访问子容器中的受管bean,但是子容器可以访问父容器中的受管bean

SpringMVC粗略的工作流程【工作原理】
1、首先用户发送请求到前端控制器,前端控制器根据请求信息(如URL)来决定选择哪一个页面控制器进行处理并把请求委托给它,即以前的控制器的控制逻辑部分
2、页面控制器接收到请求后,进行功能处理,首先需要收集和绑定请求参数到一个对象,这个对象在Spring Web MVC中叫命
令对象,并进行验证,然后将命令对象委托给业务对象进行处理;处理完毕后返回一个ModelAndView(模型数据和逻辑视图名)
handlerMapping----AnnotationHandlerMapping
handlerAdapater-----AnnotationHandlerAdapter
3、前端控制器收回控制权,然后根据返回的逻辑视图名,选择相应的视图进行渲染,并把模型数据传入以便视图渲染
InternalResourceViewResolver—ModelAndView
4、前端控制器再次收回控制权,将响应返回给用户,至此整个结束

SpringMVC注解开发中的核心组件
1、DispatcherServlet前端控制器负责表现层提供统一访问点,从而避免Model中出现重复的控制逻辑,并且可为多个请求提供共用的逻辑,将选择具体视图和具体的功能处理分离
2、DefaultAnnotationHandlerMapping通过注解,把一个URL映射到Controller类上
3、AnnotationMethodHandlerAdapter类通过注解,把一个URL映射到Controller类的方法上
4、Controller接口是页面控制器/动作处理器,功能处理代码,收集参数,封装参数到模型,转调业务对象处理模型,返回逻辑视图名交给前端控制器和具体的视图技术解耦。由前端控制器委托给应用控制器选择具体的视图展示,是命令设计模式的实现

具体的开发
1、使用XML配置(不推荐使用)

 <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"/>
    <bean name="/hello" class="com.yan.HelloController"/>

BeanNameUrlHandlerMapping表示将请求的URL和Bean名字映射,如URL为 “hello”,则Spring配置文件必须有一个名字为“/hello”的Bean,上下文默认忽略。

SimpleControllerHandlerAdapter表示所有实现Controller接口的Bean可以作为Spring Web MVC中的处理器。如果需要其他类型的处理器可以通过实现HadlerAdapter来解决

2、使用Annotation配置

控制返回的是ModelAndView对象,则需要依赖viewResovler组件转换并执行对应的视图
InternalResourceViewResolver用于支持Servlet、JSP视图解析
viewClass值为JstlView,表示JSP模板页面需要使用JSTL标签库,classpath中必须包含jstl的相关jar包
prefix和suffix:查找视图页面的前缀和后缀(前缀[逻辑视图名]后缀),如传进来的逻辑视图名为hello,则该该jsp视图页面应该存放在/hello.jsp

在早期的SpringMVC开发中有对应的Controller接口public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response)实现相应的功能处理,如收集参数、验证参数、绑定参数到命令对象、将命令对象传入业务对象进行业务处理、最后返回ModelAndView对象

ModelAndView:包含了视图要实现的模型数据和逻辑视图名
mv.addObject(“message”名称, “Hello World!”具体存储的对象);表示添加模型数据,此处可以是任意POJO对象
mv.setViewName(“hello”);表示设置逻辑视图名为“hello”,视图解析器会将其解析为具体的视图,如前边的视图解析器InternalResourceViewResolver会将其解析为“/hello.jsp”

Controller如何接收请求参数
1、参数驱动
请求参数名称和方法参数名称一致,如果数据类型不是String,SpringMVC框架会自动进行数据类型转换;当然如果转换失败,则异常
public ModelAndView hello(String username){
System.out.println(“Hello…”+username);

相关问题1: HTTP ERROR 400 Bad Request
    public ModelAndView hello(String username,int num)  请求为hello.do?username=zhangsan&num=
    这里是因为SpringMVC发现请求参数中num没有对应的数据,则不能查找到对应的方法MethodArgumentTypeMismatchException

相关问题2:如果参数值为String类型,则不传递参数不会报错。例如/hello.do?username=&num=5或者/hello.do?num=5

相关问题3:如果方法的参数名称和请求的参数名称不一致,可以使用注解进行配置
    hello(@RequestParam("name") String username, int num)  请求URL为/hello.do?name=zhangsan&num=5

@RequestParam注解:用于适配请求中的参数名称和方法中的参数名称
    属性value等价于name
    属性name就是请求参数中的名称,用于指定@RequestParam(name="name") String username表示username=request.getParameter("name")
    属性required默认值true,表示要求这个参数是必须有的,如果没有对应的请求参数则HTTP ERROR 400 Required request parameter 'name'
    for method parameter type String is not present。如果这个参数不是必须的,可以添加required=false
    属性defaultValue用于配置没有该参数时的默认值。如果提交了该参数则使用提交的数据,如果没有提交数据则使用默认值
        hello(@RequestParam(value="name",defaultValue="abcd") String username)如果请求为/hello.do?name=lisi&num=5,则username=lisi。
        如果/hello.do?name=&num=5或者/hello.do?num=5则默认值生效

相关问题4:中文乱码问题
    针对提交的中文数据一般采用post提交。SpringMVC提供了一个专门的filter,需要进行配置  web.xml
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
    </filter>
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>*.do</filter-class>
    </filter>

2、模型驱动
提交的请求参数会按照名称对应的方式注入到方法参数的值bean中,支持自动类型转换
注意:模型驱动和参数驱动不互斥,例如UserBean中有一个参数username,同时方法中也有参数username,则这两个位置都能获取到数据
public ModelAndView hello(User user)
请求地址/hello.do?username=zhangsan&password=123456&sex=true

可以在方法中添加request对象,然后通过request对象中的getParameter接收用户请求参数,但是不建议
public ModelAndView hello(HttpServletRequest request){
//接收用户提交数据
String username=request.getParameter(“username”);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值