Springboot整合MVC进阶篇

一、概述

1.1SpringBoot整合SpringMVC配置

SpringBoot对SpringMVC的配置主要包括以下几个方面:

  1. 自动配置:SpringBoot会自动配置一个嵌入式的Servlet容器(如Tomcat),并为我们提供默认的SpringMVC配置。这样我们无需手动配置Servlet容器和SpringMVC,只需添加相应的依赖即可快速搭建一个Web应用。
  2.  视图解析器:SpringBoot默认使用Thymeleaf作为视图解析器,如果需要更换其他视图解析器,可以在pom.xml中修改对应的依赖。
  3. 静态资源处理:SpringBoot默认会处理静态资源(如HTML、CSS、JavaScript等),并将其放在项目的/static或/public目录下。如果需要自定义静态资源的处理方式,可以通过编写一个类实现WebMvcConfigurer接口,并重写addResourceHandlers方法来实现。
  4. 拦截器:SpringBoot支持自定义拦截器,可以通过实现HandlerInterceptor接口来创建拦截器,并在主配置类上添加@EnableWebMvc注解,然后在该注解的configurers属性中添加自定义的拦截器。
  5.  异常处理:SpringBoot默认使用WhitelabelErrorView来处理异常,如果需要自定义异常处理方式,可以通过编写一个类实现ErrorController接口,并重写errorHtml方法来实现。
  6. 参数绑定:SpringBoot支持多种参数绑定方式,如@RequestParam、@PathVariable、@RequestBody等。如果需要自定义参数绑定方式,可以通过编写一个类实现MethodArgumentResolver接口,并重写resolveArgument方法来实现。
  7.  跨域支持:SpringBoot默认支持CORS跨域请求,如果需要自定义跨域配置,可以通过编写一个类实现WebMvcConfigurer接口,并重写addCorsMappings方法来实现。

总之,SpringBoot为我们提供了丰富的默认配置和灵活的扩展机制,可以方便地定制和扩展SpringMVC以满足项目需求。

1.2WebMvcConfiguration概述

WebMvcConfigurer接口是Spring提供的一个用于自定义Spring MVC配置的接口,主要提供了WebMvcConfigurer接口是Spring提供的一个用于自定义Spring MVC配置的接口,主要提供了多个回调方法,包括添加或修改Spring MVC的配置,如添加拦截器,自定义消息转换器等。具体来说,WebMvcConfigurer接口的主要方法包括:

  • - configurePathMatch(S):此方法用于配置路由请求规则。
  • - configureContentNegotiation(S):该方法用于内容协商配置。
  • - configureAsyncSupport(S):该方法用于异步支持配置。
  • - configureDefaultServletHandling(S):该方法用于配置默认静态资源处理器。
  • - addFormatters(S):此方法用于注册自定义转化器。
  • - addInterceptors(S):此方法用于拦截器配置。
  • - addResourceHandlers(S):此方法用于资源处理。
  • - addCorsMappings(S):此方法用于CORS配置。

在使用时,只需要实现WebMvcConfigurer接口,重写上述的方法即可完成自定义配置。

二、详解

2.1资源处理器

import org.springframework.http.CacheControl;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;import java.util.concurrent.TimeUnit;
@Configuration
public class MyConfig implements WebMvcConfigurer {@Overridepublic void addResourceHandlers(ResourceHandlerRegistry registry) {// 保留以前的配置WebMvcConfigurer.super.addResourceHandlers(registry);// 自定义配置registry.addResourceHandler("/static/**").addResourceLocations("classpath:/a/", "classpath:/b/").setCacheControl(CacheControl.maxAge(1180, TimeUnit.SECONDS));}
}

实现了WebMvcConfigurer接口。它的作用是配置静态资源的处理方式。具体来说,它会将"/static/**"路径下的资源映射到"classpath:/a/"和"classpath:/b/"这两个目录下,并设置缓存时间为1180秒。

2.2 路径匹配

Spring5.3之后加入了更多的请求路径匹配的实现策略;
以前只支持AntPathMatcher策略,现在提供了PathPatternParser策略。并且可以让我们指定到底使用那种策略。

 Ant风格

Ant风格的路径模式语法具有以下规则:

  • *:表示任意数量的字符。
  • ?:表示任意一个字符。
  • **:表示任意数量的目录。
  • {}:表示一个命名的模式占位符。
  • []:表示字符集合,例如[a-z]表示小写字母。

