美文网首页
Spring-MVC

Spring-MVC

作者: Zeppelin421 | 来源:发表于2021-09-16 21:44 被阅读0次

Spring MVC是Spring给我们提供的一个用于简化Web开发的框架

简介

MVC体系

常用的开发框架一般基于两种形式,一种C/S架构,一种B/S架构。在JavaEE开发中,几乎都是基于B/S架构的。在B/S架构中,系统标准的三层包括:表现层、业务层、持久层。

  • 表现层
    也就是我们常说的Web层。它负责接收客户端请求,向客户端响应结果,通常客户端使用http协议请求web层,完成http响应。表现层包括展示层和控制层:控制层负责接收请求,展示层负责结果的展示。表现层依赖业务层,接收到客户端请求一般回调用业务层进行业务处理,并将处理结果响应给客户端。表现层的设计一般都使用MVC模型。
  • 业务层
    也就是我们常说的Service层。它负责业务逻辑处理,和我们开发项目的需求息息相关。web层依赖业务层,但业务层不依赖web层。
  • 持久层
    也就是我们常说的dao层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进行持久化的载体,数据访问层是业务层和持久层交互的接口,业务层需要通过数据访问层将数据持久化到数据库中。

MVC设计

MVC全名Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,是一种用于设计创建Web应用程序表现层的模式。

  • Model(模型)
    模型包含业务模型和数据模型,数据模型用于封装数据,业务模型用于处理业务
  • View(视图)
    通常指我们的JSP或者HTML页面,作用一般就是展示数据。视图是依据模型数据创建
  • Controller(控制器)
    应用程序中处理用户交互的部分。作用一般是处理程序逻辑的。

TIPS:MVC提倡每一层只编写自己的东西,不编写任何其他的代码;分层是为了解耦,为了维护方便和分工协作

Spring MVC

SpringMVC全名Spring Web MVC,是一种基于Java实现的MVC设计模型的请求驱动类型的轻量级Web框架,属于spring-framework后续产品。SpringMVC本质可以认为是对Servlet的封装,简化了我们Servlet的开发

工作流程

1、配置DispatchServlet前端控制器
2、开发处理具体业务逻辑的Handler(@Controller、@RequestMapping)
3、xml配置文件配置Controller扫描,配置springmvc三个件
4、将xml文件路径告诉springmvc(DispatchServlet)

请求处理流程


  • step1:用户发送请求至前端控制器DispatchServlet
    step2:DispatchServlet收到请求调用HandlerMapping处理器映射器
    step3:处理器映射器根据请求URL找到具体的Handler,生产处理器对象及处理器拦截器,返回DispatchServlet
    step4:DispatchServlet调用HandlerAdapter处理器适配器去调用Handler
    step5:处理器适配器执行handler
    step6:Handler执行完成给处理器适配器返回ModelAndView
    step7:处理器适配器向前端控制返回ModelAndView,ModelAndView是SpringMVC框架的一个底层对象,包括model和view
    step8:前端控制器请求视图解析器去进行视图解析,根据逻辑视图名来解析真正的视图
    step9:视图解析器向前端控制器返回view
    step10:前端控制器进行视图渲染,就是将模型数据填充到request域
    step11:前端控制器向用户响应结果

