JavaEE 企业级分布式高级架构师(十一)Spring Boot学习笔记(2)

Spring Boot重要用法

多环境选择

什么是多环境选择

  • 以下两种场景下需要进行“多环境选择”:
相同代码运行在不同环境
  • 在开发应用时,通常同一套程序会被运行在多个不同的环境,例如,开发、测试、生产环境等。每个环境的数据库地址、服务器端口号等配置都会不同。若在不同环境下运行时将配置文件修改为不同内容,那么,这种做法不仅非常繁琐,而且很容易发生错误。
  • 此时就需要定义出不同的配置信息,在不同的环境中选择不同的配置。
不同环境执行不同实现类
  • 在开发应用时,有时不同的环境,需要运行的接口的实现类也是不同的。例如,若要开发一个具有短信发送功能的应用,开发环境中要执行的 send()方法仅需调用短信模拟器即可,而生产环境中要执行的 send()则需要调用短信运营商所提供的短信发送接口。
  • 此时就需要开发两个相关接口的实现类去实现 send()方法,然后在不同的环境中自动选择不同的实现类去执行。

需求

下面将实现如下功能:存在开发与生产两种环境,不同环境使用不同配置文件,不同环境调用不同接口实现类。使用不同端口号对不同的配置文件加以区分。

多配置文件实现方式 02-multi-env

  • 复制 01-primary 工程,重命名为 02-multi-env。在 src/main/resources 中再定义两个配置文件,分别对应开发环境与生产环境:
# application-dev.properties
# 开发环境
server.port=8888
server.servlet.context-path=/dev

# application-prod.properties
# 生产环境
server.port=80
server.servlet.context-path=/prod
  • 说明:在 Spring Boot 中多环境配置文件名需要满足 application-{profile}.properties 的格式,其中{profile}为对应的环境标识,例如:
    • application-dev.properties:开发环境
    • application-test.properties:测试环境
    • application-prod.properties:生产环境
  • 至于哪个配置文件会被加载,则需要在 application.properties 文件中通过spring.profiles.active 属性来设置,其值对应{profile}值。例如,spring.profiles.active=test 就会加载 application-test.properties 配置文件内容。
  • 在生产环境下,application.properties 中一般配置通用内容,并设置 spring.profiles.active 属性的值为 dev,即,直接指定要使用的配置文件为开发时的配置文件,而对于其它环境的选择,一般是通过命令行方式去激活。配置文件 application-{profile}.properties 中则配置各个环境的不同内容。
  • 定义业务接口和实现类:
/**
 * 消息服务接口
 */
public interface MsgService {
    String send();
}
/**
 * 开发环境消息服务实现类
 * 注解@Profile可以用于环境选择,可以用在类上也可以用在方法上。
 */
@Service
@Profile("dev")
public class DevMsgServiceImpl implements MsgService {

    @Override
    public String send() {
        String ret = "-------- DevMsgServiceImpl -----------";
        System.out.println(ret);
        return ret;
    }
}
/**
 * 生成环境消息服务实现类
 */
@Service
@Profile("prod")
public class ProdMsgServiceImpl implements MsgService {

    @Override
    public String send() {
        String ret = "-------- ProdMsgServiceImpl -----------";
        System.out.println(ret);
        return ret;
    }
}
  • 说明:在实现类上添加@Profile 注解,并在注解参数中指定前述配置文件中的{profile}值,用于指定该实现类所适用的环境。
  • 定义处理器:
/**
 * 消息处理器
 */
@RestController
public class MsgController {
    @Autowired
    private MsgService msgService;

    @GetMapping("/send")
    public String sendHandle() {
        return msgService.send();
    }
}
  • 运行测试:打开主类在 Idea 中直接运行,即可在控制台看到默认使用的是开发环境,即端口号使用的是 8888,而工程的根路径为/dev。

在这里插入图片描述

  • 如果要运行生产环境,需要修改 application.properties
spring.profiles.active=prod
  • 将工程打为 Jar 包后,在命令行运行。若要想切换运行环境,必须要修改主配置文件吗?答案是否定的。只需添加一个命令参数即可动态指定。
  • 在命令行下运行 Jar 包,例如,现在的主配置文件中指定的是 dev 环境。将当前工程打为 Jar 包后,在命令行运行时添加如下参数:
java -jar 02-multi-env-1.0.jar --spring.profiles.active=prod
  • 说明:在命令行中添加的参数可以是写在配置文件中的任意属性。其原理是命令行设置的属性值的优选级高于配置文件的。

单配置文件实现方式 02-multi-env-yml

  • 这种实现方式只能使用 application.yml 文件,使用 application.properties 文件本身就会出错。
  • 复制 02-multi-env 工程,并重命名为 02-multi-env-yml,在此基础上修改。
  • 将原有的配置文件全部删除,然后定义 application.yml 文件。
spring:
  profiles:
    # 选择执行开发环境
    active: dev

---
# 配置开发环境下当前应用的端口号与上下文路径
spring:
  profiles: dev
server:
  port: 8888
  servlet:
    context-path: /dev

---
# 配置生产环境下当前应用的端口号与上下文路径
spring:
  profiles: prod
server:
  port: 80
  servlet:
    context-path: /prod

读取自定义配置

  • 自定义配置,可以是定义在主配置文件 application.properties 或 application.yml 中的自定义属性,也可以是自定义配置文件中的属性。

读取主配置文件中的属性

  • 复制 01-primary 工程,重命名为 03-custom-config。
  • 修改主配置文件:
# 当前应用系统的端口号与上下文
server.port=8888
server.servlet.context-path=/yw

# 自定义属性
company.name=veli.com
  • 修改控制器类 SomeController:
@RestController
public class SomeController {
	// 在@Value 注解中通过${ }符号可以读取指定的属性值。
    @Value("${company.name}")
    private String companyName;

    @GetMapping("/some")
    public String someHandle() {
        return companyName;
    }
}
  • 启动程序,测试接口:http://localhost:8888/yw/some

读取指定配置文件中的属性

  • 一般情况下,主配置文件中存放系统中定义好的属性设置,而自定义属性一般会写入自定义的配置文件中。也就是说,Java 代码除了可以读取主配置文件中的属性外,还可以读取指定配置文件中的属性,可以通过 @PropertySource 注解加载指定的配置文件。
  • 不能自定义 yml 文件:spring boot 官网给出说明,@PropertySource 注解不能加载 yml 文件。所以其建议自定义配置文件就使用属性文件。
  • 继续在工程 03-custom-config 上修改,自定义配置文件custom.properties,文件名随意,存放在 src/main/resources 目录中。
# 自定义属性
city.name=shenzhen

# 自定义对象属性
student.name=张三
student.age=23
student.score=96.5

# 自定义数组属性
country.cities[0]=beijing
country.cities[1]=shanghai
country.cities[2]=guangzhou

# 自定义对象数组属性
group.users[0].name=zhangsan
group.users[0].age=23
group.users[1].name=lisi
group.users[1].age=24
group.users[2].name=wangwu
group.users[2].age=25
  • 定义自定义属性的DTO对象:
@Component
@PropertySource(value = "classpath:custom.properties", encoding = "utf8")
@ConfigurationProperties("student")
@Data
public class StudentDto {
    private String name;
    private int age;
    private double score;
}
@Component
@PropertySource(value = "classpath:custom.properties", encoding = "utf8")
@ConfigurationProperties("country")
@Data
public class CountryDto {
    private List<String> cities;
}
@Component
@PropertySource(value = "classpath:custom.properties", encoding = "utf8")
@ConfigurationProperties("group")
@Data
public class GroupDto {
    private List<User> users;
}
  • 修改 SomeController:若属性的值存在中文,则需要添加 encoding 属性解决中文乱码问题。
@RestController
@PropertySource(value = "classpath:custom.properties", encoding = "UTF-8")
public class SomeController {

    @Value("${company.name}")
    private String companyName;

    @Value("${city.name}")
    private String cityName;

    @Autowired
    private StudentDto student;

    @Autowired
    private CountryDto country;

    @Autowired
    private GroupDto group;

    @GetMapping("/some")
    public String someHandle() {
        return companyName;
    }

    @GetMapping("/custom")
    public String customHandle() {
        return Arrays.asList(cityName, student.toString(), country.toString(), group.toString()).toString();
    }
}
  • 启动程序,并访问接口:http://localhost:8888/yw/custom

在这里插入图片描述

Spring Boot下使用JSP页面

  • 在 Spring Boot 下直接使用 JSP 文件,其是无法解析的,需要做专门的配置。