 PathPatternParser策略

PathPatternParser是Spring框架中用于解析URL路径模式的策略类。它可以解析和匹配URL路径模式,并且支持Ant风格的通配符,例如?***

  • ·PathPatternParser在jmh基准测试下,有6~8倍吞l提升,降低30%~40%空间分配率
  • ·PathPatternParser兼容AntPathMatcheri语法,并支持更多类型的路径模式
  • ·PathPatternParser"*"多段匹配的支持仅允许在模式末尾使用
 /*** 默认使用新版 PathPatternParser 进行路径匹配* 不能匹配 ** 在中间的情况,剩下的和 antPathMatcher语法兼容* @param request* @param path* @return*/@GetMapping("/a*/b?/**/{p1:[a-f]+}/**")public String hello(HttpServletRequest request, @PathVariable("p1") String path) {log.info("路径变量p1: {}", path);String uri = request.getRequestURI();return uri;}

 模式转换

# 使用新版的路径匹配策略PathPatternParser
spring.mvc.pathmatch.matching-strategy=path_pattern_parser# 使用老版的路径匹配策略AntPathMatcher
# spring.mvc.pathmatch.matching-strategy=ant_path_matcher

2.3内容协商配置

 在Spring Boot中,内容协商(Content Negotiation)是一种处理不同客户端请求的方法。它允许服务器根据请求的内容类型、参数或其他条件来选择合适的响应格式。要配置内容协商,你需要使用WebMvcConfigurer接口的实现类。

基于请求头内容协商:默认

客户端向服务端发送请求,携带HTTP标准的Accept请求头。

  • .Accept:application/json.text/xml.text/yaml
  • 服务端根据客户端情求头期望的数据类型进行动态返回

基于请求参数内容协商:需要开启

  • 发送请求GET/projects/spring-boot?format=json
  • 匹配到@GetMapping("*/projects/spring-boot")
  • 根据参数协商,优先返回json类型数据【需要开启参数匹配设置】
  • 发送请求GET/projects/spring-boot?format:=xml,优先返回xml类型数据

 web场景自动引入了json场景

在 spring-boot-starter-web 依赖下:
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-json</artifactId><version>2.3.4.RELEASE</version><scope>compile</scope>
</dependency>

 内容协助实现转xml

请求同一个接口,可以返回json和xml不同格式数据

  1. 引入支持写出xml内容依赖
    <dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-xml</artifactId>
    </dependency>
  2. 标注注解
    package com.yanyu.springplustest4.dto;import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlRootElement;
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;@JacksonXmlRootElement  // 可以写出为xml文档
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Person {private Long id;private String userName;private String email;private Integer age;private String role;
    }
    

    @JacksonXmlRootElement注解是Jackson库中的一个注解,用于指定XML文档的根元素。当使用Jackson库将Java对象转换为XML时,可以使用此注解来设置根元素的标签名。例如:

    import com.fasterxml.jackson.annotation.JacksonXmlRootElement;@JacksonXmlRootElement(localName = "student")
    public class Student {private String name;private int age;// 省略getter和setter方法
    }

    在这个例子中,Student类被标记为@JacksonXmlRootElement(localName = "student"),表示生成的XML文档的根元素标签名为<student>

  3. 开启基于请求参数的内容协商
    # 开启基于请求参数的内容协商功能。 默认参数名:format。 默认此功能不开启
    spring.mvc.contentnegotiation.favor-parameter=true
    # 指定内容协商时使用的参数名。默认是 format
    spring.mvc.contentnegotiation.parameter-name=type
  4. 测试
    package com.yanyu.springplustest4.Controller;import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import com.yanyu.springplustest4.dto.Person;
    import jakarta.servlet.http.HttpServletRequest;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.MessageSource;
    import org.springframework.web.bind.annotation.*;import java.util.Locale;/*** @author lfy* @Description* @create 2023-04-10 18:31*/
    @Slf4j
    @RestController
    public class HelloController {/*** 1、默认支持把对象写为json。因为默认web场景导入了jackson处理json的包;jackson-core* 2、jackson也支持把数据写为xml。导入xml相关依赖* @return*/@GetMapping("/person")public Person person(){Person person = new Person();person.setId(1L);person.setUserName("张三");person.setEmail("aaa@qq.com");person.setAge(18);return person;}}

 配置协商规则与支持类型

