1、默认:只要静态资源放在类路径下: called /static (or /public or /resources or /meta-INF/resources目录下;就可以:当前项目根路径/ + 静态资源名 。
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源也找不到则响应404页面。
2、改变默认的静态资源路径:
resources:
static-locations: [classpath:/myStatic/]
3、静态资源访问前缀:默认无前缀
修改静态资源访问前缀:
spring:
mvc:
static-path-pattern: /res/**
修改后访问路径例如:http://localhost:8080/res/desk.PNG
1.2 欢迎页阿1、 把index.html放在静态资源目录如static/
2、配置能处理欢迎页请求并转发到欢迎页的controller
favicon.ico 放在静态资源目录下即可。
2 请求处理 2.1 Rest映射及其分析Rest风格支持(使用HTTP请求方式动词来表示对资源的操作)
前端:
配置开启:(表单是post请求方式的开启filter才起作用)
spring:
mvc:
hiddenmethod: #开启rest风格表单
filter:
enabled: true
controller:
//@DeleteMapping("/user")
@RequestMapping(value = "/user",method= RequestMethod.PUT)
public String put(){
return "PUT!";
}
自定义filter:
//自定义filter
@Bean
public HiddenHttpMethodFilter hiddenHttpMethodFilter(){
HiddenHttpMethodFilter methodFilter = new HiddenHttpMethodFilter();
methodFilter.setMethodParam("_m");
return methodFilter;
}
2.2 请求参数绑定
2.2.1注解绑定参数
1、@PathVariable
@PathVariable的作用是将URL中占位符参数{xxx}绑定到处理器类的方法形参中两种方式如下:
测试
@RestController
public class ParamTestController {
@GetMapping("/user/{id}/{name}")
public Map pathVariable(@PathVariable("id") Integer id,
@PathVariable("name") String name,
@PathVariable Map pv){
System.out.println(id+name);
return pv;
}
}
2、@RequestParam
@RequestParam的作用是通过请求参数的名字把请求参数值绑定到处理器类的方法形参中: 测试 @GetMapping("/user/requestParam") public MaprequestParam(@RequestParam("id") Integer id, @RequestParam("inters") List inters, @RequestParam Map pv){ System.out.println(id); System.out.println(inters); return pv; }
3、@RequestHeader
@RequestHeader的作用是把请求头信息绑定到处理器类的方法形参中有四种方法:
1、lang.String
2、java.util.Map
3、org.springframework.util.MultiValueMap
4、org.springframework.http.HttpHeaders
@GetMapping("/user/requestHeader")
public Map requestHeader(@RequestHeader("User-Agent") String userAgent,
@RequestHeader Map header){
header.put("myUserAgent",userAgent);
return header;
}
4、@cookievalue
@cookievalue的作用是把cookie信息绑定到处理器类的方法形参中有2中方式:
1、lang.String
2、cookie对象
@GetMapping("/user/cookievalue")
public String cookievalue(@cookievalue("Idea-95086d05") String idea,
@cookievalue("Idea-95086d05") cookie cookie){
return idea+cookie.getValue();
}
5、@ResponseBody
@ResponseBody的作用是把请求体串绑定到处理器类的方法形参中
该注解只有一个boolean required() default 属性
@PostMapping("/user/requestBody")
public void requestBody(@RequestBody() String requestBody){
System.out.println(requestBody);
}
6、@RequestAttribute
@RequestAttribute的作用是请求转发后获取Request域对象的参数
@GetMapping("/user/requestAttribute")
public void requestAttribute(HttpServletRequest req, HttpServletResponse resp) throws Exception {
req.setAttribute("id","603");
req.setAttribute("name","cyt");
req.getRequestDispatcher("/user/receiveDispatch").forward(req,resp);
}
@GetMapping("/user/receiveDispatch")
public String receiveDispatch(@RequestAttribute("id")String id, HttpServletRequest req) {
return id+req.getAttribute("name");
}
7、@MatrixVariable
(1)矩阵变量:
根据 URI 规范 RFC 3986 中 URL 的定义,路径片段中可以包含键值对。规范中没有对应的术语…在 Spring MVC 它被成为矩阵变量。
矩阵变量增加了Spring @RequestMapping方法可以处理的URI的灵活性。例如
页面开发,cookie禁用了,session里面的内容无法获取;可以url重写:/abc;jsesssionid=xxxx 把cookie的值使用矩阵变量的方式进行传递
(2)带有矩阵变量请的请求url:
矩阵变量 矩阵变量
(3)url路径变量才可解析出路径片段中的矩阵变量:
1、SpringBoot默认是禁用了矩阵变量的功能 2、手动开启要定制化mvc组件即WebMvcConfigurer接口组件,在其configurPathMatch方法中 将UrlPathHelper的 removeSemicolonContent属性要设为false; (UrlPathHelper用于解析路径,其removeSemicolonContent属性默认true(移除分号内容)) 3、做法是WebMvcConfigurer接口组件注册进容器: 其一是@bean接口实现类,其二是配置类实现WebMvcConfigurer接口
注册定制化WebMvcConfigurer组件:
@Configuration(proxyBeanMethods = false)
public class WebConfig implements WebMvcConfigurer {
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
UrlPathHelper urlPathHelper = new UrlPathHelper();
// 不移除;后面的内容。矩阵变量功能就可以生效
urlPathHelper.setRemoveSemicolonContent(false);
configurer.setUrlPathHelper(urlPathHelper);
}
}
后端解析矩阵变量: @GetMapping("/user/{placeholder}/matrixVariable") public String matrixVariable(@MatrixVariable(value = "id",pathVar = "placeholder")String id, @MatrixVariable(value = "names",pathVar = "placeholder") Listnames) { return id+names.get(0)+names.get(1)+names.get(2); }
8、Map&Model
Spring MVC在内部使用了一个org.springframework.ui.Model接口存储模型数据
1、Spring MVC在调用处理器方法前会创建一个隐含的模型对象作为模型数据的存储容器。
2、如果方法的入参为Map,Model类型,Spring MVC会将隐含模型的引用传递给这些入参。在方法体内,开发者可以通过这个入参对象访问到模型中的所以数据,也可以向模型中添加新的属性数据。
3、可以用于向request域存取数据:
1、若请求转发是原生servlet,则 map.put("k1","v1")或model.addAttribute("k2","v2");无法向reques域存键值。
@GetMapping("/params")
public String testParam(Map map,
Model model,
HttpServletRequest request,
HttpServletResponse response){
map.put("k1","v1");
model.addAttribute("k2","v2");
request.setAttribute("k3","v3");
return "forward:/success";
}
--------------------------------------------------------------------------------
@ResponseBody
@GetMapping("/success")
public Map success(HttpServletRequest request){
Map map = new HashMap<>();
Object hello = request.getAttribute("k1");
Object world = request.getAttribute("k2");
Object message = request.getAttribute("k3");
}
3 响应请求
- 响应页面:后端渲染,前后端不分离,响应返回html、jsp等;
- 响应数据:前端渲染,前后端分离,响应返回json、xls、图片、音视频、自定义协议数据;
1、@ResponseBody概述:
调用不同的消息转换器响应不同的媒体类型如html、json、xml、x-cyt(自定义媒体类型),其中包括自动配置和自定义的消息转换器;
2、@ResponseBody基本使用
(1)引入支持xml响应场景,系统为其自动配置com.fasterxml.jackson.dataformat jackson-dataformat-xml
(2)开启请求参数内容协商功能后,默认的消息转换器仅支持请求参数format=json或format=xml来指定响应媒体类型
spring:
mvc:
contentnegotiation:
favor-parameter: true # 开启参数的内容协商
(3)页面请求与后端接收
测试
测试
测试
@GetMapping("/test")
@ResponseBody
public String test1(){
return "abc";
//若请求头内容协商将响应html类型
//若请求参数内容协商将响应json或xml类型
}
@GetMapping("/test")
@ResponseBody
public Person test(){
Person person=new Person();
person.setName("cyt");
person.setAge(23);
return person;
//若请求头内容协商将响应xml类型
//若请求参数内容协商将响应json或xml类型
}
3、@ResponseBody响应跟踪:
(1)RequestResponseBodyMethodProcessor 处理方法返回值;
(2)对请求进行内容协商(请求头内容协商和请求参数内容协商)将返回对象交由匹配出的消息转换器处理:
-
请求头内容协商先根据返回对象类型再根据请求头接受媒体类型权重匹配能处理返回值的消息转换器;
-
参数内容协商直接匹配出消息转换器;
(3)消息转换器将返回对象转换为对应媒体类型并写出至浏览器;
4 视图解析和模板引擎 4.1 概述- 视图解析是指springboot处理请求后跳转到某个页面的过程,可以是转发或重定向。
- 服务端模板引擎是实现页面渲染的技术,jsp也是一种模板引擎,但SpringBoot默认不支持 JSP,因此需要引入第三方模板引擎技术实现页面渲染,比如模板引擎thymeleaf、freemarker。
- 优点:语法简单 ,使用简单
- 缺点:性能 低只适合简单单体项目
环境:引入 thymeleaf场景并自动配置好
org.springframework.boot spring-boot-starter-thymeleaf
//所有thymeleaf的配置值都在 ThymeleafProperties //thymeleaf资源默认目录 public static final String DEFAULT_PREFIX = "classpath:/templates/"; //thymeleaf资源默认后缀 public static final String DEFAULT_SUFFIX = ".html"; //xxx.html
1、引入名称空间享受提示功能
2、th:text="${msg}":
取出域对象的对应值给标签文本赋值;
success
3、th:href="${lct}“:
给标签属性href赋值;
去百度
4、th:href="@{/test/dispatch}":
@{}里的字符串赋值到href,动态页面的跳转需要先请求服务器,访问后台应用程序,页面经视图解析器解析后返回浏览器;
注意:浏览器请求不可直达html,只能达处理器;
5、模板抽取
th:insert/replace/include
common
====common
common
==common
6、th:each遍历
5 拦截器
编写mcv拦截器必须实现接口HandlerInterceptor:
public class LoginInterceptor implements HandlerInterceptor {
//拦截/预处理方法:在请求到达处理器前对请求进行拦截和处理return true放行return false不放行
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//拦截请求验证session权限,若有则放行,无则重定向
if(request.getSession().getAttribute("loginUser")!=null){
return true;
}
else {
HttpSession session=request.getSession();
session.setAttribute("msg","请先登录!");
response.sendRedirect("/");
return false;
}
}
//后置处理方法:处理器适配器执行处理器返回视图模型对象后,视图渲染处理前
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println(modelAndView);
}
//完成之后方法:视图渲染处理结束后,倒序遍历拦截器链元素执行本方法;或请求被拦截后,倒序遍历拦截链中放行的元素执行该方法;
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println(ex);
}
}
6 文件上传
#单个文件最大上传默认1MB spring.servlet.multipart.max-file-size=1024 #单次请求最大上传,默认10MB spring.servlet.multipart.max-request-size=10240
@PostMapping("/upload")
public String upload(@RequestParam("userName") String username,
@RequestParam("email") String email,
@RequestPart("headerImg") MultipartFile headerImg,
@RequestPart("photos") MultipartFile[] photos,
HttpServletRequest req) throws IOException, ServletException {
log.info("上传的信息:email={},userName={},headerImg={},photos={}"
, email, username, headerImg.getSize(), photos.length);
//InputStream inputStream=headerImg.getInputStream();//原生输入流
ServletContext context = req.getServletContext();
File dir = new File(context.getRealPath("/cache"));
if (!dir.exists()) {
dir.mkdirs();
}
if (!headerImg.isEmpty()) {//非空判断防止空指针异常
//输出流默认将新同名文件替换旧文件;此判断若文件不存在才把新文件写进磁盘
if (!new File(context.getRealPath("/cache") + headerImg.getOriginalFilename()).exists()) {
//此方法内置输出流,将内容写进路径参数或File对应的磁盘位置
//文件与目录不能同时创建,若路径不存在此方法将异常
headerImg.transferTo(new File(context.getRealPath("/cache/") + headerImg.getOriginalFilename()));
}
}
if(photos.length>0){
for (MultipartFile photo : photos) {
photo.transferTo(new File(context.getRealPath("/cache/") + photo.getOriginalFilename()));
}
}
return "redirect:/main";
}
7 异常处理
1、错误处理
默认情况下,Spring Boot提供/error处理所有错误的映射;其中包含错误,HTTP状态和异常消息的详细信息
对于机器客户端,它将生成JSON响应,其中包含错误,HTTP状态和异常消息的详细信息;
对于浏览器客户端,响应一个“ whitelabel”错误视图,以HTML格式呈现相同的数据;
1.1、自定义错误视图静态资源目录/error/下或template/error/下的4xx,5xx页面会被自动解析:有精确的错误状态码页面就匹配精确的否则匹配5xxhtml页或4xx.html面,如果都没有就触发白页;
404.html:静态页面 5xx.tml:1.2、自定义异常处理器
标注了@ExceptionHandler的方法是自定义异常处理器,用于供ExceptionHandlerExceptionResolver异常解析器调用来处理异常;
@ControllerAdvice//含@Component自动注册;被标注类可以增强
public class GlobalExceptionHandler {
//被标注方法将作为异常处理器;值是该异常处理器支持处理的异常类型
@ExceptionHandler({ArithmeticException.class,NullPointerException.class})
public String handleArithException(Exception e, HttpServletResponse resp, Model model) throws IOException {
log.error("异常是:{}",e.getMessage());
model.addAttribute("status",500);
model.addAttribute("message",e.getMessage());
model.addAttribute("trace",e.getStackTrace().toString());
//既可以返回ModelAndView又可以返回视图地址让系统解析为ModelAndView
return "/errorView";
}
}
1.3、@ResponseStatus+自定义异常
给自定义异常标注此注解写入Status和reason信息,以便系统默认异常解析器解析该自定义异常
@ResponseStatus(value=HttpStatus.FORBIDDEN,reason="用户太多!")
public class MyException extends RuntimeException{
public MyException(){
}
public MyException(String message){
super(message);
}
}
1.4、自定义异常解析器
添加自定义的异常解析器(默认只有DefaultErrorAttributes和HandlerExceptionResolverComposite)只需要@Component即可完成注册;
@Component//注册
@Order(value = Ordered.HIGHEST_PRECEDENCE)//设为优先级最高的异常解析器;
public class MyHandlerExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
try {
request.setAttribute(MyHandlerExceptionResolver.class.getName() + ".ERROR", ex);
//携带了状态码和信息后异常交给/error处理器处理
response.sendError(511,"经过我的异常解析器");
} catch (IOException e) {
e.printStackTrace();
}
//能返回视图对象表示本解析器可以解析异常,无需遍历后面的解析器
return new ModelAndView();
}
}
8 Web原生组件注入
Servlet、Filter、Listener三大Web原生组件的注入
8.1 注入方式 1、注解注入要在主程序类@ServletComponentScan("com.cyt.boot05_admin")才能注入;
@Slf4j//注意拦截器无法拦截servle
@WebServlet("/myServlet")//value是urlPartern
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
log.info("come to myServlet!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
@Slf4j
@WebFilter(value = {"
return new DruidDataSource();
}
}
3、测试
@Test
void manualConfigDruidTest() {
log.info("数据源:{}",dataSource.getClass());
}
4、开启druid监控页及配置各项监控功能
参照druid官方文档的mvc配置方式,springboot手动配置只需要将官方文档mvc配置方式换成springboot的配置方式即可以开启druid监控页及配置各项监控功能。
(1)druid官方文档中开启监控页步骤:
1.给druid数据源的filters属性赋值stat开启监控页功能
#配置信息直接绑定Druid对象属性
#yml配置属性开启监控页功能
datasource:
filters: stat #,wall,slf4j
2.在web.xml配置StatViewServlet的路径映射,通过该sevlet即可访问druid监控页
//注入servlet同时配置好映射路径
@Bean
public ServletRegistrationBean statViewServlet(){
StatViewServlet statViewServlet=new StatViewServlet();
return new ServletRegistrationBean<>(statViewServlet,"/druid*.xml路径); 若要修改某配置项的默认值则参考官方文档修改对应配置项即可,其配置和使用如下:
1、配置文件模式只需在yml配置myBatis全局配置文件路径和Mapper配置文件路径,然后在Mapper接口标注@Mapper即可;
2、注解配置模式只需在yml配置myBatis全局配置文件路径,然后把sql语句标注在方法上,最后在Mapper接口标注@Mapper即可;
3、混合模式在模式1的mapper的接口方法直接标注sql语句即可;
ps:myBatis全局配置项可以在yml配置;
10.1 配置模式
1、注册数据源:
需要导数据库连接驱动依赖,和数据源依赖,其中数据源至少要配置url、username、password,其他属性和功能有默认值;
2、引入myBatis场景
首先引入myBatis场景,前提是引入了数据库连接驱动和数据源
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.4
3、Mapper接口
@Mapper
@Repository
public interface AdminMapper {
List findAllAdmins();
}
4、修改mybatis规则配置和mybatis全局配置项(选做)
# 配置mybatis规则
mybatis:
#config-location: classpath:mybatis/mybatis-config.xml #配置myBatis全局配置文件路径
mapper-locations: classpath:mybatis/mapper/*.xml #配置映射文件路径,默认值为:classpath*:/mapper*.xml
configuration: #配置mybatis全局配置项
map-underscore-to-camel-case: true #全局配置项-开启波浪命名
5、配置Mapper映射
6、测试
@Service
public class AdminService {
@Autowired
AdminMapper adminMapper;
public List findAllAdmins(){
List admins=adminMapper.findAllAdmins();
return admins;
}
}
10.2 注解模式
1、注册数据源:
需要导数据库连接驱动依赖,和数据源依赖,其中数据源至少要配置url、username、password,其他属性和功能有默认值;
2、引入myBatis场景
首先引入myBatis场景,前提是引入了数据库连接驱动和数据源
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.4
3、Mapper接口
@Mapper
@Repository
public interface AdminMapper {
@Select("select * from admin where id=#{id}")
Admin findAdminById(Integer id);
}
4、配置mybatis规则和mybatis全局配置项
# 配置mybatis规则
mybatis:
# config-location: classpath:mybatis/mybatis-config.xml
configuration: #全局配置
map-underscore-to-camel-case: true #全局配置项-开启波浪命名
5、测试
@Service
public class AdminService {
@Autowired
AdminMapper adminMapper;
public Admin findAdminById(Integer id){
Admin admin=adminMapper.findAdminById(id);
if(admin!=null){
return admin;
}
return null;
}
}
11 整合MyBatisPlus
11.1 简介
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。使用参考官方文档https://baomidou.com/guide即可;
11.2 配置与使用说明
-
MyBatisplusProperties含默认配置信息且绑定yml配置文件,MybatisPlusAutoConfiguration 配置类已将mybatiseplus所有默认功能注册完成;
-
因为MyBatisplusProperties含默认配置信息,所以导完myBatisplus场景后可以不写mybatisplus配置,直接定义继承与baseMapper的持久层接口,甚至不用写接口方法,即可进行测试
-
若要修改mybatisplus某配置项的默认值,可在mybatis-plus:xxx 下修改对应配置项即可;
-
MyBatisPlus所有使用:https://baomidou.com/guide
11.3 快速开始
1、注册数据源:
需要导数据库连接驱动依赖,和数据源依赖,其中数据源至少要配置url、username、password,其他属性和功能有默认值;
2、导场景依赖
此场景包含了mybatis-spring-boot-starter,而mybatis-spring-boot-starter又包含了spring-boot-starter-data-jdbc
com.baomidou
mybatis-plus-boot-starter
3.4.1
3、修改mybatisplus配置(选做)
4、编写Entity与Mapper
@Data
@TableName("user") //当类名与表名不一致时需注明实体类与数据表的对应关系
public class User {
private Long id; //封装规则: 若没配置resultMap则实体类属性必须与表列名一致
private String password;
private String name;
private Integer age;
private String email;
// 标注数据库中不存在的属性
// @TableField(exist = false)
// private String add;
}
持久层接口继承baseMapper从而获得了对数据库T表的常用crud方法,可以直接调用;
原理:比如语句UPDATe admin SET name=#{admin.name},password=#{admin.password} WHERe id=#{id}(未涉及到对象封装)
条件:方法参数只能传入T类型和基本类型;
其表名字符串可以从T类名映射;
其列名字符串可以从T类字节码反射得到属性名;
基本类型参数字符串#{id}通过参数注解@Parm(id)确定;
pojo类型参数字符串#{admin.name}通过参数注解@Parm(admin)确定前缀,T类字节码反射属性名得到后缀,
@Mapper
@Repository
public interface UserMapper extends baseMapper {
}
当内置crud方法不能满足需求时要编写自定义持久层方法以及该方法得sql映射:
5、编写service
99 定制化mvc组件
场景starter - xxxxAutoConfiguration - @Bean导入xxx组件 - 绑定xxxProperties --绑定配置文件项;定制化组件方式:
1、修改配置文件改变默认组件属性;
2、直接在自定义配置类@Configuration()里@Bean注册,系统自动替换或增加该组件;
3、实现定制器,xxCustomizer接口是一个定制器。一般定制器只有一个方法,通过这个方法来修改Spring Boot组件的配置;
4、xxxConfigurer接口是一个配置器。实现该接口,重写给定的方法,来扩展或替换Spring Boot中的相应组件;
web场景要添加定制化web组件或以定制化组件替换默认组件常用注册WebMvcConfigurer接口的实现类,在实现类里重写相应的方法,
每个方法对应一个定制功能的注册,注册定制功能的动作由方法参数提供,注册方法有两种:
其一配置类实现实现WebMvcConfigurer接口。其二@bean注册WebMvcConfigurer接口的实现类。例如:
//定制化mvc组件配置类实现WebMvcConfigurer接口
@Configuration(proxyBeanMethods = false)
public class WebConfig implements WebMvcConfigurer {
//方法参数configurer提供注册动作。
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
//构造定制组件
UrlPathHelper urlPathHelper = new UrlPathHelper();
urlPathHelper.setRemoveSemicolonContent(false);
//方法参数把定制组件注册进去
configurer.setUrlPathHelper(urlPathHelper);
}
1、添加定制化类型转换器与格式化器
- 类型转换器用于添加定制参数绑定规则,格式化器用于定制某对象的格式如日期格式;
- 重写方法addFormatters(FormatterRegistry registry)即可添加定制类型转换器或格式化器:
定制类型转换器:
@Override
public void addFormatters(FormatterRegistry registry) {
// registry注册定制化 Converter,参数绑定是从字符串到Pet对象
registry.addConverter(new Converter() {
@Override
//定制参数绑定规则:拆分字符串给Pet各属性赋值
public Pet convert(String s) {
Pet pet=new Pet();
if(!StringUtils.isEmpty(s)){
String[] split=s.split(",");
pet.setName(split[0]);
System.out.println(Integer.parseInt(split[1]));
pet.setAge(Integer.parseInt(split[1]));
return pet;
}
return null;
}
});
}
2、添加定制化消息转换器
重写方法extendMessageConverters(List> converters)即可添加消息转化器用于响应自定义媒体类型:
@Override
public void extendMessageConverters(List> converters) {
//该自定义消息转换器仅支持处理响应Person对象
HttpMessageConverter converter=new HttpMessageConverter() {
@Override//不能读,即@ResquestBody无效
public boolean canRead(Class> clazz, MediaType mediaType) {
return false;
}
@Override
public boolean canWrite(Class> clazz, MediaType mediaType) {
return clazz.isAssignableFrom(Person.class);
}
@Override//返回我能支持的类型集合
public List getSupportedMediaTypes() {
//返回自定义类型
return MediaType.parseMediaTypes("application/x-cyt");
}
@Override
public Person read(Class extends Person> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
return null;
}
@Override//自定义数据的写出
public void write(Person person, MediaType contentType, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
String data=person.getName()+";"+person.getAge();
OutputStream out=outputMessage.getBody();
out.write(data.getBytes());
}
};
//注册添加消息转换器
converters.add(converter);
}
因为自定义媒体类型请求头权重低,默认请求参数内容协商仅有format=json和format=xml映射,
因此在浏览器想要响应自定义媒体类型只能是ajax或注册自定义内容协商管理器:
//自定义内容协商管理器替换默认的
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
//存本协商管理器支持的响应媒体类型映射
Map mediaTypes=new HashMap<>();
mediaTypes.put("json",MediaType.APPLICATION_JSON);
mediaTypes.put("xml",MediaType.APPLICATION_XML);
//自定义媒体类型
mediaTypes.put("cyt",MediaType.parseMediaType("application/x-cyt"));
//构建自定义的参数内容协商策略
ParameterContentNegotiationStrategy parameterStrategy=new ParameterContentNegotiationStrategy(mediaTypes);
//构建默认的请求头内容协商策略
//若不定义请求头内容协商策略,又以请求头的方式进行内容协商返回的永远是json
HeaderContentNegotiationStrategy headerStrategy=new HeaderContentNegotiationStrategy();
//封装各协商策略供注册
List list=new ArrayList<>();
list.add(parameterStrategy);
list.add(headerStrategy);
configurer.strategies(list);
}
3、添加拦截器
重写方法addInterceptors(InterceptorRegistry registry)即可添加拦截器:
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor())
//拦截所有路径的请求包括静态资源路径
.addPathPatterns("/**")
//指定放行路径请求
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**","/test");
// 指定放行路径请求;前提是配置了静态资源请求前缀spring:mvc:static-path-pattern: /static/**
//.excludePathPatterns("static/**");
registry.addInterceptor(new BlankInterceptor())
.addPathPatterns("/**")
.excludePathPatterns("/","/login","/css/**","/fonts/**","/images/**","/js/**");
}




