一、域对象传值
1.1、Request域对象
有多种方式
// Servlet原生Api方式
@RequestMapping("/testRequestByServletApi")
public String testRequestByServletApi(HttpServletRequest request) {
request.setAttribute("testRequest", "hello, Servlet api");
return "success";
}
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView() {
ModelAndView view = new ModelAndView();
view.addObject("testRequest", "hello, ModelAndView");
view.setViewName("success");
return view;
}
@RequestMapping("/testModel")
public String testModel(Model model) {
model.addAttribute("testRequest", "hello, Model");
return "success";
}
@RequestMapping("/testMap")
public String testModel(Map<String, Object> map) {
map.put("testRequest", "hello, Model");
return "success";
}
@RequestMapping("/testModelMap")
public String testModel(ModelMap modelMap) {
modelMap.addAttribute("testRequest", "hello, ModelMap");
return "success";
}
1.2、Session域对象
对于session域对象,直接使用原生的ServletApi比较方便
@RequestMapping("/testSession")
public String testModel(HttpSession session) {
session.setAttribute("testRequest", "hello, session");
return "success";
}
二、视图解析器
InternalResourceView:用于转发
RedirectView:用于重定向
注:转发和重定向最主要区别,转发是一次http request请求,发生在服务端,而重定向是两次请求,由浏览器触发第二次。
@Controller
public class ViewController {
@RequestMapping("/testThymeleafView")
public String testThymeleafView() {
return "success";
}
@RequestMapping("/testForward")
public String testForward() {
return "forward:/testThymeleafView";
}
@RequestMapping("/testRedirect")
public String testRedirect() {
return "redirect:/testThymeleafView";
}
}
三、视图控制器
有些时候对于一个请求(如首页访问),并不需要通过代码做一些处理,这种情况下我们可以直接使用置视图控制器,进行简单配置,就可实现功能。
<mvc:view-controller path="/" view-name="index"></mvc:view-controller>
<mvc:annotation-driven/>
其中path表示访问路径,view-name表示视图名称,即html页面
annotation-driven是注解驱动,此配置项必须存在,否则代码中基于注解的访问方式都会失效
四、SpringMvc支持PUT\DELETE方式
由于form表单默认只支持GET\POST两种方式,SpringMvc提供了一个过滤器来间接实现PUT\DELETE。
4.1、配置过滤器
<!-- 支持PUT\DELETE 过滤器 -->
<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>
4.2、设置form表单
<form th:action="@{/user}" method="post">
<input type="hidden" name="omethod" value="put">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
<input type="submit" value="修改用户put">
</form>
4.3、请求处理
@RequestMapping(value = "/user", method = RequestMethod.PUT)
public String updateUser(String username, String password) {
System.out.println("update user:"+username+",password:"+password);
return "success";
}
五、HttpMessageConverter 报文转换器
用于将http request转成java对象或者将java对象转成http response。springmvc提供两个注解和两个类
@RequestBody | 将Request Body转换成String,用于标注在形参 |
@ResponseBody | 将java bean转成http response返回给浏览器,通常是方法的返回值,用于标注在方法上(也可以用于类上) |
RequestEntity | 用于获取http报文,包括请求头和请求体。用于声明控制器形参类型 |
ResponseEntity | 作为控制器方法的返回值,典型使用场景是文件上传与下载 |
5.1、导入依赖
springmvc默认使用jackson作为json转化
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.4</version>
</dependency>
<!-- 如果使用fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.70</version>
</dependency>
5.2、开启注解驱动
<mvc:annotation-driven/>
如果使用fastjson作为转换器,则需要这样配置
<mvc:annotation-driven>
<mvc:message-converters>
<bean class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter"/>
</mvc:message-converters>
</mvc:annotation-driven>
5.3、添加@ResponseBody注解
将java bean做为返回值,传给浏览器
@RequestMapping(value = "/testResponseUser", method=RequestMethod.GET)
@ResponseBody
public User testUser() {
System.out.println("testUser。。。。");
return new User(1001, "ZHANGSAN", "1234", "男");
}
六、文件上传与下载
6.1、下载
下载功能比较简单,代码如下:
/* 下载 */
@RequestMapping("/testDown")
public ResponseEntity<byte[]> testDown(HttpSession session) throws IOException {
ServletContext servletContext = session.getServletContext();
String path = servletContext.getRealPath("/statics/b.png");
InputStream inputStream = new FileInputStream(path);
byte[] data = new byte[inputStream.available()];
inputStream.read(data);
MultiValueMap<String, String> headers = new HttpHeaders();
headers.add("Content-Disposition", "attachment;filename=aa.png");
HttpStatus status = HttpStatus.OK;
ResponseEntity responseEntity = new ResponseEntity<byte[]>(data, headers, status);
inputStream.close();
return responseEntity;
}
6.2、上传
上传需要导入依赖并且配置文件上传解析器,具体如下:
6.2.1、依赖
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.3</version>
</dependency>
6.2.2、文件上传解析器
一定要指定id,否则springmvc不能获取到这个bean
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760000"></property>
<property name="maxInMemorySize" value="40960"></property>
</bean>
6.2.3、代码
<form action="/testUp" method="post" enctype="multipart/form-data">
用户名:<input type="text" name="username" value="1234">
文件:<input type="file" name="upFile"><br/>
<input type="submit" name="up" value="up">
</form>
/**
* 文件上传
* 1. commons-fileupload依赖
* 2. 配置文件上传解析器
* 3. 形参名字与表单中组件名称保持一致
*/
@RequestMapping(value = "/testUp", method = RequestMethod.POST)
public String testUp(MultipartFile upFile, HttpSession session) throws IOException {
String filename = upFile.getOriginalFilename();
String updir = session.getServletContext().getRealPath("updir"); //获取服务器路径
File dir = new File(updir);
if (!dir.exists()) {//不存在目录则创建
dir.mkdir();
}
File saveFile = new File(updir+File.separator+filename);
upFile.transferTo(saveFile);
return "success";
}
七、拦截器
拦截器也是可以拦截各种请求(与过滤器功能类似),拦截器(接口)提供了三个方法,三个方法执行时机如下图所示:
多个拦截器执行顺序:
1)所有preHandle方法都返回true
preHandle方法,按照注册顺序执行。postHandle、afterCompletion方法,按照注册顺序反向执行
2)preHandle方法返回false
postHandle方法不会被执行,但是afterCompletion方法会执行
具体可以参考HandlerExecutionChain类中方法:applyPreHandle、applyPostHandle、triggerAfterCompletion
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 拦截所有请求
<bean class="com.atguigu.interceptors.MyInterceptor"></bean>
-->
<mvc:interceptor>
<!-- 拦截首页之外的所有请求 -->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<bean class="com.atguigu.interceptors.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MyInterceptor---->preHandle");
return true; //返回true代表放行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MyInterceptor---->postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MyInterceptor---->afterCompletion");
}
}
八、异常处理器
springmvc提供两种方式用于定制化异常处理:一种是配置方式,一种是基于注解方式。
8.1、配置方式
在springmvc配置文件中增加异常处理器
<!-- 异常解析器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- key=异常全路径名称 算数异常 value=视图名字, 此处实际执行errors.html -->
<prop key="java.lang.ArithmeticException">errors</prop>
</props>
</property>
<!-- 将错误详细信息exceptionAttribute 放到请求域中,请求域key是exinfo -->
<property name="exceptionAttribute" value="exinfo"/>
</bean>
<!-- errors.html -->
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<h1>Errors</h1>
<p th:text="${exinfo}"></p>
</body>
</html>
@RequestMapping(value = "/testException", method = RequestMethod.GET)
public String testException() {
int a = 1;
int b = 0;
int c = a / b;
return "success";
}
8.2、基于注解方式异常处理
@ControllerAdvice
public class ExceptionController {
@ExceptionHandler(value = {ArithmeticException.class, NullPointerException.class})
public String errors(Model model, Exception ex) {
model.addAttribute("exinfo", ex);
return "errors";
}
}
九、SpringMvc基于注解方式开发
spring提供了一种基于注解方式来替换xml配置文件,那么springmvc也是支持的。下面来介绍一些类,来完成之前的基于xml配置的功能
9.1、继承AbstractAnnotationConfigDispatcherServletInitializer并实现抽象方法
这个实现类不需要任何注解进行标注,在启动时自动被加载
package com.atguigu.config;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.filter.HiddenHttpMethodFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
import javax.servlet.Filter;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
/**
* SpringMvc web工程初始化类,用于替换web.xml文件
*/
public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer {
/**
* 指定spring的配置类
* @return
*/
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{SpringConfig.class};
}
/**
* 指定springmvc的配置类
* @return
*/
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{SpringMvcConfig.class};
}
/**
* 指定DispatchServlet的映射规则,即url-pattern
* @return
*/
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//两个过滤器
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter filter = new CharacterEncodingFilter();
filter.setEncoding("UTF-8");
filter.setForceResponseEncoding(true);
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
return new Filter[]{filter, methodFilter};
}
}
9.2、SpringMvc配置类
用一个类来代表springmvc.xml配置文件,这个类需要用@Configuration进行标注
package com.atguigu.config;
import com.atguigu.config.com.atguigu.interceptor.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.multipart.MultipartResolver;
import org.springframework.web.multipart.commons.CommonsMultipartResolver;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.*;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.thymeleaf.spring5.ISpringTemplateEngine;
import org.thymeleaf.spring5.SpringTemplateEngine;
import org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver;
import org.thymeleaf.spring5.view.ThymeleafViewResolver;
import org.thymeleaf.templateresolver.ITemplateResolver;
import java.util.List;
import java.util.Properties;
/**
* 需要实现以下功能
* 1.包扫描 2.视图解析器 3.静态资源访问default-servlet-handler
* 4.视图控制器view-controller 5.开启注解驱动annotation-driven
* 6.异常处理器 7.拦截器 8.文件上传解析器
*
* 继承webmvcconfigure
*/
@Configuration
//1.包扫描
@ComponentScan("com.atguigu.controller")
//5.开启注解驱动annotation-driven
@EnableWebMvc
public class SpringMvcConfig implements WebMvcConfigurer {
//2.视图解析器
@Bean
public ITemplateResolver createTemplateResolver() {
SpringResourceTemplateResolver resolver = new SpringResourceTemplateResolver();
resolver.setPrefix("/WEB-INF/templates/");
resolver.setSuffix(".html");
resolver.setCharacterEncoding("UTF-8");
resolver.setTemplateMode("HTML5");
return resolver;
}
@Bean
public ISpringTemplateEngine createTemplateEngine(ITemplateResolver resolver) {
SpringTemplateEngine engine = new SpringTemplateEngine();
engine.setTemplateResolver(resolver);
return engine;
}
@Bean
public ViewResolver createViewResolver(ISpringTemplateEngine engine) {
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setOrder(1);
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(engine);
return viewResolver;
}
//3.静态资源访问default-servlet-handler 以下两种方式都可以
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
// @Override
// public void addResourceHandlers(ResourceHandlerRegistry registry) {
// registry.addResourceHandler("/statics/**").addResourceLocations("/statics/");
// }
// 4.视图控制器view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("index");
}
//6.异常处理器
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver resolver = new SimpleMappingExceptionResolver();
Properties props = new Properties();
props.setProperty("java.lang.ArithmeticException", "errors"); //key=异常全类名, value=视图名字
resolver.setExceptionAttribute("exinfo");
resolver.setExceptionMappings(props);
resolvers.add(resolver);
}
//7.拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/");
}
//8.文件上传解析器
@Bean
public MultipartResolver multipartResolver() {
CommonsMultipartResolver file = new CommonsMultipartResolver();
file.setDefaultEncoding("UTF-8");
file.setMaxUploadSize(10485760000L);
file.setMaxInMemorySize(40960);
return file;
}
}
十、SpringMvc常用配置
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_4_0.xsd"
version="4.0">
<!-- 编码过滤器 -->
<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>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- HiddenHttpMethodFilter -->
<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>
<!-- servlet -->
<servlet>
<servlet-name>DispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc04.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>DispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
springmvc配置文件
<?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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!-- 组件扫描 -->
<context:component-scan base-package="com.atguigu.controller"/>
<!-- 视图解析器 -->
<bean class="org.thymeleaf.spring5.view.ThymeleafViewResolver">
<property name="order" value="1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class="org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class="org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<property name="prefix" value="/WEB-INF/templates/"/>
<property name="suffix" value=".html"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateMode" value="HTML5"/>
</bean>
</property>
</bean>
</property>
</bean>
<!-- 开启静态资源访问 -->
<mvc:default-servlet-handler/>
<!-- 视图控制器 -->
<mvc:view-controller path="/" view-name="index"/>
<mvc:view-controller path="/file" view-name="file"/>
<!-- 开启注解驱动 -->
<mvc:annotation-driven>
<mvc:message-converters> <!-- 处理响应中文乱码问题 -->
<bean class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="defaultCharset" value="UTF-8"/>
<property name="supportedMediaTypes">
<list>
<value>text/html</value>
<value>application/json</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<!-- 文件上传解析器 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
<property name="maxUploadSize" value="10485760000"></property>
<property name="maxInMemorySize" value="40960"></property>
</bean>
<!-- 配置拦截器 -->
<mvc:interceptors>
<!-- 拦截所有请求
<bean class="com.atguigu.interceptors.MyInterceptor"></bean>
-->
<mvc:interceptor>
<!-- 拦截首页之外的所有请求 -->
<mvc:mapping path="/**"/>
<mvc:exclude-mapping path="/"/>
<bean class="com.atguigu.interceptors.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
<!-- 异常解析器 -->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- key=异常全路径名称 value=视图名字, 此处实际执行errors.html -->
<prop key="java.lang.ArithmeticException">errors</prop>
</props>
</property>
<!-- 将错误详细信息exceptionAttribute 放到请求域中,请求域key是exinfo -->
<property name="exceptionAttribute" value="exinfo"/>
</bean>
</beans>
以上是最近学习springmvc总结,作为一个备份吧。