演示工程 04-jsp-demo

  • 定义工程:复制 01-primary 工程,并重命名为 04-use-jsp。在 src/main 下创建 webapp 目录,用于存放 jsp 文件。打开 Project Structrue 窗口,将 webapp 目录指定为 web 资源目录,然后才可以创建 jsp 文件。
  • 在 src/main/webapp 下创建一个 index.jsp 文件:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<form action="test/register" method="post">
    姓名:<input type="text" name="name"> <br>
    年龄:<input type="text" name="age"> <br>
    <input type="submit" value="注册">
</form>
</body>
</html>
  • 启动程序,此时在浏览器直接访问 http://localhost:8080/ ,发现其并没有显示 index 页面。因为当前工程不能识别 jsp 文件。
    在这里插入图片描述

使用物理视图

  • 添加 jasper 依赖:在 pom 中添加一个 Tomcat 内嵌的 jsp 引擎 jasper 依赖。jsp 引擎是用于解析 jsp 文件的,即将 jsp 文件解析为 Servlet 是由 jsp 引擎完成的。embed,嵌入。
<dependency>
 <groupId>org.apache.tomcat.embed</groupId>
  <artifactId>tomcat-embed-jasper</artifactId>
</dependency>
  • 注册资源目录:
<resources>
  <resource>
    <directory>src/main/weapp</directory>
    <targetPath>META-INF/resources</targetPath>
    <includes>
      <include>**/*.*</include>
    </includes>
  </resource>
</resources>
  • 创建 welcome.jsp:在 webapp 目录下再创建一个子目录 jsp,在其中创建 welcome.jsp 文件。
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
    name = ${name} <br>
    age = ${age} <br>
</body>
</html>
  • 修改SomeController:
@Controller
@RequestMapping("/test")
public class SomeController {
    @RequestMapping("/register")
    public String registerHandle(String name, int age, Model model) {
        model.addAttribute("name", name);
        model.addAttribute("age", age);
        return "jsp/welcome";
    }
}
  • 重启程序,访问:http://localhost:8080/index.jsp

在这里插入图片描述

使用逻辑视图

  • 修改主配置文件:
# 视图的前缀后缀
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
  • 修改处理器:

在这里插入图片描述

Spring Boot中使用MyBatis

  • 需求:完成一个简单的注册功能。

演示工程 05-use-mybatis

  • 复制 04-use-jsp 工程,重命名为 05-use-mybatis,在此基础上修改。添加依赖:
<!-- mybatis与spring boot整合的依赖 -->
<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>1.3.2</version>
</dependency>
<!-- mysql驱动 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.47</version>
</dependency>
<!-- druid驱动 -->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.12</version>
</dependency>
  • 注册资源目录:在 pom.xml 文件中将 dao 目录注册为资源目录。
<build>
 <resources>
   <!-- 注册dao包下mybatis映射文件为资源目录 -->
   <resource>
     <directory>src/main/java</directory>
     <includes>
       <include>**/*.xml</include>
     </includes>
   </resource>
 </resources>
</build>
  • 修改主配置文件,在主配置文件中主要完成以下几件工作:
    • 注册映射文件
    • 注册实体类别名
    • 注册数据源
