默认的DispatcherServlet配置

在spring-webmvc-4.3.16.RELEASE.jar/org/springframework/web/servlet/路径下的DispatcherServlet.properties是默认的DispatcherServlet配置,包括视图解析器、映射处理器等,打比方,如果配置了InternalResourceViewResolver,则将会覆盖默认的ViewResolver实现列表。

 # Default implementation classes for DispatcherServlet's strategy interfaces.
# Used as fallback when no matching beans are found in the DispatcherServlet context.
# Not meant to be customized by application developers. org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager

 DispatcherServlet处理流程

当配置好DispatcherServlet并有请求过来,DispatcherServlet将会进行如下流程:

1、WebApplicationContext在请求中被搜索并绑定,作为控制器和流程中的其他元素可以使用的属性。它默认通过DispatcherServlet.WEB_APPLICATION_CONTEXT_ATTRIBUTE进行绑定。
2、本地解析器被绑定到请求,以便在处理请求时(呈现视图、准备数据等)处理场所中的元素。
3、主题解析器被绑定到请求,让视图等元素决定使用哪个主题。
4、如果您指定了一个多部件文件解析器,那么该请求将被检查为多部分;如果发现了多部件,则请求包裹在多parthttpservletrequest中,以便在过程中进行其他元素的进一步处理。
5、将会寻找一个合适的handler。如果一个handler被发现的话,和这个handler(预处理器、后期处理器以及控制器)相关的执行链将会被执行,用于准备一个model或者渲染。
6、如果返回一个模型,就会呈现一个视图。如果没有返回模型,(可能是由于预处理器或后处理器拦截请求,可能出于安全原因),没有视图,因为请求已经完成了。

HelloWorldController:
package com.led.controller;

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping; /**
* @author Alan
* @date 2018/5/23 22:07
* @Controller:表明这个是一个控制器
* @RequestMapping:定义请求路径
*/
@Controller
public class HelloWorldController {
@RequestMapping("/helloWorld")
public String helloWorld(Model model){
model.addAttribute("message","Hello world");
return "helloworld";
}
}

该类接收了一个Model并返回了一个String类型的view.

@RequestMapping的组合形式

Spirng4.3版本建议使用以下组合注解的形式来简化常用的HTTP方法并更好的表达注释的含义。

@GetMapping==>@RequestMapping(method = RequestMethod.GET)
@PostMapping==>@RequestMapping(method = RequestMethod.POST)
@PutMapping==>@RequestMapping(method = RequestMethod.POST)
@DeleteMapping==>@RequestMapping(method = RequestMethod.DELETE)
@PatchMapping==>@RequestMapping(method = RequestMethod.PATCH)

 @Controller and AOP Proxying

在某些情况下,控制器可能需要在运行时用AOP代理来装饰。一个例子是,如果您选择直接在控制器上有@transactional注释。在这种情况下,对于控制器来说,我们建议使用基于类的代理这通常是控制器的默认选择。然而,如果一个控制器必须实现一个不是Spring上下文回调的接口(例如初始化bean、感知等等),那么您可能需要显式地配置基于阶级的代理。例如,将<tx:annotation-driven/>改为<tx:annotation-driven proxy-target-class="true"/>。

URI Template Patterns

例如,URI模板http://www.example.com/users/{userId}包含变量userId。实例如http://www.example.com/users/fred。

在Spring MVC中通过在方法参数上使用@PathVariable注解,将请求里面的变量绑定到形参上。

@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable String ownerId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
model.addAttribute("owner", owner);
return "displayOwner";
}

下面这种更具体:

@GetMapping("/owners/{ownerId}")
public String findOwner(@PathVariable("ownerId") String theOwner, Model model) {
// implementation omitted
}

一个方法里面可以有多个@PathVariable注解

@GetMapping("/owners/{ownerId}/pets/{petId}")
public String findPet(@PathVariable String ownerId, @PathVariable String petId, Model model) {
Owner owner = ownerService.findOwner(ownerId);
Pet pet = owner.getPet(petId);
model.addAttribute("pet", pet);
return "displayPet";
}

