Spring Boot 2+Thymeleaf企业应用实战
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

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样式。