Spring MVC初体验
Spring MVC介绍
什么是Spring MVC
- Spring MVC是Spring体系的轻量级Web MVC框架
- Spring MVC的核心Controller控制器,用于处理请求,产生响应
- Spring MVC基于Spring IOC容器运行,所有对象被IOC管理
Spring 5.x 版本变化
- Spring 5.x最低要求JDK8与J2EE(Servlet 3.1/Tomcat 8.5)
- Spring 5.x支持JDK8/9,可以使用新特性
- Spring 5.x最重要的新特性支持响应式编程
创建Maven WebApp
- 创建webapp目录
选中项目根目录,File => Project Structure => Facets => add => Web => 填写配置 => OK
=> 自动创建src/main/webapp目录
- 配置Template的Local Tomcat Server
Edit Configurations => Templates => Tomcat Server
#Application server中是Tomcat的存放路径
- 使用Template的Local Tomcat Server
Edit Configurations => add => 选择Tomcat Server / local

Spring MVC环境配置
- Maven依赖spring-webmvc
pom.xml
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.song</groupId><artifactId>spring_mvc_first</artifactId><version>1.0-SNAPSHOT</version><!-- 引入阿里云镜像仓库 --><repositories><repository><id>aliyun</id><name>aliyun</name><url>https://maven.aliyun.com/repository/public</url></repository></repositories><dependencies><dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>5.1.9.RELEASE</version></dependency></dependencies></project>
- web.xml配置DispatcherServlet
src/main/webapp/WEB_INF/web.xml
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"version="3.1"><!-- DispatchServlet --><!--DispatchServlet是Spring MVC最核心的对象DispatchServlet用于拦截Http请求,并根据请求的URL调用与之对应的Controller方法,来完成HTTP请求的处理--><servlet><servlet-name>springmvc</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><!-- applicationContext.xml --><init-param><param-name>contextConfigLocation</param-name><param-value>classpath:applicationContext.xml</param-value></init-param><!-- 在Web应用启动时自动创建Spring IOC容器,并初始化DispatcherServlet --><load-on-startup>0</load-on-startup></servlet><servlet-mapping><servlet-name>springmvc</servlet-name><!-- "/"代表拦截所有请求 --><url-pattern>/</url-pattern></servlet-mapping></web-app>
src/main/resources/applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mv="http://www.springframework.org/schema/mvc"
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.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--
context:component-scan 标签作用
在Spring IOC初始化过程中,自动创建并管理com.song.springmvc及子包中
拥有以下注解的对象.
@Repository
@Service
@Controller
@Component
-->
<context:component-scan base-package="com.song.springmvc"></context:component-scan>
<!--启用Spring MVC的注解开发模式-->
<mvc:annotation-driven/>
<!-- 将图片/JS/CSS等静态资源排除在外,可提高执行效率 -->
<mvc:default-servlet-handler/>
</beans>
- 添加依赖到发布目录
虽然在pom.xml中增加了springmvc依赖,但是默认情况下这些依赖不会自动增加到发布的目录(WEB-INF)中,所以需要手动指向到WEB-INF中
操作:Edit Configurations => Deployment => edit => 选择以下依赖包 => 右键选择”Put into/WEB-INF/lib”
- 测试
src/main/java/com.song.springmvc.controller
package com.song.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class TestController {
@GetMapping("/t") // localhost:8080/t
@ResponseBody // 直接向响应输出字符串数据,不跳转页面
public String test(){
return "SUCCESS";
}
}
结果:localhost:8080/t页面显示”SUCCESS”
总结:
在以前开发的时候,都使用servlet进行web请求的处理,但是servlet在很多时候并不好用,而Spring MVC简化了web处理过程。
在以上例子中,可以把TestController当初原有servlet的替代品,不需要引人servlet的请求响应对象,只需要添加对应的注解就可以了。