mybatis.mapper-locations=classpath:com/yw/springboot/example/dao/mapper/*Mapper.xml
mybatis.type-aliases-package=com.yw.springboot.example.dao.po

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.254.128/ssm?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=123456
  • 定义实体类及DB表,在 DB 的 test 数据库中定义 student 表
@Data
public class Student {
    private Integer id;
    private String name;
    private int age;
}
  • 定义Mapper接口和映射文件,Mapper 接口上要添加 @Mapper、@Repository 注解。
@Mapper
@Repository
public interface StudentMapper {
    int insertStudent(Student student);
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yw.springboot.example.dao.mapper.StudentMapper">
  <insert id="insertStudent">
    insert into student(`name`, age) values(#{name}, #{age})
  </insert>
</mapper>
  • 定义Service接口和实现类:
public interface StudentService {
    boolean addStudent(Student student);
}
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Override
    public boolean addStudent(Student student) {
        int result = studentMapper.insertStudent(student);
        return result >= 1;
    }
}
  • 定义控制器 StudentController
@RestController
@RequestMapping("stu")
public class StudentController {
    @Autowired
    private StudentService studentService;

    @RequestMapping(value = "register", method = RequestMethod.POST)
    public String registerHandle(@RequestBody Student student) {
        boolean result = studentService.addStudent(student);
        return "注册" + (result ? "成功" : "失败");
    }
}
  • 启动项目,使用 postman 进行接口测试:
    在这里插入图片描述

Spring Boot的事务支持

  • 若工程直接或间接依赖于 spring-tx,则框架会自动注入 DataSourceTransactionManager 事务管理器;若依赖于 spring-boot-data-jpa,则会自动注入 JpaTransactionManager。
  • 在工程 05-use-mybatis 完成功能演示,假设用户注册时一次插入到 DB 中两条注册信息。若在插入过程中有发生异常,则已完成插入的记录回滚。
  • 修改启动类开启事务:添加注解 @EnableTransactionManagement

在这里插入图片描述\

  • 修改Service实现类:手动增加点异常

在这里插入图片描述

  • 启动项目,测试接口:http://localhost:8080/stu/register,服务端 500 报错,数据库回滚未成功插入。

在这里插入图片描述

Spring Boot对日志的控制

  • Spring Boot 中使用的日志技术为 logback。其与 Log4J 都出自同一人,性能要优于 Log4J,是 Log4J 的替代者。
  • 在 Spring Boot 中若要使用 logback,则需要具有 spring-boot-starter-logging 依赖,而该依赖被 spring-boot-starter-web 所依赖,即不用直接导入 spring-boot-starter-logging 依赖。
  • 在 Spring Boot 中使用 logback 日志,有两种方式:

添加配置属性

  • 只需在核心配置文件中添加如下配置即可。
# 控制日志显示格式
logging.pattern.console=logs-%level %msg%n
logging.level.root=warn,info
logging.level.com.yw.springboot.example.dao=debug

注意:在日志显示格式的属性值前面的 logs-是随意内容。在 yml 文件中的属性值若以%开头会报错,所以添加一些随意字符。在 properties 文件中不存在该问题。

添加配置文件

  • 配置文件名为 logback.xml,且必须要放在 src/main/resources 类路径下。内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%-5level - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="WARN,INFO">
    <appender-ref ref="STDOUT"/>
  </root>

  <logger name="com.yw.springboot.example.dao" level="DEBUG"/>
</configuration>

Spring Boot中使用Redis

  • 使用 Redis 缓存的数据可以划分为两类:
    • DB 更新后,Redis 缓存中的数据就要马上清除,以保证将来缓存中的数据与 DB 中的数据的绝对一致性;
    • 对数据准确性要求不是很高,只要与 DB 中的数据差别不大就可以,所以这类数据一般会为其设置过期时效。
  • 需求:
    • 用户在页面中输入要查询学生的 id,其首先会查看 Redis 缓存中是否存在,若存在,则直接从 Redis 中读取;若不存在,则先从 DB 中查询出来,然后再存放到 Redis 缓存中。
    • 用户也可以通过页面注册学生,一旦有新的学生注册,则需要将缓存中的学生信息清空。根据 id 查询出的学生信息要求必须是实时性的,其适合使用注解方式的 Redis 缓存。
    • 同时,通过页面还可以查看到总学生数,但对其要求是差不多就行,无需是实时性的。对于 Spring Boot 工程,其适合使用 API 方式的 Redis 缓存,该方式方便设置缓存的到期时限。

演示工程 06-use-redis

  • 复制 05-use-mybatis 工程,重命名为 06-use-redis,在此基础上修改。
  • 添加依赖:
<!-- spring boot与redis整合依赖 -->
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  • 修改主配置文件:配置redis
# 连接单机Redis
spring.redis.host=192.168.254.128
spring.redis.port=6379
spring.redis.password=

# 连接redis高可用集群
# spring.redis.sentinel.master=mymaster
# spring.redis.sentinel.nodes=sentinel1:26379,sentinel2:26379,sentinel3:26379

spring.cache.type=redis
spring.cache.cache-names=realTimeCache
# 过期时间5分钟
spring.cache.redis.time-to-live=300000
  • 启动类开启缓存

在这里插入图片描述

  • 修改实体类Student:由于要将查询的实体类对象缓存到 Redis,Redis 要求实体类必须序列化。所以需要实体类实现序列化接口。
@Data
public class Student implements Serializable {
    private Integer id;
    private String name;
    private int age;
}
  • 添加 index.jsp 注册页面:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
  <title>Title</title>
</head>
<body>
<form action="stu/register" method="post">
  姓名:<input type="text" name="name"> <br>
  年龄:<input type="text" name="age"> <br>
  <input type="submit" value="注册">
</form>

<form action="stu/find" method="get">
  学生id:<input type="text" name="id"><br>
  <input type="submit" value="查询">
</form>
<hr>
<a href="stu/studentsCount">查询学生总人数</a>
</body>
</html>
  • 修改Mapper接口和映射文件:在其中添加两个方法

在这里插入图片描述

  • 修改 Service 接口和实现类:在其中添加两个业务方法
@Service
public class StudentServiceImpl implements StudentService {
    @Autowired
    private StudentMapper studentMapper;

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;

    @CacheEvict(value = "realTimeCache", allEntries = true)
    // 采用spring默认的事务提交方式:发生运行时异常回滚
    @Transactional(rollbackFor = Exception.class)
    @Override
    public boolean addStudent(Student student) {
        int result = studentMapper.insertStudent(student);
//        int i = 3 / 0;
//        studentMapper.insertStudent(student);
        if(result>=1){
            return true;
        }else {
            return false;
        }
    }

    @Cacheable(value = "realTimeCache", key = "'student_'+#id")
    @Override
    public Student findStudentById(int id) {
        System.out.println("从DB中查询student");
        return studentMapper.selectStudentById(id);
    }

    // 使用双重检测锁解决热点缓存问题
    @Override
    public Integer findStudentsCount() {
        // 获取Redis操作对象
        BoundValueOperations<Object, Object> ops = redisTemplate.boundValueOps("count");
        // 从缓存中读取数据
        Object count = ops.get();
        if(count == null){
            synchronized (this){
                count = ops.get();
                if(count == null){
                    // 从DB中查询数据
                    count = studentMapper.selectStudentsCount();
                    // 将数据写入到缓存,并设置到期时限
                    ops.set(count, 10, TimeUnit.SECONDS);
                }
            }
        }
        return (Integer) count;
    }
}
  • 修改StudentController:在其中添加两个处理器方法
@RestController
@RequestMapping("stu")
public class StudentController {
    @Autowired
    private StudentService studentService;
	
	// ...略
	
    @GetMapping("/find")
    public Student findHandle(int id) {
        return studentService.findStudentById(id);
    }

    @GetMapping("studentsCount")
    public Integer countHandle() {
        return studentService.findStudentsCount();
    }
}
  • 测试接口:http://localhost:8080/stu/find?id=1

步骤小结

  • 在pom中添加Redis与SpringBoot整合依赖;
  • 在配置文件中注册Redis连接信息;
  • 实体类实现序列化接口;
  • 在启动类上添加@EnableCaching;
  • 在查询方法上添加@Cacheble,在增删改方法上添加@CacheEvict;
  • 若使用API方式操作Redis,则需要注入RedisTemplate,然后通过RedisTemplate获取到Redis 操作对象后就可以对 Redis 进行操作了。

Spring Boot中使用拦截器

  • 在非 Spring Boot 工程中若要使用 SpringMVC 的拦截器,在定义好拦截器后,需要在 Spring 配置文件中对其进行注册。但 Spring Boot 工程中没有了 Spring 配置文件,那么如何使用拦截器呢?
  • Spring Boot 对于原来在配置文件配置的内容,现在全部体现在一个类中,该类需要继承自 WebMvcConfigurationSupport 类,并使用@Configuration 进行注解,表示该类为一个 JavaConfig 类,其充当配置文件的角色。

演示工程 07-interceptor

  • 创建一个 Spring Boot 的 Web 工程,命名为 07-interceptor。
  • 定义拦截器
public class SomeInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, 
                             Object handler) throws Exception{
        System.out.println("执行拦截器" + request.getRequestURI());
        return false;
    }
}
  • 定义处理器
@RestController
public class SomeController {
    @RequestMapping("/first/some")
    public String firstHandle() {
        return "/first/some";
    }

    @RequestMapping("/second/some")
    public String secondHandle() {
        return "/second/some";
    }
}
  • 定义配置文件类
// 表示该文件充当配置文件
@Configuration
public class SomeWebMvcConfig extends WebMvcConfigurationSupport {
    @Override
    protected void addInterceptors(InterceptorRegistry registry){
        SomeInterceptor interceptor = new SomeInterceptor();
        registry.addInterceptor(interceptor)
                // 拦截first开头的路径
                .addPathPatterns("/first/**")
                // 不拦截second开头的路径
                .excludePathPatterns("/second/**");
    }
}
  • 测试接口:http://localhost:8080/first/some【被拦截】、http://localhost:8080/second/some【不被拦截】

步骤小结

  • 定义拦截器
  • 定义WebMvc配置类,其需要继承自WebMvcConfigurationSupport,且需要使用 @Configuration 进行注解

Spring Boot中使用Servlet

  • 在 Spring Boot 中使用 Servlet,根据 Servlet 注册方式的不同,有两种使用方式。若使用的是 Servlet3.0+版本,则两种方式均可使用;若使用的是 Servlet2.5 版本,则只能使用配置类方式。

注解方式 08-servlet-annotation

  • 复制 07-interceptor 工程,重命名为 08-servlet-annotation,在此基础上进行修改。
  • 创建Servlet:通过创建一个 class,让其继承自 HttpServlet 方式创建,然后在 Servlet 上添加@WebServlet 注解。
/**
 * 该方案仅适用于3.0+版本
 */