九大组件

  • HandlerMapping(处理器映射器)
    HandlerMapping是用来查找Handler的,也就是处理器,具体的表现形式可以是类,也可以是方法。比如标注了@RequestMapping的每个方法都可以看成一个Handler。Handler负责具体实际的请求处理,在请求到达后,HandlerMapping的作用就是找到请求相应的处理器Handler和Interceptor
  • HandlerAdapter(处理器适配器)
    HandlerAdapter是一个适配器。因为SpringMVC中Handler可以是任意形式的,只要能处理请求即可。但是把请求交给Servlet的时候,由于Servlet的方法结构都是doService(HttpServletRequest,HttpServletResponse)形式的,要让固定的Servlet处理方法调用Handler来进行处理,便是HandlerAdapter的职责
  • HandlerExceptionResolver
    HandlerExceptionResolver用于处理Handler产生的异常情况。它的作用是根据异常设置ModelAndView,之后交给渲染方法进行渲染,渲染方法会将ModelAndView渲染成页面
  • ViewResolver
    ViewResolver即视图解析器,用于将String类型的视图名和Locale解析为View类型的视图,只有一个resolveViewName方法。Controller层返回的String类型视图名viewName最终会在这里被解析成View。View是用来渲染页面的,也就是说它会将程序返回的参数和数据填入模板中,生产HTML文件。ViewResolver主要完成两件事:1)找到渲染所用的模板,2)找到所用的技术(找到视图的类型,如JSP)并填入参数。默认情况下,SpringMVC会自动配置一个InternalResourceViewResolver是针对JSP类型视图的。
  • RequestToViewNameTranslator
    RequestToViewNameTranslator组件的作用是从请求中获取ViewName。因为ViewResolver根据ViewName查找View,但有的Handler处理完成之后没有设置View也没有设置ViewName,便要通过这个组件从请求中查找ViewName
  • LocaleResolver
    ViewResolver组件的resolveViewName方法需要两个参数,一个是视图名,一个是Locale。LocaleResolver用于从请求中解析出Locale,比如中国Locale是zh-CN,用来表示一个区域。这个组件也是i18n的基础
  • ThemeResolver
    ThemeResolver组件是用来解析主题的。主题是样式、图片及它们所形成的的显示效果的集合。SpringMVC中一套主题对应一个properties文件。里面存放着与当前主题相关的所有资源,如图片、CSS样式等。创建主题只需要准备好资源,然后新建一个“主题名.properties”并将资源设置进去,放在classpath下,之后便可以在页面中使用了。SpringMVC中与主题相关的类有ThemeResolver、ThemeSource和Theme。ThemeResolver负责从请求中解析出主题名,ThemeSource根据主题名找到具体的主题,其抽象就是Theme,可以通过Theme来获取主题和具体的资源。
  • MultipartResolver
    MultipartResolver用于上传请求,通过将普通的请求包装成MultipartHttpServletRequest来实现。MultipartHttpServletRequest可以通过getFile方法直接获得文件。如果上传多个文件,还可以调用getFileMap方法得到Map<FileName, File>这样的结构,MultipartResolver的作用就是封装普通的请求,使其拥有文件上传的功能。
  • FlashMapManager
    FlashMap用于重定向时的参数传递。因为重定向时没有传递参数这一功能,如果不想把参数写进URL(不推荐),那么就可以通过FlashMap来传递。只需要在重定向之前将要传递的数据写入请求的属性OUTPUT_FLASH_MAP_ATTRIBUTE中,这样在重定向之后的handler中Spring就会自动将其设置到Model中。FlashMapManager就是用来管理FlashMap的。

参数绑定

  • 默认支持Servlet API作为方法参数
    当需要使用HttpServletRequest、HttpServletResponse、HttpSession等原生Servlet对象时,直接在handler方法中形参声明使用即可
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, HttpSession session) {}
  • 绑定简单类型参数
    绑定简单数据类型参数,只需要直接声明形参即可,形参参数名和传递的参数名要保持一致。当形参参数名和传递参数名不一致时可以使用@RequestParam注解进行手动映射。建议使用包装类型,因为基础数据类型不可以为null
public ModelAndView handle(@RequestParam("ids") Integer id, Boolean flag) {}
  • 绑定POJO类型参数
    接受POJO类型参数,直接形参声明即可,类型就是POJO类型,形参名无所谓,但是要求传递的参数名必须和POJO的属性名保持一致
