springboot-learn-03

Springboot加入HTTPS功能

HTTPS:
超文本传输安全协议(HyperText Transfer Protocol Secure),缩写:HTTPS;常称为 HTTP over TLS、HTTP over SSL 或 HTTP Secure)是一种通过计算机网络进行安全通信的传输协议。HTTPS 经由 HTTP进行通信,但利用 SSL/TLS 来加密数据包。HTTPS 开发的主要目的,是提供对网站服务器的身份认证,保护交换数据的隐私与完整性。这个协议由网景公司(Netscape)在 1994 年首次提出,随后扩展到互联网上。

  • 生成HTTPS数字证书
    借助 Java 自带的 JDK 管理工具 keytool 来生成一个免费的 https 证书;
    进入到 %JAVVA_HOME%\bin 目录下,执行如下命令生成一个数字证书:
keytool -genkey -alias tomcathttps -keyalg RSA -keysize 2048  -keystore D:\Zhangjian_HTTPS_digital_certificate.p12 -validity 365
命令含义如下:

- genkey 表示要创建一个新的密钥。
- alias 表示 keystore 的别名。
- keyalg 表示使用的加密算法是 RSA ,一种非对称加密算法。
- keysize 表示密钥的长度。
- keystore 表示生成的密钥存放位置。
- validity 表示密钥的有效时间,单位为天。

在这里插入图片描述
在这里插入图片描述

  • 引入HTTPS
    将上面生成的Zhangjian_HTTPS_digital_certificate .p12 拷贝到 Spring Boot 项目的 resources 目录下;
    在这里插入图片描述
    然后在 application.properties 中添加如下配置:
    在这里插入图片描述
# 引入HTTPS数字证书
server.ssl.key-store=classpath:Zhangjian_HTTPS_digital_certificate.p12
server.ssl.key-alias=tomcathttps
server.ssl.key-store-password=zjroot

启动项目,直接使用 Http 协议来访问接口,就会看到如下错误:
在这里插入图片描述
在这里插入图片描述
改用 https 来访问 ,结果如下:
在这里插入图片描述
不安全”:这是因为我们自己生成的 https 证书不被浏览器认可,不过没关系,我们直接点击继续访问就可以了(实际项目中只需要更换一个被浏览器认可的 https 证书即可);

  • 请求转发
    考虑到 Spring Boot 不支持同时启动 HTTP 和 HTTPS ,为了解决这个问题,我们这里可以配置一个请求转发,当用户发起 HTTP 调用时,自动转发到 HTTPS 上;
    • 新建配置类TomcatConfig
      在这里插入图片描述
import org.apache.tomcat.util.descriptor.web.SecurityCollection;
import org.apache.tomcat.util.descriptor.web.SecurityConstraint;
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class TomcatConfig {
    @Bean
    TomcatServletWebServerFactory tomcatServletWebServerFactory() {
        TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory(){
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint constraint = new SecurityConstraint();
                constraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                constraint.addCollection(collection);
                context.addConstraint(constraint);
            }
        };
        factory.addAdditionalTomcatConnectors(createTomcatConnector());
        return factory;
    }
    private Connector createTomcatConnector() {
        Connector connector = new
                Connector("org.apache.coyote.http11.Http11NioProtocol");
        connector.setScheme("http");
        connector.setPort(8081);
        connector.setSecure(false);
        connector.setRedirectPort(8080);
        return connector;
    }
}

在这里,我们配置了 Http 的请求端口为 8081,所有来自 8081 的请求,将被自动重定向到 8080 这个 https 的端口上。

如此之后,我们再去访问 http 请求,就会自动重定向到 https;
测试:
在这里插入图片描述

在这里插入图片描述
成功转向了HTTPS;

手动生成Springboot的Starter