@WebServlet(name = "/some")
public class SomeServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        response.getWriter().println("Hello Servlet");
    }
}
  • 修改启动类:在入口类中添加 Servlet 扫描注解。

在这里插入图片描述

  • 启动项目,测试接口:http://localhost:8080/some

配置类方式 08-servlet-config

  • 复制 08-servlet-annotation 工程,重命名为 08-servlet-config,在此基础上进行修改。
  • 定义Servlet:
public class SomeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
            throws IOException {
        PrintWriter writer = response.getWriter();
        writer.println("Hello Spring Boot Servlet");
    }
}
  • 定义配置类:
// 表示其为配置类,相当于applicationContext.xml文件
@Configuration
public class MyApplicationContext {
    // 表示该方法返回的对象即为Spring容器中的Bean,方法名随意
    @Bean
    public ServletRegistrationBean<SomeServlet> getServletBean(){
        // 创建Servlet
        SomeServlet servlet = new SomeServlet();
        // 注册Servlet
        return new ServletRegistrationBean<>(servlet, "/some");
    }
}
  • 启动项目,测试接口:http://localhost:8080/some

Spring Boot中使用Filter

  • 在 Spring Boot 中使用 Filter 与前面的使用 Servlet 相似,根据 Filter 注册方式的不同,有两种使用方式。若使用的是 Servlet3.0+版本,则两种方式均可使用;若使用的是 Servlet2.5 版本,则只能使用配置类方式。

