Java-SpringMVC-前端控制器

一. SpringMVC

1. 相关概念

mvc 模式
在这里插入图片描述
springmvc 原理
在这里插入图片描述

  1. 用户发送请求到前端控制器,即 DispatcherServlet
  2. DispatcherServlet 收到请求调用 HandlerMapping 处理器映射器
  3. HandlerMapping 将处理器对象及处理器拦截器返回给 DispatcherServlet
  4. DispatcherServlet 调用 HandlerAdapter 处理器适配器
  5. HandlerAdapter 经过适配调用具体的处理器
  6. Controller 执行完成返回 ModelAndView
  7. HandlerAdapter 将 ModelAndView 返回给 DispatcherServlet
  8. DispatcherServlet 将 ModelAndView 传给 ViewReslover 视图解析器
  9. ViewReslover 解析后返回具体 View
  10. DispatcherServlet 根据 View 进行渲染视图
  11. DispatcherServlet 响应用户

springmvc 九大组件

关于 Handler:
@RequestMapping 标注的所有方法都可以看成是一个Handler,只要可以实际处理请求就可以是Handler

public class DispatcherServlet extends FrameworkServlet {
	
	...
	/*multipartResolver:
	用于处理上传请求,将普通request包装成MultipartHttpServletRequest,
	MultipartHttpServletRequest可以直接调用getFile方法获取File,
	如果上传多个文件,还可以调用getFileMap得到FileName->File结构的Map
	multipartResolver有三个方法:
	判断是不是上传请求;
	将request包装成MultipartHttpServletRequest;
	处理完后清理上传过程中产生的临时资源。
	*/
	@Nullable
    private MultipartResolver multipartResolver;

	/*localeResolver:
	用于从request解析出Locale
	Locale就是如zh-CN、en-US之类,表示一个区域,有了这个就可以对不同区域的用户显示不同的结果
	用处:
	一是ViewResolver视图解析的时候;
	二是用到国际化资源或者主题的时候
	*/
    @Nullable
    private LocaleResolver localeResolver;

	/*themeResolver:
	 用于解析主题,SpringMVC中一个主题对应一个properties文件
	 里面存放着跟当前主题相关的所有资源、如图片、css样式等
	 要得到一个主题的资源,首先要得到资源的名称,这就是themeResolver的工作
	*/
    @Nullable
    private ThemeResolver themeResolver;

	/*handlerMappings:
	是用来查找对应Handler,每个请求都需要一个Handler处理
	handlerMappings来判断具体接收到一个请求之后,使用哪个Handler进行处理
	*/
    @Nullable
    private List<HandlerMapping> handlerMappings;

	/*handlerAdapters:
	SpringMVC中以Handler处理请求,可以是任意的形式
	Servlet需要的处理方法的结构是固定的,都是以request和response为参数的方法
	handlerAdapters把Handler与Servlet进行了适配
	*/
    @Nullable
    private List<HandlerAdapter> handlerAdapters;

	/*handlerExceptionResolvers:
	对异常情况进行处理
	再根据异常设置ModelAndView,之后再交给render方法进行渲染
	*/
    @Nullable
    private List<HandlerExceptionResolver> handlerExceptionResolvers;

	/*viewNameTranslator:
	有的Handler处理完后并没有设置View也没有设置ViewName,这时就需要从request获取ViewName了
	RequestToViewNameTranslator在一个Translator里面实现了所有request到ViewName的转换规则
	*/
    @Nullable
    private RequestToViewNameTranslator viewNameTranslator;

	/*flashMapManager:
	用来管理FlashMap的,FlashMap主要用在redirect中传递参数
	*/
    @Nullable
    private FlashMapManager flashMapManager;
    @Nullable
    private List<ViewResolver> viewResolvers;
    
	...

2. DispatcherServlet(前端控制器)

DispatcherServlet 拦截所有 web 请求并进行匹配、转发、数据处理

在 web.xml 中配置 DispatcherServlet 等,完整版 web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns="http://java.sun.com/xml/ns/javaee"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

  <display-name>Archetype Created Web Application</display-name>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>

  <!--SpringMVC的相关配置,目的:把表现层交给SpringMVC管理-->
  <!--SpringMVC-配置前端控制器-->
  <servlet>
    <servlet-name>DispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--加载dispatcher-servlet.xml配置文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:dispatcher-servlet.xml</param-value>
    </init-param>
    <!--启动服务器时创建该servlet,值越小优先级越高-->
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>DispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

  <!--配置监听器把applicationContext.xml加入到配置文件中-->
  <!--ContextLoadListener默认只加载WEB-INF目录下的配置文件,所以要设置一个路径参数传入-->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!--设置路径参数-->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>

  <!--配置解决中文乱码的过滤器,且一定要放在所有过滤器之前-->
  <filter>
    <filter-name>CharacterEncodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <!--解决post请求乱码-->
    <init-param>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
    <!--解决响应乱码-->
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>CharacterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

</web-app>

加载指定的初始化配置文件 dispatcher-servlet.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:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context.xsd">

    <!--此文件负责整个SpringMVC的核心配置-->

    <!--开启注解扫描,负责表现层controller-->
    <context:component-scan base-package="com.codfish">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
    </context:component-scan>

