SpringMVC
1、SpringMVC日期转换器
SpringMVC不知道日期的格式,不写日期转换器将会出现日期格式未知,从而报400错误,这也是常见的参数异常错误。
1.1、方法一
1、如果查询类让我们自己写,那么在属性前面加上@DateTimeFormat(pattern = “yyyy-MM-dd”) ,即可将String转换为Date类型,如下
@DateTimeFormat(pattern = "yyyy-MM-dd")
private Date createTime;
1.2、方法二
自定义日期转换器实现
1、创建自定义日期转换类,需要实现Converter抽象类
2、自定义日期转换
package com.yxun8.converter;
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 定义时间转换器springmvc
* Converter<S, T>
* S:source要转换的源类型
* T:target 要转换成的数据类型
* @author
*
*/
public class MyDateConverter implements Converter<String, Date> {
@Override
public Date convert(String s) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
try {
Date date = sdf.parse(s);
return date;
} catch (ParseException e) {
return null;
}
}
}
3、告诉springmvc自己定义的日期格式
在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:aop="http://www.springframework.org/schema/aop"
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/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd">
<!--开启注解扫描-->
<context:component-scan base-package="com.yxun8"/>
<!--开启SpringMVC注解开发,使用自定义日期转换器-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean"/>
<!--可以理解为排除html/css/js各种静态文件,因为springmvc设置拦截方式为/,所以所以的请求都会被拦截-->
<mvc:default-servlet-handler/>
<!--日期转换器的配置-->
<bean id="conversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="com.yxun8.converter.MyDateConverter"/>
</set>
</property>
</bean>
</beans>
注意:日期格式出错是一件比较复杂的事情,关键是你不知道是日期参数出错,所以当springmvc遇到400错误,首先考虑参数错误,如果有时间入库操作,此时得考虑日期格式出错,日期转换器就用上了。
2、SpringMVC解决中文乱码问题
2.1、解决post请求乱码
<!--解决post请求中文乱码的拦截器-->
<filter>
<filter-name>encodingFilter</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>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
2.2、解决response响应的中文乱码
<!--开启SpringMVC注解开发,使用自定义日期转换器-->
<mvc:annotation-driven conversion-service="conversionServiceFactoryBean">
<!--解决response响应的中文乱码-->
<mvc:message-converters>
<bean id="converter" class="org.springframework.http.converter.StringHttpMessageConverter">
<property name="supportedMediaTypes">
<list>
<value>text/html;charset=utf-8</value>
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
3、SpringMVC整合Freemarker
1.导入依赖
<!--整合FreeMarker所需依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.30</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.3.3</version>
</dependency>
2.编写xml配置文件
<!--告诉springmvc我要用的模板引擎是freemarker-->
<bean id="viewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<!--产生结果以后,向客户端输出内容的字符集-->
<property name="contentType" value="text/html;charset=utf-8"/>
<property name="suffix" value=".ftl"/>
</bean>
<!--对freemarker自身进行配置-->
<bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl"/>
<property name="freemarkerSettings">
<props>
<!--产生最终结果时候的字符集-->
<prop key="defaultEncoding">UTF-8</prop>
</props>
</property>
</bean>
3.编写测试代码
@Controller
public class FreeMarkerController {
@GetMapping("/fm")
public String fm(Model model){
User user = new User();
user.setUsername("张三");
model.addAttribute("u",user);
return "/test";
}
}
4、配置SpringMVC支持复杂请求
因为SpringMVC默认只支持简单请求的get和post,所以对于put和delete只能在xml里面配置才能使用
<!--配置SpringMVC支持复杂请求的put和delete请求-->
<filter>
<filter-name>contentFilter</filter-name>
<filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>contentFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
5、JSON序列化
在SpringMVC中,使用jackson就能轻松的对java对象和集合进行序列化。
只需要简单的引入三个依赖就可以了
Jackson在处理日期时间上有点bug,需要在实体类的属性上面标明注解对日期时间进行格式化
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
注意:2.9以前的版本有漏洞问题
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.11.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.11.4</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.11.4</version>
</dependency>
6、SpringMVC中解决跨域问题
方式一:局限于每个Controller
/**
* 允许指定的域名跨域访问
*/
@CrossOrigin(origins = {"http://localhost:8080"})
方式二:全局配置
<!--解决跨域-->
<mvc:cors>
<!--path:对指定的路径允许外界跨域访问
allowed-origins:允许哪些域名跨域跨域
max-age:准备响应前的 缓存持续的 最大时间
-->
<mvc:mapping path="/**" allowed-origins="http://localhost:8080" max-age="3600"/>
</mvc:cors>
7、拦截器Interceptor的使用
1.拦截器相当于j2ee的过滤器,引入之前必须要依赖server.api的jar包
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
2.编写拦截器类
package com.yxun8.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 {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println(request.getRequestURL() + "-准备执行");
/*true:放行
* false:不放行,拦截
* */
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(request.getRequestURL() + "-方法执行结束,但还没有渲染数据");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(request.getRequestURL() + "-执行结束");
}
}
3.applicationContext.xml配置拦截器
<!--配置拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.yxun8.interceptor.MyInterceptor"/>
</mvc:interceptor>
</mvc:interceptors>
如何有多个Interceptor拦截器同时执行呢?
- 按照拦截器配置的先后顺序执行
- 响应的过程中按照倒序执行