SpringMVC

SpringMVC是一种轻量级的、基于MVC的Web层应用框架。

通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。

采用了松散耦合可插拔组件结构,比其他 MVC 框架更具扩展性和灵活性。

优点:

  1、天生与Spring框架集成,如:(IOC,AOP)

  2、支持Restful风格

  3、支持灵活的URL到页面控制器的映射

  4、非常容易与其他视图技术集成,如:Velocity、FreeMarker等等

  5、因为模型数据不存放在特定的API里,而是放在一个Model里(Map数据结构实现,因此很容易被其他框架使用)

  6、非常灵活的数据验证、格式化和数据绑定机制、能使用任何对象进行数据绑定,

  7、更加简单、强大的异常处理

  8、对静态资源的支持

  9、支持灵活的本地化、主题等解析

 常用主要组件

  ① DispatcherServlet:前端控制器
  ② Controller:处理器/页面控制器,做的是MVC中的C的事情,但控制逻辑转移到前端控制器了,用于对请求进行处理
  ③ HandlerMapping:请求映射到处理器,找谁来处理,如果映射成功返回一个HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器对象)
  ④ View Resolver : 视图解析器,找谁来处理返回的页面。把逻辑视图解析为具体的View,进行这种策略模式,很容易更换其他视图技术;如InternalResourceViewResolver将逻辑视图名映射为JSP视图
  ⑤ LocalResolver:本地化、国际化
  ⑥ MultipartResolver:文件上传解析器
  ⑦ HandlerExceptionResolver:异常处理器

Spring MVC 的配置文件

流程分析

基本步骤:

  ①    客户端请求提交到DispatcherServlet

  ②    由DispatcherServlet控制器查询一个或多个HandlerMapping,找到处理请求的Controller

  ③    DispatcherServlet将请求提交到Controller(也称为Handler)

  ④    Controller调用业务逻辑处理后,返回ModelAndView

  ⑤    DispatcherServlet查询一个或多个ViewResoler视图解析器,找到ModelAndView指定的视图

  ⑥    视图负责将结果显示到客户端

标准的 HTTP 请求报头

@RequestMapping

1、使用@RequestMapping 注解来映射请求的 URL    

  @RequestMapping可以应用的地方

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
public @interface RequestMapping {…}

  请求的方式有

public enum RequestMethod {
GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE
}

  @RequestMapping可以为控制器指定可以处理哪些 URL 请求,将该注解中的 value 属性值映射成URL,客户端可以通过该URL请求到指定类中的方法。

    1)在控制器的类定义或方法定义处都可标注 @RequestMapping
      ① 标记在类上:提供初步的请求映射信息。相对于 WEB 应用的根目录
      ② 标记在方法上:提供进一步的细分映射信息。相对于标记在类上的 URL。
    2)若类上未标注 @RequestMapping,则方法处标记的 URL 相对于 WEB 应用的根目录 
    3)作用:DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法。

  @RequestMapping属性

    value:指定URL路径
    method:指定请求方式 
    params:指定请求参数
    headers:指定请求头信息

  映射请求参数、请求方式或请求头

    1)@RequestMapping 除了可以使用请求 URL 映射请求外,还可以使用请求方法、请求参数及请求头来精确映射对应请求
    2)@RequestMapping 的 value【重点】、method【重点】、params【了解】 及 heads【了解】 分别表示请求 URL、请求方式、请求参数及请求头的映射条件,他们之间是与的关系,联合使用多个条件可让请求映射更加精确化。即:需满足所有映射条件才可匹配到对应方法
    3)params 和 headers支持简单的表达式:
      param1: 表示请求必须包含名为 param1 的请求参数
      !param1: 表示请求不能包含名为 param1 的请求参数
      param1 != value1: 表示请求包含名为 param1 的请求参数,但其值不能为 value1
      {"param1=value1", "param2"}: 请求必须包含名为 param1 和param2 的两个请求参数,且 param1 参数的值必须为 value1

Ant 路径风格

  Ant 风格资源地址支持 3 种匹配符:【了解】
    ?:匹配文件名中的一个字符
    *:匹配文件名中的任意字符
    **:** 匹配多层路径

/user/*/**/createUser??
匹配 /user/xxx/多层/createUserXX

REST

REST是什么?因为REST的内涵非常丰富,所以很难用一两句话解释清楚这个问题。首先,REST是Web自身的架构风格。