MVC数据绑定
URL Mapping(URL映射)
URL Mapping概念:
- URL Mapping指将URL与Controller方法绑定
- 通过将URL与方法绑定,SpringMVC便可通过Tomcat对外暴露服务
URL Mapping注解:
- @RequestMapping - 通用绑定
一般放在类中,用于设置地址前缀
- @GetMapping - 绑定Get请求
- @PostMapping - 绑定Post请求 ```java package com.song.springmvc.controller;
import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody;
@Controller @RequestMapping(“/um”) public class URLMappingController { @GetMapping(“/get”) @ResponseBody public String getMapping() { return “This is get method”; }
@PostMapping("/post")
@ResponseBody
public String postMapping() {
return "This is post method";
}
}
<a name="5btS7"></a>
#### Controller方法参数接受参数
src/main/com/song/springmvc/controller<br />#@RequestParam,可以解决参数名不一致的问题(下划线和驼峰的适配)
```java
package com.song.springmvc.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/um")
public class URLMappingController {
@GetMapping("/get")
@ResponseBody
public String getMapping(@RequestParam("manager_name") String managerName) {
System.out.println("managerName:" + managerName);
return "This is get method";
}
@PostMapping("/post")
@ResponseBody
public String postMapping(String username, Long password) {
System.out.println(username + ":" + password);
return "This is post method";
}
}
Controller实体对象接受参数
src/main/java/com/song/springmvc/entity/User.java
package com.song.springmvc.entity;
public class User {
private String username;
private Long password;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getPassword() {
return password;
}
public void setPassword(Long password) {
this.password = password;
}
}
package com.song.springmvc.controller;
import com.song.springmvc.entity.User;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/um")
public class URLMappingController {
@PostMapping("/post2")
@ResponseBody
public String postMapping2(User user){
System.out.println(user.getUsername() + ":" + user.getPassword());
return "This is post method";
}
}
接受表单复合数据
- @RequestParam,可以指定默认值
- List和Map接受参数,必须用@RequestParam修饰
- 建议使用List接受复合数据,而Map无法接受复合数据 ```java package com.imooc.springmvc.controller;
import com.imooc.springmvc.entity.Form; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import java.util.List; import java.util.Map;
@Controller public class FormController { // @PostMapping(“/apply”) @ResponseBody public String apply(@RequestParam(value = “n”,defaultValue = “ANON”) String name, String course, Integer[] purpose){ System.out.println(name); System.out.println(course); for (Integer p : purpose) { System.out.println(p); } return “SUCCESS”; }
// @PostMapping(“/apply”)
@ResponseBody
public String apply(String name, String course, @RequestParam List
// @PostMapping(“/apply”) @ResponseBody public String apply(Form form){ return “SUCCESS”; } @PostMapping(“/apply”) @ResponseBody public String apply(@RequestParam Map map){ System.out.println(map); return “SUCCESS”; } }
<a name="tij8b"></a>
#### 关联对象赋值
前端传递参数:<br /><br />后端接受对象:<br />delivery是Form对象中的一个关联对象,Spring MVC会自动赋值<br />
<a name="NJx1Y"></a>
#### 日期类型转换
1. 利用@DateTimeFormat注解
方法参数接受
```java
@PostMapping("/p1")
@ResponseBody
public String postMapping1(User user , String username ,@DateTimeFormat(pattern = "yyyy-MM-dd") Date createTime){
System.out.println(user.getUsername() + ":" + user.getPassword());
return "<h1>这是Post响应</h1>";
}
实体对象接受
package com.imooc.springmvc.entity;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.RequestParam;
import java.util.Date;
public class User {
private String username;
private Long password;
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date createTime;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Long getPassword() {
return password;
}
public void setPassword(Long password) {
this.password = password;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
- 全局日期转换器
每个地方都用日期注解去转换会很麻烦,我们就可以设置一个全局日期转换器来解决这个问题
#全局日期转换器和日期注解转换只能两者选一个
src/main/java/com/song/springmvc/converter/MyDateConverter.java
package com.imooc.springmvc.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class MyDateConverter implements Converter<String, Date> {
public Date convert(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
<!-- 如果有多中日期格式,这里需要处理一下 -->
<!-- 比如如果长度是8为的话,就采用yyyyMMdd的形式等 -->
try {
Date d = sdf.parse(s);
return d;
} catch (ParseException e) {
return null;
}
}
}
src/main/resources/applicationContext.xml
<!--启用Spring MVC的注解开发模式-->
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.imooc.springmvc.converter.MyDateConverter"/>
</set>
</property>
</bean>
中文乱码问题解决
Web应用的中文乱码由来
- Tomcat默认使用字符集ISO-8859-1,属于西欧字符集
- 解决乱码的核心思路是将ISO-8859-1转换为UTF-8
- Controller中请求与相应都需要设置UTF-8字符集
中文乱码的配置
- Get请求乱码:tomcat的server.xml增加URIEncoding属性
tomcat/conf/server.xml
<Connector port="8080" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" URIEncoding="UTF-8" />
tomcat8.0以后的版本可以不用设置,因为默认就是UTF-8
- Post请求乱码:web.xml配置CharacterEncodingFilter
webapp/WEB-INF/web.xml
<filter>
<filter-name>characterFilter</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>
</filter>
<filter-mapping>
<filter-name>characterFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
- Response响应乱码:Spring配置StringHttpMessageConverter
src/main/resources/applicationContext.xml
<!--启用Spring MVC的注解开发模式-->
<mvc:annotation-driven conversion-service="conversionService">
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<!-- response.setContentType("text/html;charset=utf-8") -->
<value>text/plain;charset=utf-8</value>
<value>text/html;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
响应输出
ResponseBody - 产生响应文本
- @ResponseBody直接产生响应体的数据,过程不涉及任何视图
- @ResponseBody可产生标准字符串/JSON/XML等格式数据
- @ResponseBody被StringHttpMessageConverter所影响
ModelAndView - 利用模板引擎渲染输出
- ModelAndView对象是指”模型(数据)与视图(界面)”对象
- 通过ModelAndView可将包含数据对象与模板引擎进行绑定
- SpringMVC默认的Vive是JSP,也可以配置其他模板引擎
@GetMapping("/view") public ModelAndView showView(Integer userId){ // ModelAndView mav = new ModelAndView("redirect:/view.jsp"); ModelAndView mav = new ModelAndView(); mav.setViewName("/um/view.jsp"); User user = new User(); if(userId == 1){ user.setUsername("lily"); }else if(userId == 2){ user.setUsername("smith"); }else if(userId == 3){ user.setUsername("lina"); } mav.addObject("u" , user); return mav; } //String与ModelMap //Controller方法返回String的情况 //1. 方法被@ResponseBody描述,SpringMVC直接响应String字符串本身 //2. 方法不存在@ResponseBody,则SpringMVC处理String指代的视图(页面) @GetMapping("/xxxx") // @ResponseBody public String showView1(Integer userId , ModelMap modelMap){ String view = "/um/view.jsp"; User user = new User(); if(userId == 1){ user.setUsername("lily"); }else if(userId == 2){ user.setUsername("smith"); }else if(userId == 3){ user.setUsername("lina"); } modelMap.addAttribute("u", user); return view; }
ModelAndView对象核心用法
。。。省略。。。
Spring MVC整合FreeMarker
。。。省略。。。
