SpringBoot和web组件
本篇讲解三个内容,分别为拦截器,Servlet,Filter
拦截器
拦截器是SpringMVC中的一种对象,能拦截对Controller的请求
框架中有系统的拦截器,还可以自定义拦截器,实现对请求的预先处理.
SpringMVC中实现自定义拦截器
- 创建类实现SpringMVC框架的HandlerInterceptor接口
该接口的信息如下 :
public interface HandlerInterceptor {
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 {
}
}
有三个的方法,最常用的是第一个方法preHandle
preHandle这个方法可以实现对请求的拦截和预先处理,返回布尔值,如果是true表示通过拦截器的验证,能被处理,反之请求到这里就截止了.
- 需要在SpringMVC的配置文件中声明拦截器
<mvc:interceptors>
<mvc:interceptor>
<mvc:path="url">
<bean class="拦截器类的全限定名称">
</mvc:interceptor>
</mvc:interceptors>
上面的代码表示当用户访问url时,会先去拦截器判断一下是否拦截,需要提供拦截器类的class
在SpringBoot中使用拦截器可以将上面xml文件的配置信息变成一个类
先看文件结构
- 自定义拦截器对象
LoginInterceptor,该对象实现了接口HandlerInterceptor,表示对象是一个拦截器,需要重写其中preHandle方法来表示拦截逻辑
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 自定义拦截器
*/
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;
}
}
- 编写配置对象,该对象配置了拦截器和需要拦截的url以及不需要拦截的url
@Configuration注解表示这个对象为一个配置对象,必须添加
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.zjb.web.LoginInterceptor;
@Configuration
public class MyAppConfig implements WebMvcConfigurer {
// 该方法的作用为添加拦截器对象,注入到容器中
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 创建拦截器对象
HandlerInterceptor interceptor = new LoginInterceptor();
// 指定拦截的请求url地址
String[] path = {"/user/**"};
// 指定不拦截的请求url地址
String[] excludePath = {"/user/login"};
registry.addInterceptor(interceptor).
addPathPatterns(path).
excludePathPatterns(excludePath);
}
}
- 视图层
该类中有两个方法,分别访问不同的url,根据配置对象中的拦截逻辑,/user/account被拦截,/user/login不被拦截
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class BootController {
@RequestMapping("/user/account")
@ResponseBody
public String userAccount() {
return "访问user/account地址";
}
@RequestMapping("/user/login")
@ResponseBody
public String userLogin() {
return "访问user/login地址";
}
}
- 测试
访问/user/account时拦截器中preHandle()方法执行,始终返回true,并没有拦住.
访问user/login时不被拦截
servlet
在springBoot框架中使用Servlet对象
之前的使用步骤是 :
- 创建Servlet类,创建类继承HttpServlet
- 注册Servlet实现类,注入容器,让框架能够找到
在SpringBoot中使用servlet步骤如下 :
文件结构如下 :
- 创建Servlet实现类,继承HttpServlet,实现doGet或者doPost方法
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
public class MyServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
this.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();
}
}
- 创建配置类
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.zjb.web.MyServlet;
@Configuration
public class webApplicationConfig {
@Bean
// 定义方法, 注册Servlet对象
public ServletRegistrationBean servletRegistrationBean() {
// ServletRegistrationBean(T servlet, String... urlMappings)
// 第一个参数是servlet对象,第二个参数是url地址
ServletRegistrationBean bean = new ServletRegistrationBean(new MyServlet(),
"/myservlet");
return bean;
}
}
- 该类由@Configuration修饰,表示该类等价一个配置文件
- servletRegistrationBean()方法返回的是一个bean对象,该bean对象就是一个servlet
- servletRegistrationBean()方法需要由@Bean修饰,表示需要自动创建对象
- ServletRegistrationBean(T servlet, String… urlMappings)方法有两个参数,第一个是servlet实体类对象,第二个是该servlet对应的路径的集合(第二个参数是可变长参数,等价于数组)
也可以使用无参构造来代替两个参数的构造方法.
ServletRegistrationBean bean = new ServletRegistrationBean();
bean.setServlet(new MyServlet());
bean.addUrlMappings("/login", "/login1");
- 结果展示
过滤器
Filter是过滤器,可以处理请求,对请求的参数属性进行跳转,我们常常在过滤器中处理字符编码
创建方式和Servlet十分的类似
也是先创建Filter对象,之后在通过FilterRegistrationBean来注册Filter对象
文件结构如下 :
步骤如下 :
- 先创建过滤器对象MyFilter类
import javax.servlet.*;
import java.io.IOException;
// 自定义过滤器
public class MyFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("执行了MyFilter, doFilter");
filterChain.doFilter(servletRequest, servletResponse);
}
}
- 注册过滤器,即编写配置文件对应的类WebApplicationConfig
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.zjb.web.MyFilter;
@Configuration
public class WebApplicationConfig {
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new MyFilter());
bean.addUrlPatterns("/user/*");
return bean;
}
}
- 编写视图层
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class CustomFilterController {
@RequestMapping("/user/account")
@ResponseBody
public String userAccount() {
return "user/account";
}
@RequestMapping("/query")
@ResponseBody
public String queryAccount() {
return "query";
}
}
- 检测结果
访问/user/account
访问/query
字符集过滤器
CharacterEncodingFilter : 是解决post请求中的乱码问题.
在SpringMVC框架中,在web.xml中注册过滤器,配置其属性.
还是直接给出例子 :
文件结构为 :
- 先编写servlet
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
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 {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("在Servlet中输出中文,查看是否有乱码");
out.flush();
out.close();
}
}
- 编写配置类,注册servlet和字符集过滤器
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.zjb.web.MyServlet;
@Configuration
public class WebConfig {
// 注册Servlet
@Bean
public ServletRegistrationBean servletRegistrationBean() {
MyServlet myServlet = new MyServlet();
ServletRegistrationBean reg = new ServletRegistrationBean(myServlet, "/myservlet");
return reg;
}
// 注册Filter
@Bean
public FilterRegistrationBean filterRegistrationBean() {
FilterRegistrationBean reg = new FilterRegistrationBean();
// 使用框架中原先就存在的字符集过滤器类
CharacterEncodingFilter filter = new CharacterEncodingFilter();
// 指定编码方式
filter.setEncoding("utf-8");
// 指定request, response都使用encoding的值
filter.setForceEncoding(true);
reg.setFilter(filter);
// 指定过滤的url地址
reg.addUrlPatterns("/*");
return reg;
}
}
- 在application.properties文件中关闭默认的过滤器
server.port=8081
#在springboot中默认已经配置了字符集过滤器,默认为ISO-8859-1
#设置为false为关闭默认的过滤器
server.servlet.encoding.enabled=false
- 查看结果
没有乱码,非常nice
除了上面的方法,还有一种方法,我们在上面的第三步说了,实际上SpringBoot中有默认的字符编码集过滤器,实际上我们可以通过直接修改默认的过滤器来完成这个操作
只需要在application.properties文件中进行配置即可
#使用系统自己的过滤器,默认就为true,可省略
server.servlet.encoding.enabled=true
#指定使用的编码方式
server.servlet.encoding.charset=utf-8
#强制request.response都使用charset属性的值
server.servlet.encoding.force=true
完成了这个操作就不用注册Filter了