  1. 修改内容协商方式
    #使用参数进行内容协商
    spring.mvc.contentnegotiation.favor-parameter=true  
    #自定义参数名,默认为format
    spring.mvc.contentnegotiation.parameter-name=myparam 
  2. 大多数 MediaType 都是开箱即用的。也可以自定义内容类型
    spring.mvc.contentnegotiation.media-types.yaml=text/yaml

2.4消息转化器

WebMvcAutoConfiguration提供几种默认HttpMessageConverters

  • EnableWebMvcConfiguration通过 addDefaultHttpMessageConverters添加了默认的MessageConverter;如下:
    • ByteArrayHttpMessageConverter: 支持字节数据读写
    • StringHttpMessageConverter: 支持字符串读写
    • ResourceHttpMessageConverter:支持资源读写
    • ResourceRegionHttpMessageConverter: 支持分区资源写出
    • AllEncompassingFormHttpMessageConverter:支持表单xml/json读写
    • MappingJackson2HttpMessageConverter: 支持请求响应体Json读写

      默认8个: 

      image.png

      系统提供默认的MessageConverter 功能有限,仅用于json或者普通返回数据。额外增加新的内容协商功能,必须增加新的HttpMessageConverter

在Spring Boot中,可以通过配置类来自定义消息转换器。例如,以下代码演示了如何配置一个将Java对象转换为JSON格式的消息的转换器:

@Configuration
public class WebConfig implements WebMvcConfigurer {@Overridepublic void configureMessageConverters(List<HttpMessageConverter<?>> converters) {converters.add(new MappingJackson2HttpMessageConverter());}
}

 举例

1. 增加yaml返回支持

导入依赖

<dependency><groupId>com.fasterxml.jackson.dataformat</groupId><artifactId>jackson-dataformat-yaml</artifactId>
</dependency>

把对象写出成YAML

package com.yanyu.springplustest4.Controller;import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yanyu.springplustest4.dto.Person;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.web.bind.annotation.*;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import java.util.Locale;@Slf4j
@RestController
public class HelloController {@GetMapping("/person")public Person person(/*@RequestBody Person person*/){Person person = new Person();person.setId(1L);person.setUserName("张三");person.setEmail("aaa@qq.com");person.setAge(18);return person;}public static void aaa(String[] args) throws JsonProcessingException {Person person = new Person();person.setId(1L);person.setUserName("张三");person.setEmail("aaa@qq.com");person.setAge(18);YAMLFactory factory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER);ObjectMapper mapper = new ObjectMapper(factory);String s = mapper.writeValueAsString(person);System.out.println(s);}
}

编写配置

#新增一种媒体类型
spring.mvc.contentnegotiation.media-types.yaml=text/yaml

增加HttpMessageConverter组件,专门负责把对象写出为yaml格式

package com.yanyu.springplustest4;import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import com.fasterxml.jackson.dataformat.yaml.YAMLGenerator;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.Charset;/*** 自定义的HTTP消息转换器,用于将对象转换为YAML格式*/
public class MyYamlHttpMessageConverter extends AbstractHttpMessageConverter<Object> {private ObjectMapper objectMapper = null; // 用于将对象转换为YAML格式的ObjectMapper/*** 构造方法,配置YAML格式的ObjectMapper*/public MyYamlHttpMessageConverter(){super(new MediaType("text", "yaml", Charset.forName("UTF-8")));// 告诉SpringBoot这个MessageConverter支持哪种媒体类型YAMLFactory factory = new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER); 
// 禁用YAML文档起始标记this.objectMapper = new ObjectMapper(factory);}/*** 判断是否支持转换指定的类* @param clazz 要转换的类* @return 如果是对象类型(非基本类型),返回true;否则返回false*/@Overrideprotected boolean supports(Class<?> clazz) {return true;}/*** 从HTTP输入消息中读取数据,暂不实现* @param clazz 要转换的类* @param inputMessage HTTP输入消息* @return 返回null* @throws IOException 如果发生I/O错误* @throws HttpMessageNotReadableException 如果无法读取消息*/@Overrideprotected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {return null;}/*** 将对象写入HTTP输出消息中* @param methodReturnValue 要写出的对象* @param outputMessage HTTP输出消息* @throws IOException 如果发生I/O错误* @throws HttpMessageNotWritableException 如果无法写出消息*/@Overrideprotected void writeInternal(Object methodReturnValue, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {// 使用try-with-resources语法,自动关闭流try(OutputStream os = outputMessage.getBody()){this.objectMapper.writeValue(os, methodReturnValue);}}
}

2.5国际化配置

国际化的自动配置参照MessageSourceAutoConfiguration

