SpringBoot核心应用第二弹
☠️每日毒鸡汤:这个社会是存在不公平的,不要抱怨,因为没有用!人总是在反省中进步的!
1.3 自定义配置
- SpringBoot的核心配置文件中,除了使用内置的配置项之外,我们还可以自定义配置,然后采用如下注解去读取配置的属性值。
1.3.1 @value注解
语法格式: @value("${key}") 。key来自application.properties(yml)主配置文件中。
通过这种方式我们可以获取到 application.properties|yml中的原始属性以及自定义属性的属性值。
- application.properties中有原始属性也有自定义属性。
# 设置端口号
server.port=8082
# 设置上下文路径
server.servlet.context-path=/myBoot
# 自定义属性key=value
school.name=程云博
school.website=https://github.com/yunbocheng
school.address=河北承德
school=重返计划
- 此时可以在SpringBoot的任何一个类中,通过@Value注解来获取到主配置文件中属性对用的属性值。
// 以下是在Controller层中获取到的主配置文件中属性的属性值。
@Controller
public class HelloController {
// 我们使用 @Value 注解来获取配置文件中 server.port属性对应的属性值。
@Value("${server.port}")
private Integer port;
@Value("${server.servlet.context-path}")
private String contextPath;
@Value("${school.name}")
private String schoolName;
@Value("${school.website}")
private String schoolWebsite;
@Value("${school.address}")
private String schoolAddress;
// 这个注解是请求的路径信息。请求路径如果是:localhost:8082/myBoot/hello,那么就执行这个方法
@RequestMapping(value = "/hello")
// 这个注解的作用是:告诉容器返回的是一个字符串,不是返回的一个试图,跳转页面。
@ResponseBody
public String queryData(){
return "学校名字=" + schoolName + ",学校地址=" + schoolAddress + ",学校网站="
+ schoolWebsite + ",项目端口号=" + port + ",项目路径=" + contextPath;
}
}
1.3.2 @ConfigurationProperties注解
原理:将整个文件映射成一个对象,用于自定义配置项比较多的情况。
使用步骤:
- 需要创建一个实体类,这个实体类的作用就是获取主配置文件中属性的属性值。
// 这个注解作用是:创建这个类的对象
@Component
// 这个注解的作用是:主配置文件中属性的开头,也就是配置属性的前缀
@ConfigurationProperties(prefix = "school")
// 添加lombok,省略Getter、Setter方法、有参构造、以及toString()方法
@Data
// 添加无参构造
@NoArgsConstructor
public class SchoolInfo {
// 这个成员属性的名字和主配置文件中的属性名必须保持一致。
// 主配置:school.name=程云博 school.website=https://github.com/yunbocheng school.address=河北承德
// 这样就可以把程云博赋值给以下的name属性。
private String name;
private String website;
private String address;
}
- 在其他类中使用这个实体类中属性值。这里在controller类中来使用这个实例对象。
@Controller
public class HelloController {
// 这个注解的作用是:使用自动注入的方式来获取这个对象。
// 先使用byName方式来寻找一个info对象。当对象不存在的时候使用byType方式来寻找SchoolInfo这个类。
// 因为这里不存在info这个对象。所以就使用byType的方式来寻找SchoolInfo这个类/之后发现SchoolInfo
// 这个类中存在@Component这个注解,就可以创建出一个该类的对象。
@Resource
private SchoolInfo info;
@RequestMapping(value = "/data")
@ResponseBody
public String queryData2(){
return info.toString();
}
}
具体实现见项目:SpringBoot-custom-yml
1.4 SpringBoot中使用JSP
注意:在SpringBoot不建议使用JSP并且SpringBoot本身默认也不支持JSP,需要在pom.xml中导入JSP依赖。
如果只是使用JSP,加入JSP依赖即可。但是如果要使用servelt必须加入servlet依赖。
SpringBoot不推荐使用JSP,而是使用模板技术代替JSP
使用JSP需要配置:
- 加入一个处理JSP的依赖。负责编译JSP文件
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>10.1.0-M8</version>
</dependency>
- 如果需要其他依赖,还需要加入其他的依赖。比如:servlet...
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
</dependency>
-
创建一个存放JSP文件的目录,一般叫做webapp
当我们创建这个webapp文件夹的时候,就是一个普通的文件。此时需要在项目结构中来更改这个文件的属性,让这个文件变为web资源文件夹。
-
需要在pom.xml文件中指定JSP文件编译后的存放的目录。 META-INF/resources
<build>
<!-- 指定jsp文件编译之后的存放目录-->
<resources>
<resource>
<!-- jsp原来的目录-->
<directory>src/main/webapp</directory>
<!-- 指定编译后的存放目录-->
<targetPath>META-INF/resources</targetPath>
<!-- 指定处理的目录和文件 -->
<includes>
<include>**/*.*</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.2.2.RELEASE</version>
</plugin>
</plugins>
</build
- 创建Controller,访问JSP
@Controller
public class JspController {
public String doJsp(HttpServletRequest request){
// 将数据存储到request作用域中
request.setAttribute("data","SpringBoot使用了JSP");
// 试图的逻辑名称
return "index.jsp";
}
@RequestMapping(value = "/jsp")
// 此时这个String返回值代表的是视图,用于跳转界面。而不是简单的返回一个字符串
public String doJsp(Model model){
model.addAttribute("data","SpringBoot使用了JSP");
return "index.jsp";
}
}
- 在application.properties文件中配置试图解析器
server.port=8083
server.servlet.context-path=/myJsp
# 配置视图解析器
# 配置试图解析器前缀。/ 代表的是:src/main/webapp
spring.mvc.view.prefix=/
# 配置试图解析器后缀。 .jsp
spring.mvc.view.suffix=.jsp
1.5 SpringBoot中使用 ApplicationContext
- 在main方法中SpringApplication.run()方法获取返回的Spring容器对象,在获取业务bean进行调用。
- 通过SpringApplication.run(Application.class,args):返回值就是ApplicationContext容器。
1.6 CommandLineRunner接口
- 开发中可能会有这样的场景。需要在容器启动后执行一些内容。比如读取配置文件、数据库链接之类的。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为 CommandLineRunner和ApplicationRunner。他们的执行时机为容器启动完成的时候,这两个接口中有一个 run 方法,我们只需要实现这个方法即可。这两个接口的区别:ApplicationRunner中run方法的参数为:ApplicationArguments,而CommandLineRunner接口中run方法的参数为:String数组。
- 这两个接口中都有一个run方法,执行时间在容器对象那个创建好之后,自定执行run()方法。可以完成自定义的在容器对象创建好的一些操作。
@FunctionalInterface
public interface CommandLineRunner{
void run(String...args) yhrows Exception;
}
@FunctionalInterface
public interface ApplicationRunner{
void run(ApplicationArguments args) throws Exception;
}
2.第二章:SpringBoot的Web组件
2.1 拦截器
- 拦截器是SpringMVC中的一个对象,能拦截对Controller的请求。拦截器框架中有系统的拦截器,还可以自定义拦截器,实现对请求预先处理。
SpringMVC中实现自定义拦截器:
- 创建类实现SpringMVC框架的HandlerInterceptor接口
public interface HandlerInterceptor {
// 这个方法返回值是boolean类型。返回true时,可以进行处理。返回为false时,请求被拦截。
default boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return true;
}
default void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable ModelAndView modelAndView) throws Exception {
}
default void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, @Nullable Exception ex) throws Exception {
}
}
- 需在SpringMVC的配置文件中声明拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:path="url/>
<bean class="拦截器类全限定名称"/>
</mvc:interceptor>
</mvc:interceptors>
SpringBoot中实现自定义拦截器:
- 创建一个拦截器类
// 自定义拦截器
public class LoginInterceptor implements HandlerInterceptor {
/**
*
* @param request
* @param response
* @param handler 被拦截的控制器对象
* @return boolean
* true:请求能被 Controller处理
* false:请求被拦截
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("执行了拦截器的方法!");
return true;
}
}
- 将拦截器注入到Spring容器中。声明这个拦截器拦截/不拦截哪个请求地址。
@Configuration
public class MyAppConfig implements WebMvcConfigurer {
// 添加拦截器对象,注入到容器中
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 创建拦截器对象
HandlerInterceptor interceptor = new LoginInterceptor();
// 指定拦截的请求地址。这个代表以user开头的地址全部的拦截
String path [] = {"/user/**"};
// 指定不拦截的请求地址。
String excludePath [] = {"/user/login"};
// addInterceptor() :添加拦截器的方法
// addPathPatterns():添加拦截器拦截的路径的方法
// excludePathPatterns() : 添加拦截器忽略拦截路径的方法。
registry.addInterceptor(interceptor)
.addPathPatterns(path)
.excludePathPatterns(excludePath);
}
}
- 给定两个请求路径,测试拦截器是否起作用
@Controller
public class BootController {
@RequestMapping("/user/account")
@ResponseBody
public String userAccount(){
return "访问user/account地址";
}
@RequestMapping("/user/login")
@ResponseBody
public String userLogin(){
return "访问user/login地址";
}
}
- 启动SpringBoot的主启动类,请求Controller的请求路径测试是否可以被拦截
@SpringBootApplication
public class SpringBootInterceptorApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootInterceptorApplication.class, args);
}
}
2.2 SpringBoot中使用Servlet
- ServletRegistrationBean用来做servlet3.0+容器中注册servlet的功能,但更具有SpringBoot的友好性。
SpringBoot中使用Servlet步骤:
- 定义一个Servlet
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 使用HttpServletResponse输出数据,应答结果
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("执行的是Servlet");
out.flush();;
out.close();
}
}
- 注册一个Servlet对象
@Configuration
public class WebApplicationConfig {
// 定义方法,注册Servlet对象
@Bean
public ServletRegistrationBean servletRegistrationBean(){
// public ServletRegistrationBean(T servlet,String... urlMappings)
// 第一个参数是 Servlet对象,第二个是url地址
ServletRegistrationBean bean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
return bean;
}
}
2.3 SpringBoot中注册 Filter
- Filter是Servlet规范中的过滤器,可以处理请i去,对请求的参数、属性进行调整。常常在过滤器中处理字符编码。
- SpringBoot中使用 FilterRegistrationBean来注册Filter对象
SpringBoot中使用Filter过滤器
- 创建自定义过滤器类
// 自定义过滤器
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("执行了MyFilter");
filterChain.doFilter(servletRequest,servletResponse);
}
}
- 将自定义的过滤器引入到spirng容器中
// 将自定义的过滤器配置到spring容器中
@Configuration
public class WebApplicationConfig {
public FilterRegistrationBean filterRegistrationBean(){
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new MyFilter());
bean.addUrlPatterns("/user/*");
return bean;
}
}
- 在Controller中使用过滤器来处理请求
@Controller
public class MyController {
@RequestMapping("/user/account")
@ResponseBody
public String userAccount(){
return "/user/account";
}
}
转载自:https://juejin.cn/post/7055199170990178334