参考资料:理解本真的REST架构风格  

  REST:即 Representational State Transfer。(资源)表现层状态转化。是目前最流行的一种互联网软件架构。它结构清晰、符合标准、易于理解、扩展方便

  资源(Resources):资源是一种看待服务器的方式。是网络上的一个实体,可以是一段文本、一张图片,可以用一个URI(统一资源定位符,独一无二的识别符)指向它,获取这个资源,访问它的URI就可以了

  表现层资源的表述(Representation)是一段对于资源在某个特定时刻的状态的描述,即把资源具体呈现出来的形式, 比如,文本可以用 txt 、JSON 格式表现,甚至可以采用二进制格式。

  状态转化(State Transfer):状态转移说的是:在客户端和服务器端之间转移(transfer)代表资源状态的表述。通过转移和操作资源的表述,来间接实现操作资源的目的。如:每发出一个请求,就代表了客户端和服务器的一次交互过程。HTTP协议,是一个无状态协议,即所有的状态都保存在服务器端。因此,如果客户端想要操作服务器,必须通过某种手段,让服务器端发生“状态转化”。而这种转化是建立在表现层之上的,所以就是 “表现层状态转化”。

  统一接口(Uniform Interface)REST要求,必须通过统一的接口来对资源执行各种操作。对于每个资源只能执行一组有限的操作。例如:HTTP/1.1协议定义了一个操作资源的统一接口。REST还要求,对于资源执行的操作,其操作语义必须由HTTP消息体之前的部分完全表达,不能将操作语义封装在HTTP消息体内部。这样做是为了提高交互的可见性

  超文本驱动(Hypertext Driven)将Web应用看作是一个由很多状态(应用状态)组成的有限状态机。资源之间通过超链接相互关联,超链接既代表资源之间的关系,也代表可执行的状态迁移。即:客户端应该依赖的是超媒体的状态迁移语义,而不应该对于是否存在某个URI或URI的某种特殊构造方式作出假设。一切都有可能变化,只有超媒体的状态迁移语义能够长期保持稳定。

  具体对于HTTP来说,就是 HTTP 协议里面对应的四种常用基本操作:GET 用来获取资源,POST 用来新建资源,PUT 用来更新资源,DELETE 用来删除资源。应使用由客户端定义的请求方式指定对应的某种操作,而不应该通过某种特殊构造方式进行指定

HiddenHttpMethodFilter过滤器

  浏览器 form 表单只支持 GET 与 POST 请求,HiddenHttpMethodFilter 可以将POST请求转换为标准的 http 方法以达到REST风格

使用步骤

  1. 必须将form表单中的method设置为POST
  2. 提交表单时,必须提交"_method"参数,一般使用隐藏域

    原因:HiddenHttpMethodFilter过滤器将HttpServletRequest中的getMethod()方法,重写啦。

    <!--    配置处理请求方式-->
<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>

处理请求数据

  Spring MVC 框架会将 HTTP 请求的信息绑定到相应的方法入参中,并根据方法的返回值类型做出相应的后续处理。

  可以对方法及方法入参标注相应的注解( @PathVariable 、@RequestParam、@RequestHeader 等)

@PathVariable请求占位符

  是 Spring3.0 新增的功能,通过 @PathVariable 可以将 URL 中占位符参数绑定到控制器处理方法的入参中

//@PathVariable 注解可以将请求URL路径中的请求参数,传递到处理请求方法的入参中
// 浏览器的请求为: testPathVariable/1001
@RequestMapping(value="/testPathVariable/{id}",method=RequestMethod.DELET)
public String testPathVariable(@PathVariable("id") Integer id) {}

@RequestParam请求参数

  如果请求参数与形参不一致时,可以使用@RequestParam注解实现获取参数值

  书写位置:标注在方法的参数中,springMVC默认会将请求参数注入(绑定)到方法形参中(两个参数名一致)

  一旦使用该注解,必须为相应参数传参数。如果未传参,会报错:400,因为required默认为 true,

  value:用于映射请求参数名称

  required:是否必须。默认为 true, 表示请求参数中必须包含对应的参数,若不存在,将抛出异常

  defaultValue: 默认值,当没有传递参数时使用该值作为默认值,不设默认为 null

 @RequestMapping(value="/testRequestParam?username=guigu&age=10")
public String testRequestParam(
@RequestParam(value="username") String username,
@RequestParam(value="age",required=false,defaultValue="0") int age){
return "success";
}