public ModelAndView handle(User user) {}
  • 绑定POJO包装对象参数
    不管包装POJO与否,首先它是一个POJO,那么就可以按照POJO的要求来。绑定是直接形参声明即可;传参参数名和POJO属性保持一致,如果不能定位数据项,那么通过属性名+“.”的方式进一步锁定数据
public class QueryVO {
    private User user;
}
// url: /demo/handle?user.id=1&user.username=zhangsan
public ModelAndView handle(QueryVO query) {}
  • 自定义类型转换器
// 定义类型转换器
public class DateConverter implements Converter<String, Date> {
    public Date convert(String source) {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        try {
            Date parse = simpleDateFormat.parse(source);
            return parse;
        } catch (ParseException e) {}
    }
    return null;
}

// 注册自定义类型转换器
<!-- 自动注册最合适的处理器映射器,处理器适配器 -->
<mvc:annotation-driven conversion-service="conversionServiceBean"/>
<!--注册自定义转化器-->
<bean id="conversionServiceBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
    <property name="converters">
        <set>
            <bean class="com.xxx.converter.DateConverter"/>
        </set>
    </property>
</bean>

@RequestMapping("/handle")
public ModelAndView handle(Date birthday) {
}

RESTful风格支持

RESTful风格URL:互联网所有的事物都是资源,要求URL中只有表示资源的名词,没有动词
RESTful风格资源操作:使用HTTP请求中的method方法put、delete、post、get来操作资源,分别对应添加、删除、修改、查询。不过一般使用时还是POST和GET。PUT和DELETE几乎不用
RESTful风格资源表述:可以根据需求对URL定位的资源返回不同的表述(也就是返回数据类型,比如XML、JSON等数据格式)
SpringMVC支持RESTful风格请求,具体讲就是使用@PathVariable注解获取RESTful风格的请求URL中的路径变量

<form method="post" action="/demo/handle">
    <input type="text" name="username"/>
    <input type="submit" value="修改"/>
</form>
<form method="post" action="/demo/handle/15/lisi">
    <input type="hidden" name="_method" value="put"/>
    <input type="submit" value="新增"/>
</form>
<form method="post" action="/demo/handle">
    <input type="hidden" name="_method" value="delete"/>
    <input type="submit" value="删除"/>
</form>