@PathVariable的参数可以是int、long、Date、String等。

后缀匹配

".*"的后缀形式可以匹配/person.*,比如/person.pdf/person.xml。

使用@RequestParam注解为方法参数绑定请求参数

@Controller
@RequestMapping("/pets")
@SessionAttributes("pet")
public class EditPetForm { // ... @GetMapping
pub ) {
Pet pet = this.clinic.loadPet(petId);
model.addAttribute("pet", pet);
return "petForm";
} // ... }

如果请求参数不是必须的,可以写成:@RequestParam(name="id", required=false)

 使用@ResponseBody映射响应体

这个注解指示返回类型应该直接写入HTTP响应主体,而不是放在模型中,或者被解释为视图名。

@GetMapping("/something")
@ResponseBody
public String helloWorld() {
return "Hello World";
}

上面的例子将导致文本Hello World被写入HTTP响应流。

使用@RestController注解创建REST风格的controller

这是一个非常常见的用例,让控制器实现REST API,因此只提供JSON、XML或自定义的MediaType内容。

@RestController结合了@Controller和@ResponseBody。

在方法中使用@ModelAttribute注解

@ModelAttribute可以用在方法上或者方法参数上。

一个方法上的@modelattribute表明该方法的目的是添加一个或多个模型属性。这些方法支持与@requestmapping方法相同的参数类型,但是不能直接映射到请求。相反,控制器中的@modelattribute方法在@requestmapping方法之前被调用,在同一个控制器中。

// Add one attribute
// The return value of the method is added to the model under the name "account"
// You can customize the name via @ModelAttribute("myAccount") @ModelAttribute
public Account addAccount(@RequestParam String number) {
return accountManager.findAccount(number);
} // Add multiple attributes @ModelAttribute
public void populateModel(@RequestParam String number, Model model) {
model.addAttribute(accountManager.findAccount(number));
// add more ...
}

请注意@ModelAttribute方法的两种风格。在第一种方法中,该方法通过返还属性隐式添加属性。在第二种方法中,方法接受一个模型并向它添加任意数量的模型属性。你可以根据你的需要在两种风格之间做出选择。

一个控制器可以有多个@ModelAttribute注解的方法,他们都在@RequestMapping注解的方法之前调用(同一个controller内)。@ModelAttribute注释也可以用于@RequestMapping方法。在这种情况下,@RequestMapping方法的返回值被解释为一个model属性,而不是一个视图名。然后,视图名称基于视图名约定派生而来,就像返回void的方法一样。

@ModelAttribute用在方法参数上

此时该方法的参数是从model属性中获取的,如果不在模型中出现,则应该先实例化一旦出现在模型中,参数的字段应该从具有匹配名称的所有请求参数中填充。,然后再添加到模型中。这在Spring MVC中被称为数据绑定,这是一种非常有用的机制,可以帮助您不必单独解析每个表单字段。

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute Pet pet) { }

根据上面的例子,宠物实例可以从哪里来?有几种选择:

1、由于使用@sessionattributes,它可能已经在模型中了

2、由于在同一个控制器中有一个@modelattribute方法,它可能已经在模型中了。

3、可以根据URI模板变量和类型转换器检索它。

4、可以使用它的默认构造函数实例化。

@ModelAttribute方法是从数据库中检索属性的常用方法,它可以通过使用@sessionattributes在请求之间存储。在某些情况下,通过使用URI模板变量和类型转换器来检索属性可能很方便。这是一个例子:

@PutMapping("/accounts/{account}")
public String save(@ModelAttribute("account") Account account) {
// ...
}

在这个例子中,model属性的名称(例如“account”)匹配URI模板变量的名称。如果你注册了转换器<字符串,帐户,它可以把字符串帐户值转换成一个帐户实例,那么上面的例子就可以不用@ModelAttribute方法了。

