自定义springweb拦截器
一种实现方式:继承HandlerInterceptorAdapter类,该类有四种方法;
- boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) 返回布尔类型,在请求执行前进行拦截处理.有很多interceptor,但hanlder是排在最后的,必须通过之前的拦截器处理才行.
如果有异常,或自定义返回的response,handler链将无法执行.
-
void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)throws Exception; 在请求被handler处理之后,在DispatcherServlet渲染视图之前进行拦截.可以获得ModelAndView模型,抛出异常可以让执行链中断; 执行顺序与拦截器注册顺序相反.
-
afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception 这个要在执行链完成之后处理,准确的是在视图渲染之后执行; 注:该方法只有在所有的拦截器成功执行并返回视图之后执行,且顺序与拦截器注册的顺序相反.
-
void afterConcurrentHandlingStarted(HttpServletRequest request, HttpServletResponse response, Object handler)throws Exception; 是一个异步的方法,可以替代方法2和3,但尽量不要改变request和reponse,以免发生线程冲突. 典型使用环境,清楚线程变量(A typical use of this method would be to clean up thread-local variables);
我需要在hanler执行之前获取请求参数的userId,所以只是用preHandle()方法.
代码如下:
public class UserFilter extends HandlerInterceptorAdapter {
// 存放用户id
static ThreadLocal<String> userLocal = new ThreadLocal<>();
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
/* if (request.getRequestURI().indexOf("/cart/") == 0) {
String userId = request.getParameter("userId");
userLocal.set(userId);
}
*/
String userId = request.getParameter("userId");
userLocal.set(userId);
return true;
}
}
这里用了个默认修饰符的静态变量,可以使别的包无法获取该静态变量.
下面我们需要注册这个拦截器,springboot下如此注册,创建一个类,继承了WebMvcConfigurerAdapter配置,里面有个方法,用来注册自定义拦截器,并可以为该项添加匹配路径addPathPatterns;拦截所有是/**,这里设置的需要拦截的url.
@Configuration
public class CartWebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new UserFilter()).addPathPatterns("/cart/**");
}
}
当然还有其他用法,不过没有认真涉及.
如何实现restful跳转
大部分使用springmvc,要实现restful风格的http请求.可以通过获取HttpServletResponse对象来获取,然后输出json.
/* * Created by on 2017/3/23.
*
* @
*/
import com.alibaba.fastjson.JSON;
import com.netflix.discovery.EurekaClient;
import com.sanji.mall.common.util.*;
import com.sanji.mall.members.service.MemberService;
import com.sanji.mall.model.Members;
import com.sanji.mall.model.OrderSignFor;
import com.sanji.mall.yworder.service.OrderSignForService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Date;
import java.util.List;
/**
* @author yangqc
* User: yangqc
* Date: 2017/3/23
* Time: 10:13
* @Description
* @since 1.0
*/
@Component("appUserFilter")
public class AppUserFilter extends HandlerInterceptorAdapter {
@Autowired
private EurekaClient eurekaClient;
@Autowired
private OrderSignForService orderService;
@Resource
private MemberService memberService;
private static final Logger logger = Logger.getLogger(AppUserFilter.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
if (request.getMethod().equals("POST")) {
String userId = request.getParameter("userId");
if (null == userId || userId.equals("")) {
userId = request.getParameter("memberId");
}
Members member = memberService.gainMembersDetailById(userId);
String mobile;
if (null == member && request.getRequestURI().contains("/login/check")) {
mobile = request.getParameter("username");
} else if (null == member) {
return true;
} else {
mobile = member.getMobile();
}
//白名单
// if (!filterWhiteList(mobile)) {
// writeJson(response, ResponseFactory.getFailed("没在白名单中!!"));
// return false;
// }
//支付超时
if (!filterUnpayedOrder(mobile)) {
writeJson(response, ResponseFactory.getFailed("有订单超时支付,功能暂时关闭,请联系业务员付款!!"));
return false;
}
}
} catch (Exception e) {
logger.error("app拦截器报错!", e);
writeJson(response, ResponseFactory.getFailed("拦截器出错-->" + e.getLocalizedMessage()));
return false;
}
return true;
}
/**
* 根据手机号判断是否在黑名单中
*
* @param mobile 手机号
* @return 是否通过黑名单验证
*/
public boolean filterUnpayedOrder(String mobile) {
Date loginDay = new Date();//业务员登陆时间
String loginDayStr = DateUtil.getStringByDate(loginDay, "yyyy-MM-dd");
Date loginDay12 = DateUtil.getDateStrToDate(loginDayStr + " 12:00", "yyyy-MM-dd HH:mm");//登陆当日的12:00
Date yesterday = DateUtil.getAnotherDate(loginDay, -1);//业务员登陆的前一天
String yesterdayStr = DateUtil.getStringByDate(yesterday, "yyyy-MM-dd");
String yesterdayStr12 = yesterdayStr + " 12:00";//前一天12:00
String yesterdayStr24 = yesterdayStr + " 23:59";//前一天24:00
//12点以前登陆
if (!DateUtil.compareDate(loginDay12, loginDay)) {
//查询昨天12:00之前是否有未付款订单,有就不行
List<OrderSignFor> orderSignFors = orderService.findByMobile(mobile, yesterdayStr12);
if (CollectionUtils.isEmpty(orderSignFors)) {
return true;
}
} else {
//查询昨天24:00之前是否有未付款订单
List<OrderSignFor> orderSignFors = orderService.findByMobile(mobile, yesterdayStr24);
if (CollectionUtils.isEmpty(orderSignFors)) {
return true;
}
}
return false;
}
/**
* 根据手机号判断是否在白名单
*
* @param mobile 手机号
* @return 是否通过白名单验证
*/
public Boolean filterWhiteList(String mobile) {
String message = HttpClientUtils.sendGetRequest(EurekaUtils.getUrl(eurekaClient, "whitelist") + "get/NO_PAYMENT/" + mobile, null);
String status = (String) JsonUtil.getMap4Json(message).get("status");
Boolean result = (Boolean) JsonUtil.getMap4Json(message).get("result");
return "success".equals(status) && result;
}
// 将对象写成json扔到前台
public void writeJson(HttpServletResponse response, Object object) {
try {
String json = JSON.toJSONStringWithDateFormat(object, "yyyy-MM-dd HH:mm:ss");
response.setContentType("text/html;charset=utf-8");
response.getWriter().write(json);
response.getWriter().flush();
response.getWriter().close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
在其return false之前用response将相应内容用json输出,这样就可以了.