我们使用 Spring Boot,基本上都是沉醉在它 Stater 的方便之中。Starter 为我们带来了众多的自动化配置,有了这些自动化配置,我们可以不费吹灰之力就能搭建一个生产级开发环境,有的小伙伴会觉得这个 Starter 好神奇呀!其实 Starter 也都是 Spring + SpringMVC 中的基础知识点实现的;
其实 Starter 的核心就是条件注解 @Conditional ,当 classpath 下存在某一个 Class 时,某个配置才会生效;

  • 自定义Starter
    所谓的 Starter ,其实就是一个普通的 Maven 项目,因此我们自定义 Starter ,需要首先创建一个普通的 Maven 项目,创建完成后,在pom.xml中添加 Starter 的自动化配置类即可,如下:
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    <version>2.1.4.RELEASE</version>
</dependency>

在这里插入图片描述
配置完成后,我们首先创建一个 HelloProperties 类,用来接受 application.properties 中注入的值,如下:

package com.zhangjian.springboot.springboot_learn_002;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "zhangjian")
public class HelloProperties {
    private static final String DEFAULT_NAME = "ZhangJian";
    private static final String DEFAULT_MSG = "hello~";
    private String name = DEFAULT_NAME;
    private String msg = DEFAULT_MSG;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
}

在这里插入图片描述
报错,加上Component解决;
在这里插入图片描述
解决Configuration Annotation Proessor not found in classpath
如下:

  1. 出现spring boot Configuration Annotation Proessor not found in classpath的提示是在用了@ConfigurationProperties这个注解时,所以问题出现在2. ConfigurationProperties注解。
  2. 根据提示的not found in classpath,查询此注解的使用关于怎么指定classpath,进而查询location,spring boot1.5以上版本@ConfigurationProperties取消location注解;

官方解决方案,Maven引入依赖:

<dependency>
   <groupId> org.springframework.boot </groupId>
   <artifactId> spring-boot-configuration-processor </artifactId>
   <optional> true </optional>
</dependency>

在这里插入图片描述
回到HelloProperties类,这个配置类很好理解,将 application.properties 中配置的属性值直接注入到这个实例中, @ConfigurationProperties 类型安全的属性注入,即将 application.properties 文件中前缀为 zhangjian的属性注入到这个类对应的属性上, 最后使用的时候,application.properties 中的配置文件,大概如下:
在这里插入图片描述
配置完成 HelloProperties 后,接下来我们来定义一个 HelloService ,然后定义一个简单的 say 方法, HelloService 的定义如下:

package com.zhangjian.springboot.springboot_learn_002;

public class HelloService {
    private String msg;
    private String name;
    public String sayHello() {
        return name + " say " + msg + " !";
    }
    public String getMsg() {
        return msg;
    }
    public void setMsg(String msg) {
        this.msg = msg;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

在这里插入图片描述
接下来就是我们的重轴戏,自动配置类的定义,用了很多别人定义的自定义类之后,我们也来自己定义一个自定义类HelloServiceAutoConfiguration

package com.zhangjian.springboot.springboot_learn_002;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableConfigurationProperties(HelloProperties.class)
@ConditionalOnClass(HelloService.class)
public class HelloServiceAutoConfiguration {
    @Autowired
    HelloProperties helloProperties;

    @Bean
    HelloService helloService() {
        HelloService helloService = new HelloService();
        helloService.setName(helloProperties.getName());
        helloService.setMsg(helloProperties.getMsg());
        return helloService;
    }
}

在这里插入图片描述
解释如下:

  • 首先 @Configuration 注解表明这是一个配置类。
  • @EnableConfigurationProperties 注解是使我们之前配@ConfigurationProperties 生效,让配置的属性成功的进入 Bean 中。
  • @ConditionalOnClass 表示当项目当前 classpath 下存在 HelloService 时,后面的配置才生效。
  • 自动配置类中首先注入 HelloProperties ,这个实例中含有我们在 application.properties 中配置的相关数据。
  • 提供一个 HelloService 的实例,将 HelloProperties 中的值注入进去。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值