    <!-- 模型视图解析器,即在模型视图名称添加前后缀(如果最后一个还是文件夹,则最后的斜杠不要漏了) 使用JSP-->
    <bean id="internalResourceViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/><!--前缀,即JSP文件的目录位置-->
        <property name="suffix" value=".jsp"/><!--后缀-->
    </bean>

    <!--静态资源映射-->
    <!--本项目把静态资源放在了webapp的statics目录下,资源映射如下-->
    <mvc:resources mapping="/css/**" location="/statics/css/"/>
    <mvc:resources mapping="/js/**" location="/statics/js/"/>
    <mvc:resources mapping="/image/**" location="/statics/images/"/>
    <mvc:default-servlet-handler/>  <!--这句要加上,要不然可能会访问不到静态资源,具体作用自行百度-->

    <!--开启SpringMVC注解的支持,可以将request参数与绑定到controller参数上 -->
    <mvc:annotation-driven/>

</beans>

二. Springboot 中的 SpringMVC

1. @RequestMapping 注解

源码:

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {
    String name() default "";

    @AliasFor("path")
    String[] value() default {};

    @AliasFor("value")
    String[] path() default {};

    RequestMethod[] method() default {};

    String[] params() default {};

    String[] headers() default {};

    String[] consumes() default {};

    String[] produces() default {};
}
  • method:指定HTTP协议中的请求方式,如GETPOST(PUT、DELETE)等,指定后如果不按规定的请求方式请求会报错,不指定则接收任何方式的请求
@RequestMapping(method = RequestMethod.POST)
@GetMaping //相当于@RequestMapping(method = RequestMethod.GET)
@PostMaping //相当于@RequestMapping(method = RequestMethod.POST)
@PutMapping //相当于@RequestMapping(method = RequestMethod.PUT)
@DeleteMapping //相当于@RequestMapping(method = RequestMethod.DELETE)

  • params:请求时必须(不)包含指定的一个或多个参数以及对应参数值,否则报错
@RequestMapping(params = {"username", "age!=28"})

  • headers:请求时必须包含指定的header(请求头)中的值,否则报错
    在这里插入图片描述
@RequestMapping(headers = {"User-Agent = Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:80.0) Gecko/20100101 Firefox/80.0"})

  • consumes:指定请求时的 Content-Type ,如 text/html
@RequestMapping(consumes = "text/html")

  • produces:指定响应的 Content-Type,请求头中的 Accept 中必须包含该类型才能返回
@RequestMapping(produces = "application/json;charset=utf-8")

  • value:指定请求的实际地址
@RequestMapping(value = "/project")

可搭配 ANT 风格实现 URL 的模糊匹配

通配符说明
?匹配任意单个字符
*匹配0或多个任意字符
**匹配0或多层目录

2. REST (REpresentational State Transfer)

核心思想:URL 用名词定位资源,用 HTTP动词 描述操作

  • GET:获取资源
  • POST:新建资源
  • PUT:更新资源
  • DELETE:删除资源

目的:

  • 看 url 就知道要什么
  • 看 http method 就知道干什么
  • 看 http status code 就知道结果如何

3. @RequestParam 和 @RequestBody(获取前端请求的数据)

源码:

@Target({ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface RequestParam {
    @AliasFor("name")
    String value() default "";

    @AliasFor("value")
    String name() default "";

    boolean required() default true;

    String defaultValue() default "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";
}
  • value:请求参数名,即后台获取 .html 中设置的变量名(必须配置)
  • required:请求中必须包含该参数,默认为 true,如果没包含则会抛出异常(可选配置)
  • defaultValue:为获取的参数赋默认值,设置后无论是否配置了 required ,都自动设为 false(可选配置)

在这里插入图片描述

Thymeleaf(Springboot 推荐的视图解析器)

要使用 Thymeleaf 语法必须引入空间名称

<html lang="en" xmlns:th="http://www.thymeleaf.org"></html>

在这里插入图片描述
IDEA 中通过 Thymeleaf 语法读取变量时爆红色波浪线问题
在这里插入图片描述
在 Thymeleaf 模板引擎下的error文件夹里可以定制错误信息面页
在这里插入图片描述

4. Model(回显数据)

常规绑定数据的方式,给handle方法传入Map、Model、ModelMap参数

  • Map:JDK提供的接口
  • Model:Spring提供的接口,最常用
  • ModelMap:Map接口下的一个类

三种方式最终都是实现了 BindingAwareModelMap

  • 使用SpringMVC的 ModelAndView 对象也可以给面页传递数据

以上四种方式,返回的数据都在 request域 中

//方式一
@RequestMapping("/echo")
public String echo(Model model){
	model.addAttribute("message", "回显的信息");
	return "echopage";
}

//方式二
@RequestMapping("/echo")
public String echo(ModelMap modelMap){
	modelMap.addAttribute("message", "回显的信息");
	return "echopage";
}

//方式三
@RequestMapping("/echo")
public String echo(Map<String, Object> map){
	map.put("message", "回显的信息");
	return "echopage";
}

//方式四
@RequestMapping("/echo")
public ModelAndView echo(){
	ModelAndView mav = new ModelAndView("echopage");
	mav.addObject("massage", "回显的信息");
	return mav;
}

@ModelAttribute 该注解已淘汰

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值