@RequestHeader 请求头

  获取请求头信息,请求头包含了若干个属性,服务器可据此获知客户端的信息,通过 @RequestHeader 即可将请求头中的属性值绑定到处理方法的入参中

@CookieValue 

  获取指定的Cookie信息,可让处理方法入参绑定某个 Cookie 值

使用POJO作为参数

  Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值支持级联属性

    @RequestMapping(value = "/emps",method = RequestMethod.PUT)
public String updateEmp(Employee employee){
employeeDao.save(employee);
return "redirect:/emps";
}
   //Spring MVC 会按请求参数名和 Employee 属性名进行自动匹配, 自动为该对象填充属性值。支持级联属性

配置字符编码过滤器

    <!--    处理POST请求和响应乱码-->
<filter>
<filter-name>characterEncodingFilter</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>
<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>

GET请求乱码

  • GET请求参数是在地址后面的。我们需要修改tomcat的配置文件。需要在server.xml文件修改Connector标签,添加URIEncoding="utf-8"属性。

使用Servlet原生API

    /**
* 可以使用 Serlvet 原生的 API 作为目标方法的参数 具体支持以下类型
* HttpServletRequest
* HttpServletResponse
* HttpSession
* java.security.Principal
* Locale
   * InputStream
* OutputStream
* Reader
* Writer
*/
@RequestMapping("/testServletAPI")
public void testServletAPI(HttpServletRequest request,HttpServletResponse response, Writer out) throws IOException {
System.out.println("testServletAPI, " + request + ", " + response);
out.write("hello springmvc");
}

处理响应数据

2、返回值会通过视图解析器解析为实际的物理视图

输出模型数据类型

  1)    ModelAndView: 作为返回值类型,响应数据:处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据

  2)  String: 作为返回值类型,即为视图信息直接找字符串映射 URL 路径,转发或重定向

  3)    Map 或 Model: 作为参数,响应数据:入参为 Model、ModelMap 或  Map,处理方法返回时,Map 中的数据会自动添加到模型中。

ModelAndView

  控制器处理方法的返回值如果为 ModelAndView, 则其包含视图信息包含模型数据信息

  1)  两个重要的成员变量:

    private Object view;                       【视图信息】

    private ModelMap model;              【模型数据】

  2)添加模型数据:

    MoelAndView addObject(String attributeName, Object attributeValue)   【设置模型数据】

    ModelAndView addAllObject(Map<String, ?> modelMap)

  4)设置视图:

    void setView(View view)                         【设置视图对象】

    void setViewName(String viewName)            【设置视图名字】

  5)获取模型数据

    protected Map<String, Object> getModelInternal()   【获取模型数据】

    public ModelMap getModelMap()

    public Map<String, Object> getModel()

    @RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){
String viewName = "success";
ModelAndView mv = new ModelAndView(viewName);
mv.addObject("time",new Date().toString()); //实质上存放到request域中
return mv;
}

ModelAndView 底层工作原理,不论控制器返回一个String,ModelAndView,View都会转换为ModelAndView对象,将数据放到request域中,再通过转发实现页面跳转

Map   Model

  Spring MVC 在内部使用了一个 org.springframework.ui.Model 接口存储模型数据

  Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器

  如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。

  在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据

    //目标方法的返回类型也可以是一个Map类型参数(也可以是Model,或ModelMap类型)
@RequestMapping("/testMap")
public String testMap(Map<String, Object> map) { //【重点】
System.out.println(map.getClass().getName());
//org.springframework.validation.support.BindingAwareModelMap
map.put("names", Arrays.asList("Tom", "Jerry", "Kite"));
return "success";
}

注意问题:Map集合的泛型,key为String,Value为Object,而不是String

由源码可知:不论用那个类型作为数据模型,其内部都会转化为BindingAwareModelMap类型使其指向同一map对象

BindingAwareModelMap底层支持两种接口(Map&Model)推荐使用 Map 便于框架移植

