1. 构建SpringMVC项目
1.1 通过Maven构建一个web项目
1.2 添加相关的依赖
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.1.7.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
</dependencies>
<!-- Tomcat插件 --->
<build>
<finalName>spring-mvc-demo</finalName>
<plugins>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>
<version>2.2</version>
<configuration>
<port>8082</port>
<path>/</path>
<uriEncoding>utf-8</uriEncoding>
</configuration>
</plugin>
</plugins>
</build>
1.3 创建Spring配置文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- 适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
</beans>
1.4 在web.xml中配置DispatchServlet
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
1.5 创建自定义的Controller
package com.wxw.controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) throws Exception {
System.out.println("HelloController执行了!!!");
ModelAndView view = new ModelAndView();
view.setViewName("/index.jsp");
return view;
}
}
1.6 在Spring配置文件中配置Controller
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 映射器 -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"></bean>
<!-- 适配器 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<bean class="com.wxw.controller.HelloController" name="/hello" />
</beans>
1.7 运行测试
启动Tomcat
访问接口
2. 基于注解的方式
2.1 修改Spring配置文件
<?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"
xmlns:mvc="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 base-package="com.wxw.controller" />
<!-- 开启SpringMVC注解的使用 -->
<mvc:annotation-driven />
</beans>
2.2 创建自定义的Controller
package com.wxw.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
@RequestMapping("/hello")
public class HelloController {
@RequestMapping("/query")
public String query(){
System.out.println("执行【HelloController】的【query】方法!!!");
return "/index.jsp";
}
}
2.3 运行测试
3. SpringMVC中响应请求的方式
3.1 不响应
如果用户提交了请求后服务端不需要给客户端一个响应,那么我们可以指定返回类型为void
同时在方法头部添加@ResponseBody
注解即可
@RequestMapping("/save")
@ResponseBody
public void add(){
System.out.println("执行【HelloController】的【save】方法!!!");
}
3.2 通过字符串返回指定页面
我们可以在处理方法的最后返回一个要跳转的页面地址”/“不要漏了
@RequestMapping("/query")
public String query(){
System.out.println("执行【HelloController】的【query】方法!!!");
return "/index.jsp";
}
3.2.1 通过视图解析器添加前后缀
在Spring配置文件中添加视图解析器
<!-- 配置视图解析器 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" >
<property name="suffix" value=".jsp"/>
<property name="prefix" value="/" />
</bean>
响应页面时,可以用以下方式简写
@RequestMapping("/query")
public String query(){
System.out.println("执行【HelloController】的【query】方法!!!");
return "index";
}
3.3 通过ModelAndView返回
ModelAndView是SpringMVC自带的组件,通过该组件可以返回指定的页面,并且可以绑定返回的参数。
@RequestMapping("/delete")
public ModelAndView delete(){
System.out.println("执行【HelloController】的【delete】方法!!!");
ModelAndView mm = new ModelAndView();
mm.setViewName("/index.jsp");
return mm;
}
3.4 通过重定向跳转
@RequestMapping("/update")
public String update(){
System.out.println("执行【HelloController】的【update】方法!!!");
return "redirect:/hello/query";
}
3.5 通过HttpServletResponse响应
@RequestMapping("/fun1")
public void fun1(HttpServletRequest request,
HttpServletResponse response) throws Exception {
System.out.println("执行【HelloController】的【fun1】方法!!!");
request.getRequestDispatcher("/index.jsp").forward(request,response);
}
4. SpringMVC接收请求数据
4.1 基本数据类型
直接在形参中声明要接收的数据,默认情况下前台传来的参数名必须和形参的名称保持一致,可以使用@RequestParam注解指定相关的属性。
@RequestMapping("/query")
public String query(@RequestParam(value = "ids",required = true,defaultValue = "123")Integer id,
String name){
System.out.println("执行【HelloController】的【query】方法!!!");
System.out.println("接收到的参数ids:" + id + ",name:" + name);
return "index";
}
4.2 对象接收
使用自定义对象接收时,参数的名称需要与对象的名称保持一致,并且需要提供对应的setter方法。
@RequestMapping("/save")
@ResponseBody
public void add(UserPojo userPojo){
System.out.println("执行【HelloController】的【save】方法!!!");
System.out.println("接收到的参数:" + userPojo);
}
4.3 通过数组接收
http://localhost:8082/hello/delete?ids=1,2,3,4
@RequestMapping("/delete")
public ModelAndView delete(String[] ids){
System.out.println("执行【HelloController】的【delete】方法!!!");
System.out.println("接收到的参数:" + Arrays.toString(ids));
ModelAndView mm = new ModelAndView();
mm.setViewName("index");
return mm;
}
4.4 通过集合接收
在形参中不能使用集合接收参数,但是可以把集合封装在自定义对象中用来接收。
package com.wxw.pojo;
import java.util.List;
@Data
public class UserPojo {
private String name;
private Integer age;
private List<String> catNames;
@Override
public String toString() {
return "UserPojo{" +
"name='" + name + '\'' +
", age=" + age +
", catNames=" + catNames +
'}';
}
}
@RequestMapping("/update")
public String update(UserPojo userPojo){
System.out.println("执行【HelloController】的【update】方法!!!");
System.out.println("接收到的参数:" + userPojo);
return "redirect:/hello/query";
}
执行【HelloController】的【update】方法!!!
接收到的参数:UserPojo{name='wangmian', age=20, catNames=[溜溜, 琉璃]}
4.5 自定义转换器
如果客户端传入的是特殊类型的数据,SpringMVC默认提供的转换器无法支持,则可以使用自定义转换器。
package com.wxw.convert;
import org.springframework.core.convert.converter.Converter;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 自定义日期转换器
*/
public class DateConvert implements Converter<String, Date> {
@Override
public Date convert(String s) {
System.out.println("进入【DateConvert】自定义转换器!!!");
SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd");
try {
return sf.parse(s);
} catch (Exception e){
System.out.println("日期类型格式错误!!!");
e.printStackTrace();
}
return null;
}
}
修改配置文件
<!-- 开启SpringMVC注解的使用 -->
<mvc:annotation-driven conversion-service="dateConvert" />
<!-- 配置自定义转换器 -->
<bean id="dateConvert" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.wxw.convert.DateConvert"/>
</set>
</property>
</bean>
5. SpringMVC返回响应数据
5.1 ModelAndView返回数据
@RequestMapping("/hello")
public ModelAndView hello(String name) {
System.out.println("进入【HelloController】的【hello】方法!!!");
ModelAndView mv = new ModelAndView();
// 指定返回的页面名称
mv.setViewName("user");
// 添加返回的数据
mv.addObject("msg",name);
return mv;
}
返回的页面使用EL表达式绑定返回的数据
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>Title</title>
</head>
<body>
hello<br>
${msg}
</body>
</html>
5.2 Map对象返回数据
@RequestMapping("mapHello")
public String mapHello(Map<String,Object> map,String name){
System.out.println("进入【HelloController】的【mapHello】方法!!!");
map.put("msg",name);
return "user";
}
5.3 Model对象返回数据
@RequestMapping("modelHello")
public String modelHello(String name, Model model){
System.out.println("进入【HelloController】的【modelHello】方法!!!");
model.addAttribute("msg",name);
return "user";
}
5.4 ModelMap对象返回数据
@RequestMapping("modelMapHello")
public String modelMapHello(String name, ModelMap modelMap){
System.out.println("进入【HelloController】的【modelMapHello】方法!!!");
modelMap.put("msg",name);
return "user";
}
5.5 返回响应数据的作用域
默认情况下返回的数据都是保存在request作用域中的,如果需要将数据保存在session作用域中,只需要在类的头部添加@SessionAttributes注解即可。
@Controller
@RequestMapping("/hello")
@SessionAttributes({"msg"})
public class HelloController {
}
5.6 响应数据乱码问题
<filter>
<filter-name>encodeFiletr</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>forceRequestEncoding</param-name>
<param-value>true</param-value>
</init-param>
<init-param>
<param-name>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodeFiletr</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
6. SpringMVC文件上传
6.1 引入依赖
<!-- fileUpload 解析上传的文件用到的jar -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
6.2 上传页面
文件上传必须使用multipart方式提交
<html>
<body>
<h2>Hello World!</h2>
<form action="/user/save" method="post" enctype="multipart/form-data">
姓名:<input type="text" name="name"><br>
头像:<input type="file" name="file"><br>
<input type="submit" value="提交">
</form>
</body>
</html>
6.3 处理器
提交的文件我们可以通过 MultipartFile
类型来接收
@RequestMapping("fileUpload")
public String fileUpload(MultipartFile file,String name) throws IOException {
System.out.println(name);
System.out.println("文件名称:" + file.getOriginalFilename());
file.transferTo(new File("d:/" + file.getOriginalFilename()));
return "index";
}
6.4 Spring配置文件
<!-- 文件上传的解析器-->
<bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver" id="multipartResolver">
<property name="maxUploadSize">
<value>5242880</value>
</property>
</bean>
7. SpringMVC文件下载
@RequestMapping("fileDownload")
public void fileDownload(HttpServletRequest request,
HttpServletResponse response) {
File file = new File("d://IMG_4942.JPG");
// 设置响应的头和客户端保存文件名
response.setCharacterEncoding("utf-8");
response.setContentType("multipart/form-data");
response.setHeader("Content-Disposition","attchement;filename=" + file.getName());
try {
// 打开本地文件流
InputStream in = new FileInputStream(file);
// 激活下载的流
ServletOutputStream out = response.getOutputStream();
byte[] b = new byte[1024];
int num = 0;
while ((num = in.read(b)) != -1){
out.write(b,0,num);
}
out.close();
in.close();
}catch (Exception e){
e.printStackTrace();
}
}
8. SpringMVC访问静态资源
8.1 重新制定Servlet
默认情况下SpringMVC只能访问jsp页面,其他的都会被DispatchServlet拦截,是因为DispatchServlet配置的时候用的/
覆盖掉了defaultServlet所做的工作,所以我们只需要重新制定即可。
<filter-mapping>
<filter-name>encodeFiletr</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.html</url-pattern>
</servlet-mapping>
8.2 在配置文件中指定映射规则
<mvc:resources mapping="/img/**" location="/img/" />
9. SpringMVC中处理JSON数据
9.1 添加依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.9.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.9.8</version>
</dependency>
9.2 返回JSON数据
返回JSON数据的方法必须使用@ResponseBody注解修饰
@RequestMapping("/queryList")
@ResponseBody
public List<String> queryList(){
System.out.println("queryList....");
return Arrays.asList("111","222","333");
}
9.3 接收JSON数据
页面提交请求必须为Post,控制器接收的参数必须使用@RequestBody注解修饰
@RequestMapping("/getJson")
@ResponseBody
public UserPojo getJson(@RequestBody UserPojo userPojo){
System.out.println(userPojo);
return userPojo;
}
10. SpringMVC拦截器
自定义拦截器,实现HandlerInterceptor接口
package com.wxw.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class MyInterceptor implements HandlerInterceptor {
/**
* 在自定义控制器执行之前执行
* @param request
* @param response
* @param handler
* @return
* false 拦截
* true 放过
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("preHandle...");
return true;
}
/**
* 自定义控制器执行后执行
* 在返回ModelAndView之前执行
* @param request
* @param response
* @param handler
* @param modelAndView
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("postHandle...");
}
/**
* 自定义控制器执行后执行
* 在返回ModelAndView之后执行
* @param request
* @param response
* @param handler
* @param ex
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("afterCompletion...");
}
}
在Spring配置文件中注册拦截器
<!-- 配置拦截器 -->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.wxw.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>