出现此错误的大致环境如下- SpringBoot 2.7.17, SpringWeb 项目,所引用入的 spring-webmvc-5.3.30, spring 6 已解决
- JDK 1.8 或 JDK 17
- 依赖了 jackson-dataformat-xml:2.12.6 和 jackson-dataformat-cbor:2.12.6, 它会在 RestTemplate 加上 application/xml, application/cbor 等 Accept 类型
- 代码中用 RestTemplate 调用此应用的 Endpoint, 未设置任何头
后面会详细列出能重现此问题的 pom.xml 配置及 Java 代码
在执行restTemplate.getForEntity("http://localhost:8080/test2", String.class)
时出现如下错误 Read More
写作此篇是作为对 Spring 使用 Cache 解析及使用不同类型的 Cache 一文的补充,该文中提到了自定 CacheManager 及配置spring.cache.type来选择自己的 Cache 实例,但对 Spring 是如何确定具体 Cache 实现未作展开。本文将介绍选择 Cache 实现的几种方式- 默认选择 Cache
- 声明 Spring Bean
Cache - 声明 Spring Bean
CacheManager - 通过
spring.cache.type属性选择 - 引入相应的 Cache 实现依赖
Read More
项目中有用到 Spring Security 来控制 API 的访问权限,但对于配置应用它基本上是照葫芦画瓢。至于为什么要调用方法SecurityContextHolder.getContext().setAuthentication()
并且能从 HttpServletRequest 中得到 Authentication。还有,只要在 Controller 的方法中添加一个带 @AuthenticationPrincipal 注解的参数public String sampleApi(@AuthenticationPrincipal DecodedJWT decodedJWT) {...}
之后,decodedJWT 便自动有了值,诸如此类的,此前一概模糊不清。
早先配置 spring-security-config 是通过继承 WebSecurityConfigurerAdapter, 覆盖它的 configure(HttpSecurity http) 来配置访问规则等。在 spring-security-config 5.7.x 开始不建议用 WebSecurityConfigurerAdapter, 而是借由 SecurityFilterChain 来配置 HttpSecurity 中的规则 ,或者通过 WebSecurityCustomizer 完成定制。 Read More
本文记录 SpringBoot 与 Logback 是如何工作的,即观察 SpringBoot 中 Logback 是怎么一步一步初始化的。用以测试的 SpringBoot 版本是 1.5.16, 而非最新的 SpringBoot 2。关于 SpringBoot 日志的官方文档在 Logging, 但不太详细或透彻。本文也不承诺说就理解得更有深度,只是为官方文档提供更多方面的参考。
SpringBoot 默认使用 Slf4J + Logback 来记录日志,对于一个基本的依赖于
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>的 Spring Boot 项目,上面组件依赖了 spring-boot-starter-logging 组件,而该组件又引入了以下几个依赖
- logback-classic: 依赖了 Slf4J
- jcl-over-slf4j
- jul-to-slf4j
- log4j-over-slf4j
相当于把其他的日志框架全桥接到了 Slf4J + Logback 上去了。 Read More
- 在 Java 中对于泛型类型,比如这样简单的类定义
class Processor<T> {}
如果直接初始化时要指定具体类型的话,我们可以这么写Processor<String> processor = new Processor<>(); //Java 7 及以上版本
Spring 对基本泛型的初始化
如果我们要用 Spring 容器来初始化这个类,比如给上面那个类加个 @Named 注解@Named
这时候我们通过
class Processor<T> {
}beanFactory.getBean(Processor.class)得到的是一个什么样的实例呢?Spring 怎么知道要指定什么具体类型呢?很简单,任何不确定的情况都是 Object。所以通过容器得到的Processor实例相当于用下面代码构造出来的Processor processor = new Processor(); //更准确来讲是 Processor<Object> processor = new Processor<>();
再进一步,对于有上限约束的泛型定义,Spring 才如何应对呢?像 Read More
当我们启动一个 Spring Boot 的 Hello World 程序, 可以看到 Spring 会在控制台下输出一段 ASCII 字符组成的 Spring 字样, 像这个图中的样子,
并且 ":: Spring Boot ::" 是绿色显示, 版本号灰色. 如果每个 Spring Boot 做的应用都用默认的 Banner 就不好玩了, 无外乎只在声明我正在用 Spring Boot. 好在 Spring 提供了多种方式让我们定制自己的 Banner.
官方文档: http://docs.spring.io/spring-boot/docs/1.3.8.RELEASE/reference/htmlsingle/#boot-features-banner
初始 Banner 的代码是 SpringApplicationBannerPrinter 类.
Spring Boot 默认寻找 Banner 的顺序是:- 依次在 Classpath 下找 文件
banner.gif,banner.jpg, 和banner.png, 先找到谁就用谁 - 继续 Classpath 下找
banner.txt - 上面都没有找到的话, 用默认的 SpringBootBanner, 就是我们最常见到的那个
- 依次在 Classpath 下找 文件
前阵想试下 Spring MVC 4 有了些什么新特性, 可真正用 Maven 在 IDE 中建立一个项目并不那么容易. Spring 当初在笑 EJB 的笨重时如今把自己也搞大了, 继而出台了一个 Spring Boot 来响应微服务的号召.
Spring Boot 的出世可以大大提升使用 Spring 框架时的开发效率. Spring 尽量简化 Spring 项目的配置, 一个mvn package就轻轻松的把一个 Web 项目打成一个fat jar, 运行java -jar spring-boot-sample-1.0-SNAPSHOT.jar就能通过内嵌的 Tomcat 或 Jetty 来启动一个 Web 应用了, 更别提怎么应对普通控制台应用了.
现在就来体验一下 Spring Boot 做一个 Spring MVC 项目有多简单, 我们仍然是建立一个 Maven 项目, 最简单的pom.xml文件内容如下: Read More