SpringMVC
SpringMVC
本人的理解:学习一个框架,最好的是先从大体上了解大致的运行流程,进而结合实例,从具体出发,对每个流程的具体细节进行了解,这样可以做到从实例中进行学习,对框架的知识进行有条理的梳理和记忆,同时有助于形成一个大局观念。本笔记就是按照这种思路出发,由大到小,有大致流程到具体细化,从每个细节出发,形成一个完成的学习流程,最后在阅读源码。任重而道远,与君共勉。
SpringMVC的请求到相应全过程:
具体流程:
⑴用户发送一个请求到主机或者服务器;
⑵Servlet容器接受到请求,将请求发送给Spring MVC控制器,但是一般会有多个控制器,所以Serlvet会查询一个或者多个Handler Mapping来确定请求的Controller是哪个
⑶请求到达具体控制器,控制器进行逻辑处理,然后返回信息,这些信息称为model,同时信息需要发送一个视图,最后控制器将模型数据打包,并标示出用于渲染输出的视图名,将请求和视图名发送回Servlet
⑷Servlet使用视图解析器来将视图名匹配为一个特定的视图实现
⑸视图的实现,即视图将使用模型数据渲染输出,将视图通过响应对象传递给客户端。
一,DispatcherServlet配置
DispatcherServlet继承HttpServlet,HttpServlet是在web.xml文件中声明的,可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,本例中Serlvet-name为hello,因此Spring配置文件为hello-servlet.xml;
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>SpringMVCProject</display-name>
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!--可以自定义servlet.xml配置文件的位置和名称,默认为WEB-INF目录下,名称为[<servlet-name>]-servlet.xml,如spring-servlet.xml
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
hello-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: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/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!-- 启用spring mvc 注解 -->
<context:annotation-config />
<context:component-scan base-package="com.dong.Controller"></context:component-scan>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
</beans>
二,请求与控制器的映射
使用的注解有:
@Controller:用来声明这是一个控制器
@Controller
public class controller {
}
@RequestMapping:将请求的URL与注解中的值进行匹配RequestMapping可以放在类上,也可以放在方法上,然后执行注解所标注的方法进行相应的处理;方法的返回值为下一个视图的名称。
@RequestMapping注解中的参数有:
value: 代表映射的路径
method:代表请求的类型。
consumes:代表请的HTTP头的Content-Type媒体类型;
produces:对应于HTTP请求的Accept字段。
params:判断请求参数;
@Controller
@RequestMapping("test")
public class controller {
@RequestMapping(value="hello",method=RequestMethod.GET,consumes="text/html",produces="text/html")
public String hello() {
return "success";
}
@RequestParam:进一步限定HTTP参数到Controller方法的映射关系:参数有:
value:指明HTTP参数的名称
required:boolean类型,声明参数是否必须有
defaultValue:字符类型,如果HTTP参数没有提供,可以指定一个默认字符串。
@Controller
@RequestMapping("test")
public class controller {
@RequestMapping(value="hello",method=RequestMethod.GET,consumes="text/html",produces="text/html")
public String hello(@RequestParam(name="id",required=true) Integer id) {
return "success";
}
@PathVariable:将URL路径作为参数传递给方法,
@RequestMapping(value="hello4/{name}")
public String hello5(@PathVariable ("name") String name) {
System.out.println(name);
return "success";
}
注意:HTTP提交的参数可以映射到方法参数上,按照名称来映射。
请求:/hello04/ld?id=6&address=shanxi,中的id和address会按名字映射到参数中。
@RequestMapping(value="hello4/{name}")
public String hello5(@PathVariable ("name") String name,Integer id,String address) {
return "success";
}
@ModelAttribute:使用该注解的变量将作为Model的一个属性,通常用在Controller的某个方法上,此方法会首先被调用,并将方法结果作为Model的属性,然后再调用对应的Controller处理方法。
@RequestBody:自动将请求内容转为指定的对象,默认使用HttpMessageConverters来转化。
方法中使用的参数有:
Model model:代表一个模型,用于将数据放入到模型中,然后再视图中可以获取到放入的数据
@RequestMapping(value="hello4/{name}")
public String hello5(@PathVariable ("name") String name, Model model) {
model.addAttribute("name",name);
System.out.println(name);
return "success";
}
ModeAndView view : 类似与Model,但是又提供了一个视图名称,ModelView对象即可以通过方法声明,也可以在方法中构造。
@RequestMapping(value="model",method=RequestMethod.GET)
public ModelAndView testModelAndView() {
ModelAndView mv = new ModelAndView("success");
mv.addObject("model", "springmodel");
return mv;
}
MultipartFile file:处理文件的上传。
@RequestMapping(value="test")
public String testFileMultipartFile(String name,MultipartFile file) throws IOException {
if(!file.isEmpty()) {
String filename= file.getOriginalFilename();
InputStream ins = file.getInputStream();
OutputStream out =new FileOutputStream("xxx");
//...
return "success";
}
return "failure";
}
三,验证
Spring支持Java校验API(Java Validation API,又称JSR-303),Spring3.0支持JSR,在SpringMVC中,使用JSR,不需要任何额外的配置。只要保证类路径下包含这个Java API的实现即可。
JSR的常用校验注解有:
@NotNull:非空
@Size:元素值为String,集合数组,且长度符合给定的范围
@Null:必须为空
@Digits:元素为数字,且指定大小范围
@Max:最大值
@Min:最小值
应用校验功能,使用@Valid注解
@Component
public class User {
@NotNull
private String user;
@NotNull
private String password;
@Min
private Integer age;
//get/set方法
}
@RequestMapping(value="testvalidator")
public String testvalidator(@Valid User user,Error errors) {
return "success";
}
四,Web视图
我们已经讲到,Request请求如何进行handler Mapping映射找到相应的控制器,控制器进行逻辑处理(根据具体的业务代码),将数据填充到模型中,然后将模型传递给一个用来渲染的视图,方法返回一个String类型的值,值为视图的逻辑名称,不会直接饮用具体的视图实现。将控制器中请求处理的逻辑和视图中渲染实现解耦是Spring MVC的一个重要特性。
Spring通过视图解析器来决定使用哪个视图实现来渲染模型,
常用视图解析器有:
InternalResourceViewResolve:将视图解析为Web应用的内部资源(一般为JSP),
TilesViewResolver:将视图解析为Apache Title定义
FreeMarkerViewResolver:将视图解析为FreeMarker模板
VelocityViewResolver:将视图解析为Velocity布局。
。。。
通过xml文件配置使用哪个视图解析器:在[<Servlet-name>]-servlet.xml中进行配置。
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
也可以通过Java配置实现。
Spring的标签库可以避免我们在脚本快中直接编写Java代码,Spring提供了两个JSP标签库,用来帮助定义Spring MVC Web的视图。
对于标签库的实现我们可以查看手册来进行熟悉。
下一章节将具体使用一个完成的案例展现SpringMVC
内容参考《Spring实现》第四版 《Spring Boot2精髓》 从构建小系统到架构分布式大系统。