注解方式

  • 在 08-servlet-annotation 工程上进行修改,创建 Filter 需要通过创建一个 class,让其实现 Filter 接口方式创建。然后在 Filter 上添加 @WebFilter 注解。
@WebFilter("/*")
public class SomeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("信息已被过滤");
        chain.doFilter(request, response);
    }

    @Override
    public void destroy() {
    }
}
  • 修改启动类:在 @ServletComponentScan 注解中注册 Filter 所在的包,当然 Spring Boot 也支持通配符的使用。

配置方式

  • 在 08-servlet-config 工程上进行,创建Filter:
public class SomeFilter implements Filter {
    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 
            throws IOException, ServletException {
        System.out.println("信息已被过滤");
        chain.doFilter(request, response);      
    }

    @Override
    public void destroy() {
    }
}
  • 修改配置类:在配置类中添加如下方法。
// 表示其为配置类,相当于applicationContext.xml文件
@Configuration
public class MyApplicationContext {
    // ...
    @Bean
    public FilterRegistrationBean<SomeFilter> getFilterBean(){
        // 创建Filter
        SomeFilter filter = new SomeFilter();
        // 创建注册对象
        FilterRegistrationBean<SomeFilter> registrationBean = new FilterRegistrationBean<>(filter);
        // 添加过滤条件
        registrationBean.addUrlPatterns("/*");
        return registrationBean;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

讲文明的喜羊羊拒绝pua

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值