案例拦截request
public class CheckLoginStatusFilter implements Filter{
private static final Logger LOGGER = LoggerFactory.getLogger(CheckLoginStatusFilter.class);
// web容器启动时init 方法。init 方法在 Filter 生命周期中仅被执行一次
// 实例化后一直存在于内存中
@Override
public void init(FilterConfig filterConfig) {
LOGGER.info("CheckLoginStatusFilter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request =(HttpServletRequest)servletRequest;
HttpServletResponse response =(HttpServletResponse) servletResponse;
Object session = request.getSession().getAttribute(CAS_IS_VERIFY);
if(session == null){
String header = request.getHeader("X-Requested-With");
if ("XMLHttpRequest".equals(header)){
returnErrorMessage(response,"sessionIsNull","session is Null");
}else {
// 静态页面的处理
request.getSession().setAttribute("_const_cas_assertion_",null);
filterChain.doFilter(servletRequest,servletResponse);
}
}else {
filterChain.doFilter(servletRequest,servletResponse);
}
}
// Web 容器卸载 Filter 对象之前被调用
@Override
public void destroy() {
LOGGER.info("CheckLoginStatusFilter destroy");
}
private void returnErrorMessage(HttpServletResponse response, String errorCode, String errorMessage) throws IOException {
Result<String> result = new Result<>(false);
result.setErrorCode(errorCode);
result.setErrorMessage(errorMessage);
response.setContentType("application/json");
PrintWriter out = response.getWriter();
JSONObject json = JSONObject.fromObject(result);
out.print(json.toString());
out.flush();
}
}
Filter
在 web.xml 注册了一个 Filter 来对某个 Servlet 程序进行拦截处理时,它可以决定是否将请求继续传递给 Servlet 程序,以及对请求和响应消息是否进行修改。
当 Servlet 容器开始调用某个 Servlet 程序时,如果发现已经注册了一个 Filter 程序来对该 Servlet 进行拦截,那么容器不再直接调用 Servlet 的 service 方法,而是调用 Filter 的 doFilter 方法,再由 doFilter 方法决定是否去激活 service 方法。
// 注册一个filter
<filter>
<filter-name>FirstFilter</filter-name>
<filter-class>FirstFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>GB2312</param-value>
</init-param>
</filter>
// 设置拦截器的作用特征
<filter-mapping>
<filter-name>FirstFilter</filter-name>
<servlet-name>default></servlet-name>
<dispatcher>INCLUDE</dispatcher>
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
web.xml注册filter拦截某个servlet->调用servlet时检测是否有filter->控制权交给filter的doFilter()->调用FilterChain.doFilter()->调用servlet的service
FilterChain 拦截链
当某个servlet在web.xml配置多个拦截器时,调用FilterChain.doFilter可以触发下一个拦截器的Filter.doFilter,拦截顺序与它们在 web.xml 文件中的映射顺序一致,最后一个执行servlet的service,任何一个没有调用FilterChain.doFilter则不会执行servlet的service
FilterConfig
获取ServletContext 对象,以及获取在 web.xml 文件中为 Filter 设置的友好名称和初始化参数
getFilterName 方法,返回 <filter-name> 元素的设置值。
getServletContext 方法,返回 FilterConfig 对象中所包装的 ServletContext 对象的引用。
getInitParameter 方法,用于返回在 web.xml 文件中为 Filter 所设置的某个名称的初始化的参数值。
getInitParameterNames 方法,返回一个 Enumeration 集合对象。
springboot中基于注解的配置
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;=
@Configuration
public class FilterConfig {
@Bean
public FilterRegistrationBean authFilterRegistrationBean() {
// 添加自定义的拦截器
FilterRegistrationBean registrationBean = new FilterRegistrationBean(new ParameterCheckFilter());
registrationBean.setName("parameterCheckFilter");
registrationBean.setFilter(new ParameterCheckFilter());
registrationBean.setOrder(1);
registrationBean.addUrlPatterns("/*");
return registrationBean;
}
}
案例拦截response
@Configuration
public class WebConfigurer extends WebMvcConfigurationSupport {
private final Logger logger = LoggerFactory.getLogger(WebConfigurer.class);
@RestControllerAdvice
public class ResponseBodyAnalysis implements ResponseBodyAdvice {
@Override
public Object beforeBodyWrite(Object body, MethodParameter methodParameter,
MediaType mediaType, Class arg3, ServerHttpRequest request,
ServerHttpResponse response) {
HttpHeaders httpHeaders = response.getHeaders();
if ( !httpHeaders.containsKey("currentPage") &&
!httpHeaders.containsKey("pageSize")){
// 如果不同时包含这两个值,则说明该返回数据不同分页
return body;
}
try {
Integer currentPage = Integer.valueOf(httpHeaders.get("currentPage").get(0));
Integer pageSize = Integer.valueOf(httpHeaders.get("pageSize").get(0));
ResultBean resultBean = (ResultBean)body;
PageBean pageBean = new PageBean(currentPage,pageSize,(List<Object>)resultBean.getData());
resultBean.setData(pageBean);
return resultBean;
}catch (ClassCastException castException){
return body;
}catch (Exception e){
throw new CustomException(CodeEnum.FAIL.getCode(),e.getMessage());
}
}
@Override
public boolean supports(MethodParameter methodParameter, Class arg) {
return true;
}
}
网友评论