由于数据绑定的结果,可能会出现一些错误,比如缺少所需的字段或类型转换错误。要检查这些错误,请立即在@ModelAttribute参数后面添加一个BindingResult参数:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { if (result.hasErrors()) {
return "petForm";
} // ... }

有了一个BindingResult,您可以检查是否发现了错误,在这种情况下,呈现相同的表单,可以显示错误,这是很常见的。请注意,在某些情况下,在没有数据绑定的情况下访问模型中的属性可能是有用的。对于这种情况,您可以将模型注入控制器中,也可以在注释上使用绑定标志:

@ModelAttribute
public AccountForm setUpForm() {
return new AccountForm();
} @ModelAttribute
public Account findAccount(@PathVariable String accountId) {
return accountRepository.findOne(accountId);
} @PostMapping("update")
public String update(@Valid AccountUpdateForm form, BindingResult result,
@ModelAttribute(binding=false) Account account) { // ...
}

除了数据绑定之外,您还可以使用您自己的自定义验证器来调用验证,该验证器传递了用于记录数据绑定错误的相同BindingResult。这使得数据绑定和验证错误可以在一个地方累积,并随后向用户报告:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@ModelAttribute("pet") Pet pet, BindingResult result) { new PetValidator().validate(pet, result);
if (result.hasErrors()) {
return "petForm";
} // ... }

或者,您可以通过添加@Valid注解有效注释来自动调用验证:

@PostMapping("/owners/{ownerId}/pets/{petId}/edit")
public String processSubmit(@Valid @ModelAttribute("pet") Pet pet, BindingResult result) { if (result.hasErrors()) {
return "petForm";
} // ... }

使用@sessionattributes在请求之间的HTTP会话中存储模型属性

类型级@SessionAttributes注释声明一个特定处理程序使用的会话属性。这通常会列出模型属性的名称或模型属性的类型,这些属性应该透明地存储在会话中或一些会话存储中,在随后的请求之间充当表单支持bean。

下面的代码片段显示了这个注释的用法,指定了模型属性名:

@Controller
@RequestMapping("/editPet.do")
@SessionAttributes("pet")
public class EditPetForm {
// ...
}

使用@SessionAttribute来访问预先存在的全局会话属性 

如果您需要访问全局管理的已存在的会话属性,例如在控制器之外(例如通过过滤器),并且可能或可能不存在于方法参数上的@sessionattribute注释:

@RequestMapping("/")
public String handle(@SessionAttribute User user) {
// ...
}

作为控制器工作流的一部分,在会话中临时储存模型属性,请考虑使用SessionAttributes。

使用@RequestAttribute获取请求属性

与@SessionAttribute类似,@RequestAttribute注释可以用来访问由过滤器或拦截器创建的预先存在的请求属性:

@RequestMapping("/")
public String handle(@RequestAttribute Client client) {
// ...
}

SpringMVC官方文档阅读的更多相关文章

  1. [E] Shiro 官方文档阅读笔记 The Reading Notes of Shiro's Offical Docs

    官方文档: https://shiro.apache.org/reference.html https://shiro.apache.org/java-authentication-guide.htm ...

  2. python2.7官方文档阅读笔记

    官方地址:https://docs.python.org/2.7/tutorial/index.html 本笔记只记录本人不熟悉的知识点 The Python Tutorial Index 1 Whe ...

  3. 保存与恢复变量和模型,tensorflow官方文档阅读笔记

    官方中文文档的网址先贴出来:https://tensorflow.google.cn/programmers_guide/saved_model tf.train.Saver 类别提供了保存和恢复模型 ...

  4. Spark SQL官方文档阅读--待完善

    1,DataFrame是一个将数据格式化为列形式的分布式容器,类似于一个关系型数据库表. 编程入口:SQLContext 2,SQLContext由SparkContext对象创建 也可创建一个功能更 ...

  5. lavarel5.2官方文档阅读——架构基础

    <目录> 1.请求的生命周期 2.应用的架构 3.服务提供者 4.服务容器 5.Facades外立面(从这节起,看中文版的:https://phphub.org/topics/1783) ...

  6. pandas官方文档阅读收获

    1.当心它里面的简写: 第二张图中的输出实际上是等效于: df = df.drop() df 若只进行下面的操作,则drop操作不会起作用,因为它的inplace默认为False: df.drop() ...

  7. iOS官方文档阅读 基本格式指北

    一些关键词作用 NS_AVAILABLE 表示可用 如 NS_AVAILABLE(NA, 6_0);例如上面这句就是表示 该方法在6.0系统后可用 如果在6.0以下的系统用不了的 或者直接崩溃. NS ...

  8. 教你如何阅读Oracle数据库官方文档

    < Ask Oracle官方原创 > Oracle 官方文档 数量庞大,而且往往没有侧重点,让oracle新手看起来很费力.但是,仍有很多Oracle使用者认为任何oracle学习资料都比 ...

  9. 阅读Python官方文档心得

    我会每天都阅读一些python的官方文档,并每天更新心得体会. -------------------------------------------------2016.12.08--------- ...

随机推荐

  1. NODE-WEBKIT教程(5)NATIVE UI API 之FRAMELESS WINDOW

    node-webkit教程(5)Native UI API 之Frameless window 文/玄魂 原文链接:http://www.xuanhun521.com/Blog/2014/4/15/n ...

  2. 记Asp.Net Core Swagger 使用 并带域接口处理

    引用作者原话:Asp.Net的WebApi中使用Swagger作为说明和测试的页面是非常不错的,比起WebApiTestClient来至少在界面上的很大的提升.但是使用Swagger时如果只是一般的控 ...

  3. 关于ubuntu软件卸载的问题

    ...... 起因很菜....就是手贱把/usr/lib/下的R的目录给rm -rf掉了, 然后在R的软件包里用./configure也生不成, R RHOME还在, 然而因为lib下的R删掉了所以R ...

  4. Akka(42): Http:身份验证 - authentication, authorization and use of raw headers

    当我们把Akka-http作为数据库数据交换工具时,数据是以Source[ROW,_]形式存放在Entity里的.很多时候除数据之外我们可能需要进行一些附加的信息传递如对数据的具体处理方式等.我们可以 ...

  5. 学习使用Apollo配置中心

    Apollo(阿波罗)是携程框架部门研发的配置管理平台,能够集中化管理应用不同环境.不同集群的配置,配置修改后能够实时推送到应用端. Apollo官网地址 如何安装服务端可以按照上面官网的步骤. 这里 ...

  6. [Vue] vue-cli3.0安装

    1. node.js安装https://nodejs.org/en/download/ 2.npm的安装 由于新版的nodejs已经集成了npm,所以之前npm也一并安装好了.同样可以通过输入 &qu ...

  7. django安装与环境调配

    91.查看当前已有虚拟环境 2.进入虚拟环境 3.退出当前虚拟环境 4.创建python隔离环境前先可用此先查看已经拥有什么版本的python 5.创建一个名为first的python隔离环境 6.安 ...

  8. Eclipse连接MuMu模拟器 方便 测试 查日志

    Eclipse连接MuMu模拟器 方便 测试 查日志 问题由来 真机测试麻烦(首先你得拿一部手机,然后在用数据线连接电脑和手机...) 解决流程 确保打开MuMu模拟器和Eclipse的DDMS功能 ...

  9. Ubutntu安装docker启动报Removed /etc/systemd/system/docker.service.

    Ubutntu安装docker启动报Removed /etc/systemd/system/docker.service.的错误,只需要执行以下三条命令. systemctl unmask docke ...

  10. 桶排序和计数排序的理解实现和比较(Java)

    比较和非比较的区别 常见的快速排序.归并排序.堆排序.冒泡排序等属于比较排序.在排序的最终结果里,元素之间的次序依赖于它们之间的比较.每个数都必须和其他数进行比较,才能确定自己的位置.比较排序的优势是 ...