3.3 其他配置
这一节将会讲述一些较为常用的配置,例如压缩、SSL等。
3.3.1 服务器常用配置
Spring Boot通用的配置项大约有一千多个,这些配置项大多与某个特定框架相关。在日常的使用中,还会涉及一些服务器的配置,这些配置基本上都以“server”作为前缀。下面我们介绍一些较为常用的服务器配置。
server.port:配置服务器的HTTP端口,默认为8080。
server.context-path:应用的访问路径。
server.connection-timeout:HTTP请求的连接超时时间,单位为毫秒,如果不设置,将会使用特定服务器的超时时间,设置为-1表示不会超时。
server.session.timeout:session的超时时间,单位为秒。
如果读者需要了解更多的配置,可以到Spring Boot的官方文档查看,也可以到本书的codes\03目录下查找SpringProperties.properties文件,笔者已经将全部配置复制到该文件中了。
3.3.2 响应压缩
Spring Boot默认支持Gzip压缩,使用该压缩比较简单,只需要在application.yml里面配置即可。新建一个Maven项目,加入“spring-boot-starter-web”的依赖。项目的启动类和控制器代码见代码清单3-15。
代码清单3-15:compression-test\src\main\java\org\crazyit\boot\c3\ComApp.java
@SpringBootApplication @Controller public class ComApp { public static void main(String[] args) { SpringApplication.run(ComApp.class, args); } @RequestMapping(path = "/hello") @ResponseBody public String hello() { return "hello world"; } }
在控制器中,只提供了一个“/hello”服务,返回“hello world”字符串。接下来配置application.yml文件,请见代码清单3-16。
代码清单3-16:compression-test\src\main\resources\application.yml
server: compression: enabled: true min-response-size: 1 mime-types: text/html, text/xml, text/plain, text/css, text/javascript, application/javascript
其中enabled配置是否打开压缩开关;min-response-size配置压缩阀值,单位是字节,默认值为2048,本例的配置较为极端,当响应的数据大于1字节时,就会进行压缩;mime-types属性用于配置需要压缩的报文类型,这里使用默认值,如果需要对JSON进行压缩,加上“application/json”即可。
编写请求客户端,调用hello服务,请求客户端可以使用CXF、Feign等框架。为了简单起见,我们直接使用RestTemplate,请见代码清单3-17。
代码清单3-17:codes\03\3.3\compression-test\src\test\java\org\crazyit\boot\c3\TestMain.java
public class TestMain {
public static void main(String[] args) throws Exception {
// 创建RestTemplate实例,也可以在单元测试中使用TestRestTemplate
RestTemplate restTemplate = new RestTemplate();
HttpHeaders requestHeaders = new HttpHeaders();
// 设置编码为gzip
requestHeaders.set("Accept-Encoding", "gzip");
HttpEntity<? > requestEntity = new HttpEntity<Object>(requestHeaders);
// 调用hello服务
ResponseEntity<byte[]> entity = restTemplate.exchange(
"http://localhost:8080/hello", HttpMethod.GET, requestEntity,
byte[].class);
// 读取返回的内容
GZIPInputStream inflater = new GZIPInputStream(
new ByteArrayInputStream(entity.getBody()));
String s = StreamUtils.copyToString(inflater, Charset.forName("UTF-8"));
System.out.println(s);
}
}
在客户端代码中,直接使用RestTemplate调用“/hello”服务。注意,要在请求头中编码,获取响应后会得到byte[]数组,使用GZIPInputStream将byte[]数组转换为字符再输出。运行启动类(ComApp),再运行TestMain类,则可以看到客户端返回“hello world”字符串。
3.3.3 SSL配置
我们还可以对Web应用内嵌的服务器进行配置,让其支持HTTPS。使用keytool工具生成我们自己的证书,命令如下:
keytool -genkeypair -alias "sslTestKey" -keyalg "RSA" -keystore "D:\sslTest.keystore"
在此过程中会提示我们输入密码等信息。接下来,新建一个Maven项目,添加“spring-boot-starter-web”依赖。在该项目中只发布一个“/hello”服务,返回“hello”字符串。启动类与控制器的代码与前面的项目一致,在此不再赘述,代码请见“codes\03\3.3\ssl-test\src\main\java\org\crazyit\boot\c3\SslApp.java”。
将前面生成的sslTest.keystore文件复制到src/main/resources下,并在项目的application.yml中进行SSL的配置,请见代码清单3-18。
代码清单3-18:codes\03\3.3\ssl-test\src\main\resources\application.yml
server: port: 8443 ssl: key-store: classpath:sslTest.keystore key-store-password: 123456 key-password: 123456
属性key-store用于指定keystore文件的位置,key-store-password用于配置密钥库的密码,key-password用于配置密钥的密码。启动项目,在浏览器中访问:https://localhost:8443/hello,则可以看到具体结果。
3.3.4 使用其他服务器
除了可以使用内置的Tomcat服务器外,还可以使用Jetty及JBoss Undertow服务器。使用这两个服务器较为简单,只需要修改Maven的脚本文件即可。以Jetty为例,项目的pom.xml配置请见代码清单3-19。
代码清单3-19:codes\03\3.3\use-jetty\pom.xml
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.1.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions> <exclusion> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency> </dependencies>
在添加“spring-boot-starter-web”依赖时,使用exclusion元素将Tomcat的依赖排除,再另外加入“spring-boot-starter-jetty”依赖。编写启动类进行测试(本例的运行类为codes\03\3.3\use-jetty\src\main\java\org\crazyit\boot\c3\JettyApp.java),运行成功后可以看到以下的日志输出:
Jetty started on port(s) 8080 (http/1.1)
与Jetty类似,使用Undertow的话,先将Tomcat依赖排除,再加入“spring-boot-starter-undertow”依赖,启动后也有类似于Jetty的日志输出。如无特别说明,本书的所有示例,都使用Tomcat服务器运行。
3.3.5 服务器访问日志
服务器访问日志与服务器日志并不是同一个概念,我们一般在Tomcat控制台中看到的日志,是服务器的日志,而服务器访问日志,则会记录服务处理的请求信息,默认情况下,Tomcat并不会记录访问日志。新建一个Maven项目并为其加入“/hello”服务,在配置文件中,对访问日志进行配置,请见代码清单3-20。
代码清单3-20:codes\03\3.3\log-test\src\main\resources\application.yml
server: tomcat: basedir: my-tomcat accesslog: pattern: 'ip: %A, response code: %s, time: %t' enabled: true directory: crazyit-logs buffered: false
在代码清单3-20的配置项目中,需要先指定Tomcat的根目录,本例指定了my-tomcat目录,也就是会以log-test/my-tomcat作为Tomcat根目录。使用directory来配置访问日志的存放目录,本例中指定为my-tomcat/crazyit-logs。属性accesslog.enabled=true用于开启日志记录,accesslog.buffered被设置为false,表示不进行缓冲,直接将日志记录到文件中。
访问日志以哪种格式进行保存呢?要使用accesslog.pattern属性进行配置,可以使用Tomcat提供的标识符来表示不同的信息,例如本例中的“%A”表示本地的IP地址,%s表示HTTP的响应码,%t表示含时间的日期格式。除了这里使用的3个标识符外,其他标识符可以参看Tomcat文档:https://tomcat.apache.org/tomcat-8.0-doc/config/valve.html#Access_Logging。
启动本例的服务器(codes\03\3.3\log-test\src\main\java\org\crazyit\boot\c3\LogApp.java),访问:http://localhost:8080/hello,到log-test/my-tomcat/crazyit-logs目录下,则可以看到访问日志已经生成,日志内容如下:
ip: 192.168.1.102, response code: 200, time: [07/Nov/2017:13:48:47 +0800]
如果读者在实际环境中使用日志分析工具(例如ELK),则可以结合以上的配置,将日志存放到特定目录,再让日志分析工具按照设置好的格式读取入库。
本节介绍了Spring Boot常用的Server配置,这些配置项都以“server”开头。本节介绍的配置基本上可以满足需求,如果你想了解更多的Server配置,则可以到codes\03目录下,打开SpringProperties.properties文件,查找“server.xxxx”格式的配置。
3.3.6 banner配置
Spring Boot在启动时,会将banner信息显示到控制台中,默认的banner如图3-3所示。
图3-3 默认banner
我们可以通过配置application.yml文件,修改默认的banner,例如在classpath下提供一份txt文本文件,然后将spring.banner.location属性配置为“classpath:banner.txt”,这样在启动时,就可以将默认的banner替换掉。除了文本外,还可以提供图片文件用于显示,图片格式可以为jpg、png或gif, Spring Boot会将图片转换为ASCII,以文本的方式将图片显示到控制台中。以疯狂Java论坛的logo为例,使用图片作为banner,如图3-4所示为logo原图。
图3-4 疯狂Java论坛logo
将其配置为banner, application.yml的内容如下:
spring:
banner:
charset: UTF-8
location: classpath:banner.txt
image:
location: classpath:logo.jpg
invert: false
启动Spring Boot,控制台输出如图3-5所示。
图3-5 使用图片配置banner
在Spring Boot中配置banner,可以在application.yml中配置以下几个属性。
spring.banner.charset:如果banner的文本文件中有UTF-8以外的编码,则需要配置该项。
spring.banner.location:用于指定banner的文本文件位置。
spring.banner.image.location:指定banner图片的位置。
spring.banner.image.width:banner图片经转换后的字符长度,默认为76。
spring.banner.image.height:图片经转换后的字符高度。
spring.banner.image.margin:设置图片显示的边距,默认为2。
spring.banner.image.invert:配置为true,则将图片进行转换显示,以适应深色的终端风格。
还可以将特定的变量传递到banner文本文件中。在文本文件中可以使用以下的变量。
${application.version}:读取MANIFEST.MF文件里面的Implementation-Version, Spring Boot在打包时,会将pom.xml文件中的version值设置为Implementation-Version。
${application.formatted-version}:格式化过的application.version值,例如application.version值为1.0,则格式化后值为(v1.0)。
${spring-boot.version}:Spring Boot的版本,如2.0.1.RELEASE。
${spring-boot.formatted-version}:格式化后的Spring Boot版本,例如(v2.0.2.RELEASE)。
${application.title}:应用名称,读取MANIFEST.MF里面的Implementation-Title,打包后使用pom.xml的artifactId。
除了以上的变量外,还可以使用AnsiColor.XXX、AnsiBackground.XXX、Ansi.XXX与AnsiStyle.XXX来控制输出的banner样式。