Java框架之SpringMVC 03-RequestMapping-请求数据-响应数据的更多相关文章

  1. 【Spring学习笔记-MVC-5】利用spring MVC框架,实现ajax异步请求以及json数据的返回

    作者:ssslinppp      时间:2015年5月26日 15:32:51 1. 摘要 本文讲解如何利用spring MVC框架,实现ajax异步请求以及json数据的返回. Spring MV ...

  2. 使用Typescript重构axios(十六)——请求和响应数据配置化

    0. 系列文章 1.使用Typescript重构axios(一)--写在最前面 2.使用Typescript重构axios(二)--项目起手,跑通流程 3.使用Typescript重构axios(三) ...

  3. Fiddler之模拟响应、修改请求或响应数据(断点)

    在测试过程中,有时候需要修改请求或响应数据,或者直接模拟服务器响应,此时可以使用fiddler进行此类操作.可以使用断点功能完成. 一.修改请求数据 在发起请求后,需要修改请求的数据时,可以设置请求前 ...

  4. java框架之SpringMVC(2)-补充及拦截器

    高级参数绑定 package com.zze.springmvc.web.controller; import org.springframework.stereotype.Controller; i ...

  5. Java框架之SpringMVC 05-拦截器-异常映射-Spring工作流程

    SpringMVC 拦截器 Spring MVC也可以使用拦截器对请求进行拦截处理,可以自定义拦截器来实现特定的功能,自定义的拦截器可以实现HandlerInterceptor接口中的三个方法,也可以 ...

  6. SpringMVC 入门、请求、响应

    目录 SpringMVC 概述 SSM 简介 MVC 简介 SpringMVC 简介 入门案例 Spring 技术架构 SpringMVC 基础配置 常规配置 Controller 加载控制 静态资源 ...

  7. 用 jQuery.ajaxSetup 实现对请求和响应数据的过滤

    不知道同学们在做项目的过程中有没有相同的经历呢?在使用 ajax 的时候,需要对请求参数和响应数据进行过滤处理,比如你们觉得就让请求参数和响应信息就这么赤裸裸的在互联网里来回的穿梭,比如这样: 要知道 ...

  8. java框架之springmvc

    一.HelloWorld程序 (1)导包:四个spring 核心包(core.beans.context.expression).一个aop包.两个 web 包和一个logging 包: (2)配置 ...

  9. java框架之SpringMVC(1)-入门&整合MyBatis

    前言 SpringMVC简介 SpringMVC 是一个类似于 Struts2 表现层的框架,属于 SpringFramework 的后续产品. 学习SpringMVC的原因 SpringMVC 与 ...

随机推荐

  1. 原生Js 实现等比缩放页面

    针对1920*1080 分配率缩放 window.addEventListener('load', adaptation); window.addEventListener('resize', ada ...

  2. 分布式全局唯一ID

    方案一.UUID UUID的方式能生成一串唯一随机32位长度数据,它是无序的一串数据,按照开放软件基金会(OSF)制定的标准计算,UUID的生成用到了以太网卡地址.纳秒级时间.芯片ID码和许多可能的数 ...

  3. Codeforces Round #564(div2)

    Codeforces Round #564(div2) 本来以为是送分场,结果成了送命场. 菜是原罪 A SB题,上来读不懂题就交WA了一发,代码就不粘了 B 简单构造 很明显,\(n*n\)的矩阵可 ...

  4. 2019-8-31-dotnet-core-隐藏控制台

    title author date CreateTime categories dotnet core 隐藏控制台 lindexi 2019-08-31 16:55:58 +0800 2019-2-1 ...

  5. 2018-8-14-resharper-自定义代码片

    title author date CreateTime categories resharper 自定义代码片 lindexi 2018-08-14 17:34:51 +0800 2018-2-13 ...

  6. 2018-2-13-win10-uwp-csdn-博客阅读器

    title author date CreateTime categories win10 uwp csdn 博客阅读器 lindexi 2018-2-13 17:23:3 +0800 2018-2- ...

  7. WPF实现软键盘

    wpf 实现一个软键盘, 先发个图: 工作有需要实现一个软键盘,本来想用windows自带的软键盘凑合凑合得了,又觉得那个软键盘太大了,所以自己实现了一个. 说一下实现的思路,其实没什么思路 界面就是 ...

  8. maxmind geoip2使用笔记

    客户需求如下,nginx的访问日志中ip,匹配出对应的国家,省份和城市,然后给我了一个maxmind的连接参考. 查找资料,有做成hive udf的使用方式, 我们项目中一直使用 waterdrop ...

  9. js获取url参数值的方式

    定义方法: function getParam(paramName) { paramValue = ""; isFound = false; paramName = paramNa ...

  10. slim中的请求URI

    请求 URI 每个 HTTP 请求都有一个识别被请求的应用程序资源的 URI .HTTP 请求 URI 分为这几部分: Scheme (e.g. http or https) Host (e.g. e ...