实现步骤

  1. Spring Boot 在类路径根下查找messages资源绑定文件。文件名为:messages.properties
  2. 多语言可以定义多个消息文件,命名为messages_区域代码.properties。如:
    1. messages.properties:默认
    2. messages_zh_CN.properties:中文环境
    3. messages_en_US.properties:英语环境
  3. 程序中可以自动注入 MessageSource组件,获取国际化的配置项值
  4. 页面中可以使用表达式  #{}获取国际化的配置项值
        @Autowired  //国际化取消息用的组件MessageSource messageSource;@GetMapping("/haha")public String haha(HttpServletRequest request){Locale locale = request.getLocale();//利用代码的方式获取国际化配置文件中指定的配置项的值String login = messageSource.getMessage("login", null, locale);return login;}
    
  5. 配置

    spring.messages.basename=messages
    spring.messages.encoding=UTF-8
    

1. `spring.messages.basename=messages`:这个属性设置了Spring Boot默认的消息文件的基本名称,即在类路径下查找名为"messages"的文件。这些文件通常用于存储国际化消息,例如错误消息、提示消息等。

2. `spring.messages.encoding=UTF-8`:这个属性设置了Spring Boot默认的消息文件的字符编码。在这个例子中,编码被设置为UTF-8,这意味着消息文件中的文本将使用UTF-8编码进行存储和读取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/578099.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

深圳锐科达SIP矿用电话模块SV-2801VP

深圳锐科达SIP矿用电话模块SV-2801VP 一、简介 SV-2800VP系列模块是我司设计研发的一款用于井下的矿用IP音频传输模块&#xff0c;可用此模块打造一套低延迟、高效率、高灵活和多扩展的IP矿用广播对讲系统&#xff0c;亦可对传统煤矿电话系统加装此模块&#xff0c;进行智能化…

基于5G智能网关的智慧塔吊监测方案

塔吊是建筑施工中必不可少的设施&#xff0c;由于塔吊工作重心高、起重载荷大、人工视距/视角受限等因素&#xff0c;也使得塔吊在工作过程中着较多的危险因素。对此&#xff0c;可以部署基于工业5G智能网关搭建智慧塔吊安全监测系统&#xff0c;实现对塔吊运行的全局精细监测感…

TP-Link路由器桥接设置

本文介绍了TP-Link路由器无线桥接设置方法&#xff1b;无线桥接指的就是通过无线的方式&#xff0c;把两台(多台)无线路由器连接起来&#xff0c;进行桥接的几台路由器中&#xff0c;只要有一台可以上网&#xff0c;剩下的也就可以上网了&#xff1b;主要作用是用来扩大无线WiF…

【STM32单片机】电子木鱼设计

文章目录 一、功能简介二、软件设计三、实验现象联系作者 一、功能简介 本项目使用STM32F103/F407单片机控制器&#xff0c;TFTLCD触摸屏、蜂鸣器等。 主要功能&#xff1a; 系统运行后&#xff0c;TFTLCD显示画面&#xff0c;可触摸木鱼区域&#xff0c;功德计数加1&#xf…

漏刻有时数据可视化Echarts组件开发(46)散点图颜色判断

