SpringMVC
Spring5.x要求tomcat版本至少是为8.5,一般使用Maven引入spring-webmvc就会将Web模块引入,切记将javax包排除,也就是将Tomcat中有的包排除
在引入IOC和AOP模块的基础上在引入Web模块
基本使用
在web.xml
中配置SpringMVC提供的前端控制器DispatcherServlet
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param> <!--配置Spring全局配置文件的位置,当该类被加载时会自动创建IOC容器-->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup> <!--让SpringIOC容器预加载-->
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern> <!--让Spring的前端控制器拦截所有请求-->
</servlet-mapping>
<!--
Tomcat默认有一个servlet是用于处理静态资源的,默认是匹配路径 / ,所以优先级最低,
也可以覆盖此配置达到排除静态资源的目的
-->
<!--<servlet-mapping>-->
<!-- <servlet-name>default</servlet-name>-->
<!-- <url-pattern>/static/*</url-pattern>-->
<!--</servlet-mapping>-->
再在Spring全局配置文件applicationContext.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"
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">
<!--
首先添加 xmlns:mvc="http://www.springframework.org/schema/mvc" 约束文件
再在 xsi:schemaLocation属性后增加 http://www.springframework.org/schema/mvc https://www.springframework.org/schema/mvc/spring-mvc.xsd
之后使用下面标签才能有代码提示
-->
<context:component-scan base-package="com"/> <!--开启IOC注解扫描-->
<mvc:annotation-driven/> <!--开启SpringMVC注解开发模式-->
<mvc:default-servlet-handler/> <!--在使用DispatcherServlet前端控制器拦截时,将静态资源排除在外-->
<!-- <mvc:resources mapping="/static/**" location="/static/"/> -->
<!--resources标签也可以指定静态资源,以/static路径开头的,可访问/webapp/static目录-->
</beans>
在类中使用注解,具体如下
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller //交由spring容器管理该类对象
public class Main {
@RequestMapping(value = "/test", method = RequestMethod.GET) //定义请求映射,若不指定请求方法则任意请求都可以
@ResponseBody //该方法的返回值直接返回
public String test() {
return "Hello world";
}
}
URL映射
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/prefix") //通常RequestMapping作用于类上,用于定义请求路径前缀
public class Main {
@GetMapping("/get") //get请求
@ResponseBody
public String get() {
return "get method";
}
@PostMapping("/post") //post请求
@ResponseBody
public String post() {
return "post method";
}
@PutMapping("/put") //put请求
@ResponseBody
public String put() {
return "put method";
}
@DeleteMapping("/delete") //delete请求
@ResponseBody
public String delete() {
return "delete method";
}
}
请求参数
当有多个请求参数时,使用键值对都是String类型的Map进行接收,即可自动将其封装成Map对象
queryString请求参数
作用与Get请求,当请求参数与方法参数数据类型不一样时,SpringMVC会自动转化,数据类型校验应该在前端进行,否则可能会出现类型转化异常的400客户端错误
简单参数
- 请求参数与方法的参数一一对应即可
- 若该参数有多个值,可使用List集合进行接收
- 若请求参数与方法参数不能一一对应时,可使用
@RequestParam
注解进行对应,若此参数不是必须的,就将该注解的required
设置为fasle
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class Main {
@GetMapping("/test1")
@ResponseBody
public String test1(Integer id) { //请求参数与方法参数一一对应,数据类型自动转化
return "id: " + id;
}
@GetMapping("/test2")
@ResponseBody
public String test2(@RequestParam("abc") String id) {
//使用@RequestParam注解手动对应,默认是必须参数,未传入参数时会报错
return "abc: " + id;
}
@GetMapping("/test3")
@ResponseBody
public String test3(@RequestParam(value = "abc", required = false) String id) {
//使用@RequestParam注解手动对应,可设置非必须参数,未传入参数时该参数值为null,
return "abc: " + id;
}
}
使用下面JSP页面进行测试
<a href="${pageContext.request.contextPath}/test1?id=1">/test1?id=1</a><br>
<a href="${pageContext.request.contextPath}/test2?abc=1">/test2?abc=1</a><br>
<a href="${pageContext.request.contextPath}/test3">/test3</a><br>
对象参数
- 对于方法参数是复杂类型时,请求参数与对象属性一一对应即可,对象属性还是对象时支持级联方式进行对应(强制要求,无法使用
@RequestParam
注解) - 若方法参数既有复杂数据类型又有简单数据类型,并且还有冲突的情况下,SpringMVC会同时注入两个值
- 该对象也可以是Map数据结构,会依次解析成Map中的键值对
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
class Student {
private String id;
private String name;
//setter getter toString 省略
}
@Controller
public class Main {
@GetMapping("/test1")
@ResponseBody
public String test1(Student student) { //请求参数与对象属性一一对应
return "student: " + student;
}
@GetMapping("/test2")
@ResponseBody
public String test2(Student student, String id) { //冲突情况下,同时注入两个值
return "student: " + student + " | id: " + id;
}
}
使用下面JSP页面进行测试
<a href="${pageContext.request.contextPath}/test3?id=1&name=zs">/test3?id=1&name=zs</a><br>
<a href="${pageContext.request.contextPath}/test4?id=1&name=zs">/test4?id=1&name=zs</a>
path请求参数
@Controller
public class Main {
@GetMapping("/test/{id}") //使用花括号包裹路径请求参数
@ResponseBody
public String test(@PathVariable("id") Integer id) { //使用@PathVariable注解对应路径请求参数
return "id: " + id;
}
}
使用下面JSP页面进行测试
<a href="${pageContext.request.contextPath}/test/1">/test/1</a>
queryBody请求参数
请使用至少2.9.x版本,因为之前的版本与MySQL同时使用时存在很严重的安全隐患
作用与Post请求,为了将JSON数据转化为Java对象,首先需要引入JSON序列化包jackson-databind
,之后不需要任何配置,因为Spring全局配置文件中配置过<mvc:annotation-driven/>
注解开发模式,由SpringMVC自动创建该类中的转换器对象(该包转换器类实现了HttpMessageConverter
接口,转化返回值类型),所以就会自动转化
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>x.x.x</version>
</dependency>
参数上使用@RequestBody
注解,该组件会自动将JSON格式字符串序列化成Java对象
package work.nobility.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Map;
class User {
private Integer id;
//setter getter toString 省略
}
@Controller
public class Main {
@PostMapping("/test1")
@ResponseBody
public String test1(@RequestBody User user) {
return user.toString();
}
@PostMapping("/test2")
@ResponseBody
public String test2(@RequestBody Map<String,Object> map) {
return map.toString();
}
}
Http请求元信息
@Controller
public class Main {
@GetMapping("/test1")
@ResponseBody
public String test(@RequestHeader("User-Agent") String userAgent) { //使用@RequestHeader注解获取对应请求头信息
return "userAgent: " + userAgent;
}
@GetMapping("/test2")
@ResponseBody
public String test(@CookieValue("Idea-efd34b6e") Cookie cookie) { //使用@CookieValue注解对应路Cookie对象,这里使用的是开发工具自带的Cookie
return "cookie: " + cookie.getValue();
}
}
使用下面JSP页面进行测试
<a href="${pageContext.request.contextPath}/test1">/test1</a><br>
<a href="${pageContext.request.contextPath}/test2">/test2</a>
使用ServletAPI
若是Maven项目,需要引入
javax.servlet-api
包,注意要将依赖范围设置为provided
,因为这些类型参数是该包中的类
在方法的参数列表中定义HttpServletRequest
、HttpServletResponse
、HttpSession
类型的参数,SpringMVC会根据类型自动注入这些参数,直接使用即可
对于请求转发可使用@RequestAttribute
注解快速获取
@Controller
public class Main {
@GetMapping("/test1")
@ResponseBody
public String test(HttpServletRequest request, HttpServletResponse response, HttpSession session) {
System.out.println(request);
System.out.println(response);
System.out.println(session);
return "hello world";
}
@GetMapping("/test2")
public String test2(HttpServletRequest request) {
request.setAttribute("message", "hello world"); //设置请求参数
return "/test3"; //未加@ResponseBody注解,会进行请求转发到test3地址上
}
@GetMapping("/test3")
@ResponseBody
public String test3(@RequestAttribute("message") String message) {
return "test3: " + message;
}
}
响应结果
我所探测到的,支持返回String、ModeAndView、void,ResponseEntity和普通对象类型,若返回其他类型抛出异常,若非要返回其他类型数据可能就需要手写解析器了,比如JSON解析器
返回String类型
- 使用
@ResponseBody
注解,表示该方法直接产生响应体数据,不经过视图,用于生成JSON等结构化字符串 - 在类上使用
@RestController
注解代替@Controller
注解,表示该类下的所有方法都会直接返回字符串 - 若不使用
@ResponseBody
和@RestController
注解,直接返回的字符串会被当成请求转发的视图页面
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Controller
//@RestController
public class Main {
@GetMapping("/test1")
@ResponseBody
public String test1(Integer id) {
return "id: " + id;
}
@GetMapping("/test2")
public String test2(HttpServletRequest request) {
request.setAttribute("id", 1);
return "/index.jsp"; //请求转发到index.jsp
}
@GetMapping("/test3")
public String test3() {
return "redirect:/index.jsp"; //使用 redirect: 前缀表示重定向
}
}
使用下面jsp页面进行测试
<a href="${pageContext.request.contextPath}/test1?id=1">/test1?id=1</a><br>
<a href="${pageContext.request.contextPath}/test2">/test2</a><br>
<a href="${pageContext.request.contextPath}/test3?id=1">/test3?id=1</a><br>
<h2>id: ${requestScope.id}</h2>
返回ModelAndView类型
- 方法返回ModelAndView对象,可向视图中绑定数据,ModelAndView是SpringMVC提供的一个类
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class Main {
@GetMapping("/test1")
public ModelAndView test1(Integer id) {
ModelAndView modelAndView = new ModelAndView("/index.jsp"); //若视图不使用斜杠开头表示使用该类的路径前缀做前缀
//modelAndView.setViewName("/view.jsp"); //也可使用该方法修改视图
modelAndView.addObject("id", id); //默认将属性加入到请求对象上
return modelAndView; //返回ModelAndView对象,默认是请求转发方式
}
@GetMapping("/test2")
public ModelAndView test2(Integer id) {
ModelAndView modelAndView = new ModelAndView("redirect:/index.jsp"); //使用 redirect: 表示重定向
modelAndView.addObject("id", id); //重定向,由于是新的请求,所以该数据无法传递到视图
return modelAndView;
}
}
使用下面jsp页面进行测试
<a href="${pageContext.request.contextPath}/test1?id=1">/test1?id=1</a><br>
<a href="${pageContext.request.contextPath}/test2?id=1">/test2?id=1</a><br>
<h2>id: ${requestScope.id}</h2>
返回普通对象类型
请使用至少2.9.x版本,因为之前的版本与MySQL同时使用时存在很严重的安全隐患
默认调用对象的toString()
方法,为了返回JSON数据,首先需要引入JSON序列化包jackson-databind
,之后不需要任何配置,因为Spring全局配置文件中配置过<mvc:annotation-driven/>
注解开发模式,由SpringMVC自动创建该类中的转换器对象(该包转换器类实现了HttpMessageConverter
接口,转化返回值类型),所以就会自动转化
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>x.x.x</version>
</dependency>
在控制器上类中使用@ResponseBody
或@RestController
注解,并且方法中返回对象时(List集合会转化成JavaScript数组),该组件会自动序列化成JSON格式字符串
下面是简单使用,默认情况下对于时间类型返回的是时间戳,若不想返回时间戳可使用@JsonFormat
注解进行格式化(同时设置时区),该注解也可以格式化数字
package com;
import com.fasterxml.jackson.annotation.JsonFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.Date;
class Student {
private Integer id;
private String name;
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS", timezone = "GMT+8")
private Date birthday;
//setter getter toString 省略
}
@Controller
public class Main {
@GetMapping("/test")
@ResponseBody
public Student test() {
Student student = new Student();
student.setId(1);
student.setName("zs");
student.setBirthday(new Date());
return student;
}
}
返回void类型
使用Servlet中的请求响应对象手动转发
package com;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@Controller
public class Main {
@GetMapping("/test1")
public void test1(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setAttribute("id", 1);
request.getRequestDispatcher("/index.jsp").forward(request, response);
}
@GetMapping("/test2")
public void test2(HttpServletRequest request, HttpServletResponse response) throws IOException {
request.setAttribute("id", 1);
response.sendRedirect(request.getContextPath() + "/index.jsp");
}
}
使用下面jsp页面进行测试
<a href="${pageContext.request.contextPath}/test1">/test1</a><br>
<a href="${pageContext.request.contextPath}/test2">/test2</a><br>
<h2>id: ${requestScope.id}</h2>
返回ResponseEntity类型
用于自定义HTTP响应
package com;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
@RestController
public class Main {
@GetMapping("/test")
public ResponseEntity<String> get() { //泛型指定返回类型,泛型也是普通对象,与直接返回普通对象一致
HttpHeaders headers = new HttpHeaders(); //创建响应头
headers.setContentType(MediaType.APPLICATION_JSON); //指定媒体类型
HttpStatus status = HttpStatus.resolve(200); //创建响应状态码
return ResponseEntity //返回响应对象
.status(status) //指定http响应状态码
.headers(headers) //指定http响应头
.body("请求体"); //指定http响应体,对应ResponseEntity的泛型
}
}
异常处理器
在异常处理器类上使用@ControllerAdvice
注解,异常处理器方法上使用@ExceptionHandler
注解指定要处理的异常,之后在控制器中抛出异常时,异常处理器中匹配的方法就会执行
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class MyException {
@ExceptionHandler(value = {Exception.class}) //数组形式,可指定多个异常
@ResponseBody
public String error(Exception e) { //与控制器中的方法用法一致
return "出现异常" + e.getMessage();
}
}
拦截器
若是Maven项目,需要引入
javax.servlet-api
包,注意要将依赖范围设置为provided
,因为拦截器中的参数需要用到该包中的类
自定义类实现HandlerInterceptor
接口,重写preHandle()
、postHandle()
和afterCompletion()
方法,这三个方法都是默认方法
preHandle()
:前置执行处理,进入控制器之前执行,若返回false则后续不会执行postHandle()
:目标资源已被SpringMVC进行处理,即控制器方法被执行完(return了之后)后执行afterCompletion()
:响应文本已产生,即响应HTML字符串或JSON字符串生成后执行
同时设置多个拦截器的执行顺序为,请求时按照配置顺序进行执行,响应时按照配置逆序执行,若期间某个拦截器出现了异常,则后续拦截器不会被执行,而是直接逆序执行
afterCompletion()
方法,而不会执行postHandle()
方法
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("前置处理");
return true; //返回true后续会接着执行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("控制器方法执行完毕");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("响应文本已经生成");
}
}
之后再在Spring全局配置文件applicationContext.xml
中添加下面配置,但是要注意<mvc:default-servlet-handler/>
设置对拦截器是不起作用的,静态资源还是会被拦截器拦截到
<mvc:interceptors> <!--设置SpringMVC拦截器,-->
<mvc:interceptor> <!--设置单个拦截器,可设置多个拦截器-->
<mvc:mapping path="/**"/> <!--拦截的路径,可是设置多个-->
<mvc:exclude-mapping path="/**.jsp"/> <!--不拦截的路径,可是设置多个-->
<bean class="com.MyInterceptor"/> <!--拦截器类-->
</mvc:interceptor>
</mvc:interceptors>
使用下面代码进行测试
public class Main {
@GetMapping("/test")
@ResponseBody
public String test() {
System.out.println("控制器中的方法");
return "test";
}
}
SpringMVC处理流程
解决常见问题
格式转化器
局部日期格式转化
@Controller
public class Main {
@GetMapping("/test")
@ResponseBody
public String test(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS") Date date) {
return "date: " + date;
}
}
//用于测试的连接
//<a href="${pageContext.request.contextPath}/test?date=1970-01-01 00:00:00.000">/test?date=1970-01-01 00:00:00.000</a>
全局日期格式转化
自定义格式转化器,实现Converter
接口,重写convert()
方法,优先级低于局部日期转化,这只是个示例,自定义转换器可用于任意类型的转化
import org.springframework.core.convert.converter.Converter;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateConverter implements Converter<String, Date> { //实现Converter接口,泛型表示将String转化为Date类型
@Override
public Date convert(String string) {
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
try {
return simpleDateFormat.parse(string); //返回转化后的日期对象
} catch (ParseException e) {
return null; //解析错误返回null
}
}
}
再在Spring全局配置文件applicationContext.xml
中更新下面配置
<context:component-scan base-package="com"/>
<mvc:annotation-driven conversion-service="FormattingConversionServiceFactoryBean"/> <!--指定转换器工厂,之后遇到转换器能转化的就会使用转换器转化-->
<mvc:default-servlet-handler/>
<bean id="FormattingConversionServiceFactoryBean" class="org.springframework.format.support.FormattingConversionServiceFactoryBean"> <!--创建转换器工厂-->
<property name="converters"> <!--注入自定义转化器-->
<set>
<bean class="com.DateConverter"/>
</set>
</property>
</bean>
解决中文乱码
请求中的中文乱码
对于Get请求,Tomcat8及以上版本Get请求参数默认就是UTF-8,Tomcat7需要在Tomcat的server.xml配置文件中找到这项配置:<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" />
,添加一个属性字段URLEncoding="UTF-8"
,改为这样<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URLEncoding="UTF-8" />
即可
对于Post请求,需要在web.xml
中配置SpringMVC提供的字符编码过滤器即可,具体如下
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param> <!--配置字符编码为UTF-8-->
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern> <!--拦截所有请求-->
</filter-mapping>
响应中的中问乱码
局部解决
在URL映射注解中设置produces
属性,可指定Context-Text的值,以@RequestMapping
注解为例,因为可添加到类上
@RequestMapping(produces = "text/html;charset=utf-8")
全局解决
在Spring全局配置文件applicationContext.xml
中更新下面配置
<context:component-scan base-package="com"/>
<mvc:annotation-driven> <!--开启此标签的双标签模式-->
<mvc:message-converters>
<bean class="org.springframework.http.converter.StringHttpMessageConverter"> <!--指定消息转换器-->
<property name="supportedMediaTypes"> <!--注入支持的媒体类型-->
<list>
<value>text/html;charset=utf-8</value> <!--html类型-->
<value>application/json;charset=utf-8</value> <!--json类型-->
</list>
</property>
</bean>
</mvc:message-converters>
</mvc:annotation-driven>
<mvc:default-servlet-handler/>
解决非简单请求接收不到参数问题
需要在web.xml
中配置SpringMVC提供的表单内容过滤器即可,具体如下
<filter>
<filter-name>formContentFilter</filter-name>
<filter-class>org.springframework.web.filter.FormContentFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>formContentFilter</filter-name>
<url-pattern>/*</url-pattern> <!--拦截所有请求-->
</filter-mapping>
解决跨域请求
局部注解方式
在控制器类上使用@CrossOrigin
注解,表示该类下的所有映射的URL都支持跨域请求,具体使用如下
@CrossOrigin(origins = {"http://www.baidu.com"}) //origins是一个数组,可指定多个域名
//@CrossOrigin(origins = "*") //也可使用星号通配符进行全部放行
//@CrossOrigin(origins = {"http://www.baidu.com"},maxAge = 3600) //maxAge属性表示缓存预检请求缓存时间,可减请服务器的压力,单位秒
@RestController
public class Main {
//...
}
全局xml方式
在Spring全局配置文件applicationContext.xml
中添加下面配置
<mvc:cors>
<mvc:mapping path="/prefix/**" allowed-origins="http://www.baidu.com" max-age="3600"/>
<!--path属性决定了哪些请求路径可以跨域访问,/prefix/** 代表 prefix 父路径下的所有路径-->
<!--allowed-origins中多个域名使用逗号分隔即可-->
</mvc:cors>
整合Freemarker
引入freemarker
包和spring-context-support
整合包
在Spring全局配置文件applicationContext.xml
中添加下面配置
<bean id="freeMarkerViewResolver" class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
<property name="contentType" value="text/html;charset=utf-8"/> <!--设置contentType-->
<property name="suffix" value=".ftl"/> <!--指定FreeMarker模板文件的后缀名,在程序中就可省略后缀名-->
</bean>
<bean id="freeMarkerConfigurer" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
<property name="templateLoaderPath" value="/WEB-INF/ftl"/> <!--指定模板文件目录,若代码中不想使用该目录,添加 forward: 前缀即可-->
<property name="freemarkerSettings">
<props>
<prop key="defaultEncoding">UTF-8</prop> <!--指定Freemarker脚本与数据渲染时使用的字符集-->
</props>
</property>
</bean>
使用下面代码测试
@Controller
public class Main {
@GetMapping("/test")
public ModelAndView test(Integer id) {
ModelAndView modelAndView = new ModelAndView("/index");
//无需添加后缀,以为已经配置过,并且 / 根对应模板文件根目录
modelAndView.addObject("id", id);
return modelAndView;
///index.ftl中内容为:<h1>${id}</h1>
}
}
Comments NOTHING