@RequestMapping(value = "/demo/handle/{id}", method={RequestMethod.GET}
public ModelAndView get(@PathVariable("id") Integer id) {
}

@RequestMapping(value = "/demo/handle/{id}/{name}", method={RequestMethod.PUT}
public ModelAndView add(@PathVariable("id") Integer id, @PathVariable("username") String username) {
}

@RequestMapping(value = "/demo/handle/{id}", method={RequestMethod.POST}
public ModelAndView update(@PathVariable("id") Integer id, String username) {
}

@RequestMapping(value = "/demo/handle/{id}", method={RequestMethod.DELETE}
public ModelAndView add(@PathVariable("id") Integer id) String username) {
}

<!-- 配置springmvc请求方式转换过滤器,会检查请求参数中是否有_method参数,如果有就按照指定的请求方式进行转换-->
<filter>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>hiddenHttpMethodFilter</filter-name>
    <url-pattern>/*<url-pattern>
</filter-mapping>

Ajax Json交互

@ResponseBody注解
@ResponseBody注解的作用是将Controller的方法返回的对象通过适当的转化器转化为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者XML数据。
TIPS:在使用此注解之后不会再走视图处理器,而是直接将数据写入输入流中,它的效果等同于通过response对象输入指定格式的数据

@RequestMapping("/handle")
public @ResponseBody User handle(@RequestBody User user) {
}

SpringMVC高级技术

拦截器(Interceptor)

监听器、过滤器和拦截器对比

  • Servlet:处理Request请求和Response相应
  • 过滤器(Filter):堆Request请求起到过滤的作用,作用在Servlet之前,如果配置为/*可以对所有的资源访问进行过滤处理
  • 监听器(Listener):实现了javax.servlet.ServletContextListener接口的服务端组件,它随Web应用的启动而启动,只初始化一次,然后会一直运行监视,随web应用的停止而销毁
    作用一:做一些初始化工作,web应用中spring容器启动ContextLoaderListener
    作用二:监听web中的特定事件,比如HttpSession,ServletRequest的创建和销毁;变量的创建、销毁和修改等。可以在某些动作前后增加处理,实现监控,比如统计在线人数,利用HttpSessionListener
  • 拦截器(Interceptor):是SpringMVC、Struts等表现层框架自己的,不会拦截jsp/html/css/images的访问等,只会拦截访问的控制器方法(Handler)
    从配置的角度也能够发现:servlet、filter、listener是配置在web.xml中的,而Interceptor是配置在表现层框架自己的配置文件中的。

    拦截器执行流程

    1)程序先执行preHandle方法,如果该方法的返回值为true,则程序会继续向下执行处理器中的方法,否则将不再向下执行
    2)在业务处理器(即控制器Controller类)处理完请求后,会执行postHandle方法,然后会通过DispatchServlet向客户端返回响应
    3)在DispatchServlet处理完请求后,才会执行afterCompletion方法
    多拦截器的执行流程

    当有多个拦截器同时工作时,它们的preHandle方法会按照配置文件中拦截器的配置顺序执行,而它们的postHandle和afterCompletion则会按照配置顺序的反序执行

控制器中处理异常

@ControllerAdvice
public class GlobalExceptionResolver {
    @ExceptionHandler(ArithmeticException.class)
    public ModelAndView handleException(ArithmeticException exception, HttpServletResponse response) {
        ModelAndView modelAndView = new ModelAndView();
        modelAndView.addObject("msg", exception.getMessage());
        modelAndView.setViewName("error");
    }
}

基于Flash属性的跨重定向请求数据传递

重定向时请求参数会丢失,我们往往需要重新携带请求参数,我们可以进行手动参数拼接。
return "redirect:handle?name=" + name;
但上述拼接参数的方法属于get请求,携带参数长度有限,参数安全性也不高,此时,我们可以使用SpringMVC提供的flash属性机制,向上下文中添加flash属性,框架会在session中记录该属性,当跳转到页面之后框架会自动删除flash属性,不需要我们手动删除,通过这种方式进行重定向参数传递,参数长度和安全性都得到了保障。

@RequestMapping("/handle")
public String handle(String name, RedirectAttributes redirectAttributes) {
    redirectAttributes.addFlashAttribute("name", name);
    return "redirect:handle01";
}

相关文章

  • spring-mvc

    spring-mvc spring-mvc不是spring的core内容,需要额外引入jar包spring-mvc...

  • springmvc xml

    spring-beans.xml spring-context.xml spring-mvc spring-dat...

  • 源码分析spring-mvc启动流程

    spring-mvc 的启动流程 1、request 请求到达 dispatchServlet-> doServi...

  • spring-mvc

  • spring-mvc

    springmvc DispatcherServlet:前端控制器 概念:spring在web层的一个mvc架构的...

  • Spring-MVC

    监听器初始化ioc 配置文件拆分 @ControllerAdvice全局异常拦截 @RestControllerA...

  • Spring-MVC

    2019-06-14 Spring 框架提供了构建 Web 应用程序的全功能 MVC 模块,可以取代Servlet...

  • spring-mvc

    您有一份文件待查收!即刻点击链接获取文件: https://cowtransfer.com/s/8f865d551...

  • Spring-MVC

    Spring MVC是Spring给我们提供的一个用于简化Web开发的框架 简介 MVC体系 常用的开发框架一般基...

  • 0509-web:app页面完善:s-mvc交互框架(数据绑定)

    spring-mvc交互框架 概述 Controller会返回一个ModelAndView的实例 Spring根据...

网友评论

      本文标题:Spring-MVC

      本文链接:https://www.haomeiwen.com/subject/lvxcgltx.html