series组件 series: [{name: Top 5,type: scatter,coordinateSystem: bmap,data: convertData(data.sort(function (a, b) {return b.value - a.value;}).slice(0, 6)),symbolSize: 20,encode: {value: 2},showEffectOn: render,rippleEffect: {brushType: stroke},label: {fo…

分布式系统架构设计之分布式通信机制

二、分布式通信机制&#xff1a;保障系统正常运行基石 在分布式系统中&#xff0c;各个组件之间的通信是保障系统正常运行的基石&#xff0c;直接影响到系统的性能、可扩展性以及整体的可维护性。接下来我们就一起看看通信在分布式系统中的重要性&#xff0c;以及一些常用的技…

Java---IO流讲解(2)

文章目录 1. 字符流1.1 为什么出现字符流1.2 字符流写数据的5种方式1.3 字符流读数据的两种方式1.4 字符缓冲流1.5 字符缓冲流特有功能 2. IO流小结2.1 字节流2.2 字符流 1. 字符流 1.1 为什么出现字符流 由于字节流操作中文时不是特别方便&#xff0c;因此Java提供了字符流。…

SpringBoot - Maven 打包合并一个胖 JAR 以及主项目 JAR 依赖 JAR 分离打包解决方案

问题描述 <plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><version>2.1.18.RELEASE</version><configuration><!--<classifier>exec</classifier>--…

12.25广义分布外检测学习/代码复现

A model.getA().toarray() # b np.array(model.RHS) sense np.array(model.sense) f np.array(model.obj)Aineq np.vstack((-Ale, Age)) # 把所有的<和>组合在一起 bineq np.append(-ble, bge) # 这里用append使bineq为一个一维矩阵&#xff0c;而不是2行1列的二…

SpringBoot 3.2.0 基于Spring Security+JWT实现动态鉴权

依赖版本 JDK 17 Spring Boot 3.2.0 Spring Security 6.2.0 工程源码&#xff1a;Gitee 为了能够不需要额外配置就能启动项目&#xff0c;看到配置效果。用例采用模拟数据&#xff0c;可自行修改为对应的ORM操作 编写Spring Security基础配置 导入依赖 <properties>&l…

java练习之abstract (抽象) final(最终) static(静态) 练习

1&#xff1a;分析总结&#xff1a;写出private、abstract、static、final之间能否联动使用&#xff0c;并写出分析原因 private static final 之间可以任意结合 abstract 不可以与private static final 结合使用 2&#xff1a;关于三个修饰符描述不正确的是(AD) A. static …

Linux操作系统基础知识点

Linux是一种计算机操作系统&#xff0c;其内核由林纳斯本纳第克特托瓦兹&#xff08;Linus Benedict Torvalds&#xff09;于1991年首次发布。Linux操作系统通常与GNU套件一起使用&#xff0c;因此也被称为GNU/Linux。它是一种类UNIX的操作系统&#xff0c;设计为多用户、多任务…

计算机组成原理综合6

补码表示&#xff1a; X&#xff1a;1111 1111 1111 1101 Y&#xff1a;1111 1111 1101 1111 Z&#xff1a;0111 1111 1111 1100 转原码表示&#xff1a;从右往左找第一个“1”&#xff0c;左边的所有数值位按位取反 X&#xff1a;1111 1111 1111 1101 1000 0000 00…

OGG-MySQL无法正常同步数据问题分析

问题背景: 用户通过OGG从源端一个MySQL从库将数据同步到目标端的另一个MySQL数据库里面&#xff0c;后面由于源端的从库出现了长时间的同步延时&#xff0c;由于延时差距过大最后选择通过重建从库方式进行了修复 从库重建之后&#xff0c;源端的OGG出现了报错ERROR OGG-0014…

关于Sneaky DogeRAT特洛伊木马病毒网络攻击的动态情报

一、基本内容 作为复杂恶意软件活动的一部分&#xff0c;一种名为DogeRAT的新开源远程访问特洛伊木马&#xff08;RAT&#xff09;主要针对位于印度的安卓用户发动了网络安全攻击。该恶意软件通过分享Opera Mini、OpenAI ChatGOT以及YouTube、Netfilx和Instagram的高级版本等合…

《PySpark大数据分析实战》-19.NumPy介绍ndarray介绍

&#x1f4cb; 博主简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是wux_labs。&#x1f61c; 热衷于各种主流技术&#xff0c;热爱数据科学、机器学习、云计算、人工智能。 通过了TiDB数据库专员&#xff08;PCTA&#xff09;、TiDB数据库专家&#xff08;PCTP…

饥荒Mod 开发(二三):显示物品栏详细信息

饥荒Mod 开发(二二)&#xff1a;显示物品信息 源码 前一篇介绍了如何获取 鼠标悬浮物品的信息&#xff0c;这一片介绍如何获取 物品栏的详细信息。 拦截 inventorybar 和 itemtile等设置字符串方法 在modmain.lua 文件中放入下面代码即可实现鼠标悬浮到 物品栏显示物品详细信…

适合引流源码声音鉴定神器网站源码,轻松吸引用户关注

源码介绍 声鉴卡HTML5网页源码&#xff0c;完整可运转&#xff0c;调用wx录音&#xff0c;自动判断声音属性&#xff0c;输出结果 安装教程 只需要把源码上传至主机空间就可以 支持上传二级目录访问&#xff01;提示一下&#xff1a;wxvx打开效果是最佳的源码里面生成二维码…

测试服务器带宽(ubuntu)

apt install python3 python3-pippip3 install speedtest-clispeestest-cli

Hive05_DML 操作

1 DML 数据操作 1.1 数据导入 1.1.1 向表中装载数据&#xff08;Load&#xff09; 1&#xff09;语法 hive> load data [local] inpath 数据的 path [overwrite] into table student [partition (partcol1val1,…)];&#xff08;1&#xff09;load data:表示加载数据 &…