SpringBoot日常知识整理
一、项目管理工具
SpringBoot项目使用Maven/gradle作为项目管理工具,pom.xml与settings.gradle为各自的项目管理文件。主要作用为1、统一开发规范与工具 , 2、统一管理jar包
二、SpringBoot启动
SpringBoot通过main方法所在类文件开启SpringBoot项目,通过注释@SpringBootApplication启动其他SpringBoot自动配置与按规则自定义的信息。
三、@SpringBootApplication注释内容
@SpringBootApplication内主要有@ComponentScan与@EnabledAutoConfigure两个注释,前者能能扫到当前包下所有配置类与组件,后者能开启SpringBoot的自动配置功能。
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
? ? excludeFilters = {@Filter(
? ? type = FilterType.CUSTOM,
? ? classes = {TypeExcludeFilter.class}
), @Filter(
? ? type = FilterType.CUSTOM,
? ? classes = {AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
?
四、SpringBoot具有默认SpringMVC配置信息
要让SpringBoot默认的SpringMVC相关配置信息无效,则在配置自定义SpringMVC的配置类(继承WebMvcConfigurer)上使用@EnableWebMVC注释即可
五、后端发送请求对象RestTemplate
使用RestTemplate需要引入相关依赖。
<dependency>
? ? <groupId>org.apache.httpcomponents</groupId>
? ? <artifactId>httpclient</artifactId>
? ? <version>4.5.6</version>
</dependency>
<dependency>
? ? <groupId>org.springframework.boot</groupId>
? ? <artifactId>spring-boot-starter-web</artifactId>
</dependency>
引入依赖包后,SpringBoot只自动配置了RestTemplateBuilder相关基础组件,而未生成RestTemplate;
为了导入RestTemplate组件需要通过builder.build()创建。 若需要拓展,如修改连接与超时时间等,可通过设置 ClientHttpRequestFactory、httpClientBuilder、HttpClientConnectionManager组件;
依赖关系为RestTemplate->ClientHttpRequestFactory->httpClientBuilder->HttpClientConnectionManage。
六、反射应用:
可以通过反射方式为对象按照属性名设置值、为对象按照方法名执行。可在http请求与响应中通过解析器进行参数或响应值进行转换对象设置。
七、参数数据绑定:
控制器中对没有注释标注的参数,都会经过参数数据绑定,在Spring执行过程中通过ServletRequestDataBinder进行数据与Request参数数据绑定。对有注释标注的参数,则会通过对应解析器进行数据绑定。SpringMVC支持自定义解析器,自定义解析器可通过实现HandlerMethodArgumentResolver接口组件完成数据绑定。
八、过滤器:
过滤器对响应报文的头部字段进行修改只能在chain.doFilter之前,之后不可对响应报文的头部字段进行修改,但可对响应报文体修改。因controller方法执行完毕后响应报文状态即设置为了commited,hearder固定。
@WebFilter:标注过滤器,指定过滤路径与过滤器名称。 @ServletComponentScan:扫描过滤器等Servlet容器组件,使Servlet容器下的过滤器组件在Spring下生效。 @Component:标注过滤器,声明将过滤器交由Spring容器管理。
//过滤器无需手动设置过滤器注入
@Component
@WebFilter(filterName = "file", urlPatterns = "/filter")
public class myTestFilter implements Filter{
?? ?@Override
? ? public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
?}
?
九、拦截器:
//拦截器需通过WebMvcConfigurer的addInterceptors设置拦截器注入
public class testInterceptor implements HandlerInterceptor {
? ? @Override
? ? public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
? ? ? ? return false;
? ? }
? ? @Override
? ? public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
? ? }
}
?
十、过滤器、拦截器、解析器中的request、response:
request、response是同一个;并且更改SpringMVC流程中的的request、response会直接改变后面流程中的reuqest、response(如:更改chain.doFilter(request,response,chain)中request与response)
十一、过滤器、拦截器、解析器中的request、response为什么是同一个的源码流程解析:
通过SpringBoot框架源码预览可以看出过滤器链filterChain.doFilter执行到完成所有过滤器的执行,将其中的HttpServletRequest与HttpServletResponse交由Servlet容器执行器service方法(进入Spring容器层次),故可以在filterchain中通过doFilter的request与response替换完成NativeRequest与NativeResponse更改。
使用:拦截器与过滤器将请求拦截下来,响应依然可以响应,只不过后续处理不执行而已。抛出异常可通过@ControllerAdvice进入异常处理。
十二、SpringBoot中事务:
在Spring Boot中,当我们使用了spring-boot-starter-jdbc或spring-boot-starter-data-jpa依赖的时候,框架会自动默认分别注入DataSourceTransactionManager或JpaTransactionManager。所以我们不需要任何额外 配置就可以用@Transactional注解进行事务的使用(使用Mybatis下则导入spring-boot-starter-jdbc依赖)。
事务只针对存在的数据源生效。SpringBoot使用@EnableTransactionManagement注释启动事务管理。当@Transactional标注的方法内抛出异常,则当前事务中执行的数据源操作将回滚。
十三、Java:字符串编码转换:
Java下可以进行字符串编码转换,通过String字符串作为中间介。不过不是所有字符串编码都可以进行转换,比如GBK与UTF-8编码可以进行字符串转换,而UTF-8与ISO_8859_1无法进行字符串转换,会出现字符串显示乱码。
需要额外注意,java字符串默认字符编码是由本地windows的语言地域里的设定决定,而非固定。本地测试得到的默认字符串编码为UTF-8。
//字符串编码转换测试代码示例
? ? @org.junit.Test
? ? public void test3() {
? ? ? ? String str1 = "你好";
? ? ? ? try {
? ? ? ? ? ? byte[] b0 = str1.getBytes();
? ? ? ? ? ? byte[] b = str1.getBytes("GBK");
? ? ? ? ? ? String str2 = new String(b, "GBK");
? ? ? ? ? ? byte[] b1 = str2.getBytes(StandardCharsets.UTF_8);
? ? ? ? ? ? String str3 = new String(b1, StandardCharsets.UTF_8);
? ? ? ? ? ? byte[] b2 = str2.getBytes(StandardCharsets.ISO_8859_1);
? ? ? ? ? ? String str4 = new String(b2, StandardCharsets.ISO_8859_1);
? ? ? ? ? ? System.out.println(b1 + str3 + " " + b + " " + str2 + b2 + "" + str4);
? ? ? ? } catch (UnsupportedEncodingException e) {
? ? ? ? ? ? e.printStackTrace();
? ? ? ? ? ? System.out.println("编码解码失败");
? ? ? ? }
? ? }
运行结果:
十四、前后端分离 后台重定向地址:
对于HttpServletResponse ?response响应,直接使用 response.sendRedirect("http://www.baidu.com");即可完成重定向。
十五、Spring Boot CLI:
Spring Boot CLI是SpringBoot的命令行工具,通过命令行能快速安装、启动与配置Spring Boot项目。也就是说,SpringBoot的开发可以不使用IDE。
然而,使用SpringBoot CLI开发比使用IDE复杂且可视化程度低,因此普通程序员通过IDE开发能更加专注于业务代码的实现,减少对项目较低层层面的关注。
十六、SpringBoot中的CommendLineRunner类:
在Springboot启动中,会对上下文中所有的CommendLineRunner类型对象执行启动的run方法。通过@Order进行顺序的排列执行。
应用:要想在SpringBoot启动时执行一些操作,既可以使用@PostConstruct标注相应执行方法,也可以创建CommendLineRunner接口的方法类重写run方法实现。
十七、SpringBoot中数据校验@Validated与@Valid:
SpringBoot数据校验使用@Validated或者@Valid。
@Validated与@Valid标注在形参、类、方法上用于进行类对象字段验证的操作。待验证的类对象字段上需标注相应验证注释,如@NotEmpty、@NotBlank、@NotNull等.
@Valid属于JAVA拓展包下的注释,用于满足JSR-303验证规范。 @Validated属于Spring包下对@Valid拓展的注释,包含@Valid的所有功能,增加了对分组验证的支持。
@Valid使用:
1、引入pom依赖:依赖版本好必须保持一致
有两种依赖引入方式
1.1、
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>jakarta.validation</groupId>
? ? ? ? ? ? <artifactId>jakarta.validation-api</artifactId>
? ? ? ? ? ? <version>2.0.2</version>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.hibernate</groupId>
? ? ? ? ? ? <artifactId>hibernate-validator</artifactId>
? ? ? ? ? ? <version>6.0.16.Final</version>
? ? ? ? </dependency>
?
1.2、SpringBoot已对依赖版本一致进行封装,其中包含上面两依赖以及版本对应:
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-validation</artifactId>
? ? ? ? </dependency>
?
2、验证字段标明注释:
import lombok.Data;
import javax.validation.constraints.*;
@Data
public class ValidObject {
? ? @NotBlank
? ? @Size(min = 4, max = 15)
? ? private String id;
? ? @Max(100)
? ? @Min(0)
? ? private Integer age;
? ? @NotNull
? ? private String name;
? ? @Email
? ? private String email;
}
3、编写全局验证异常处理类: ?
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
? ? @ExceptionHandler(Exception.class)
? ? @ResponseBody
? ? public String handleException(Exception e){
? ? ? ? return "全局异常处理器处理valid验证异常";
? ? }
}
4、编写RequestBody对象验证控制器 4.1、通过全局异常处理器处理验证异常:
import com.example.abilitymodulesummary.validations.ValidObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@Slf4j
@RestController
public class ValidController {
? ? @RequestMapping("/validtest/valid")
? ? public String validController(@RequestBody @Valid ValidObject validObject){
? ? ? ? return "验证valid";
? ? }
}
4.2、若不打算通过异常处理处理验证异常,可通过绑定BindResult对验证结果进行处理:
import com.example.abilitymodulesummary.validations.ValidObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.validation.Valid;
@Slf4j
@RestController
public class ValidController {
? ? @RequestMapping("/validtest/valid")
? ? public String validController(@RequestBody @Valid ValidObject validObject, BindingResult bindingResult){
? ? ? ? log.info("控制器内验证valid开始");
? ? ? ? ?return "控制器内验证valid结束,验证结果是否有错误:"+(bindingResult.hasErrors()?"有":"无");
? ? }
}
?
5、验证示例: 切换到全局异常处理器处理异常,对4.1验证:
控制器内部处理验证异常,对4.2验证:
@Validated使用:
1、引入pom依赖:
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-web</artifactId>
? ? ? ? </dependency>
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.springframework.boot</groupId>
? ? ? ? ? ? <artifactId>spring-boot-starter-validation</artifactId>
? ? ? ? </dependency>
或者
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>jakarta.validation</groupId>
? ? ? ? ? ? <artifactId>jakarta.validation-api</artifactId>
? ? ? ? ? ? <version>2.0.2</version>
? ? ? ? </dependency>
? ? ? ? <!-- hibernate validator-->
? ? ? ? <dependency>
? ? ? ? ? ? <groupId>org.hibernate</groupId>
? ? ? ? ? ? <artifactId>hibernate-validator</artifactId>
? ? ? ? ? ? <version>6.0.16.Final</version>
? ? ? ? </dependency>
?
2、验证字段标明注释:
import lombok.Data;
import javax.validation.constraints.*;
@Data
public class ValidatedObject {
? ? @NotBlank(message = "id不能为空白",groups = {first.class,second.class,third.class})
? ? @Size(min = 4, max = 15,groups = {first.class,second.class,third.class})
? ? private String id;
? ? @Max(value = 100,groups = second.class)
? ? @Min(value = 0,groups = second.class)
? ? private Integer age;
? ? @NotNull(message = "name不能为null",groups = third.class)
? ? private String name;
? ? @Email(message = "email必须满足邮箱格式",groups = third.class)
? ? private String email;
? ? public interface first{};
? ? public interface second{};
? ? public interface third{};
}
?
3、编写全局验证异常处理类:. ?
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
@ControllerAdvice
public class GlobalExceptionHandler {
? ? @ExceptionHandler(Exception.class)
? ? @ResponseBody
? ? public String handleException(Exception e){
? ? ? ? return "全局异常处理器处理valid验证异常";
? ? }
}
4、编写RequestBody对象验证控制器 4.1、通过全局异常处理器处理验证异常:
import com.example.abilitymodulesummary.validations.ValidatedObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class ValidatedController {
? ? @RequestMapping("/validtest/validated")
? ? public String validatedController(@RequestBody @Validated({ValidatedObject.first.class, ValidatedObject.second.class, ValidatedObject.third.class}) ValidatedObject validatedObject){
? ? ? ? log.info("控制器内验证validated开始");
? ? ? ? return "控制器内验证validated结束,验证结果是否有错误:";
? ? }
}
4.2、若不打算通过异常处理处理验证异常,可通过绑定BindResult对验证结果进行处理:
import com.example.abilitymodulesummary.validations.ValidatedObject;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindingResult;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@Slf4j
@RestController
public class ValidatedController {
? ? @RequestMapping("/validtest/validated")
? ? public String validatedController(@RequestBody @Validated({ValidatedObject.first.class, ValidatedObject.second.class, ValidatedObject.third.class}) ValidatedObject validatedObject, BindingResult result){
? ? ? ? log.info("控制器内验证validated开始");
? ? ? ? return "控制器内验证validated结束,验证结果是否有错误:"+result.hasErrors();
? ? }
}
5、验证示例: 切换到全局异常处理器处理异常,对4.1验证:
控制器内部处理验证异常,对4.2验证:
|