前后端分离开发,如果入参是json对象时,在controller中,使用@RequestBody加对象形式,会将入参映射到对应字段上;如果要对请求加拦截校验,验证入参是否带有特定参数,使用request.getParameter("key")来获取参数是无法实现的;如果想要获取参数,我们应该使用数据流来实现,但是会存在问题,就是数据流只能使用一次,request.getInputStream()只能读取一次的解决方案,因为当拦截器使用了request.getInputStream()后,controller中对象将无法映射。
代码实现如下:controller获取json对象,拦截器中验证参数是否传入
拦截器代码:
package com.test.interceptor;
import com.alibaba.fastjson.JSON;
import com.demo.common.util.StringUtils;
import com.demo.util.MD5Util;
import com.demo.common.result.base.Helper;
import com.demo.common.result.enums.CodeEnum;
import lombok.Data;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StreamUtils;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.nio.charset.Charset;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
/**
* @description: 拦截器
* @author: feng
* @create: 2018
**/
@Data
public class AuthInterceptor implements HandlerInterceptor {
private static final Logger LOGGER = LoggerFactory.getLogger(AuthInterceptor.class);
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String auth = request.getParameter("auth");
//request.getParameter获取参数
if(Objects.isNull(auth)){
//获取数据流
String s = StreamUtils.copyToString(request.getInputStream(), Charset.forName("UTF-8"));
if (StringUtils.isEmpty(s)) {
//检验数据是否为空
String json = JSON.toJSONString(Helper.setResultData(ResultCodeEnum.BAD_REQUEST_FORBIDDEN_FALSE_CHANNEL,
"参数auth为空。"));
returnJson(response, json);
return false;
}
//将json字符串转成map
Map map = JSON.parseObject(s, Map.class);
Set set = map.keySet();
Iterator iterator = set.iterator();
//从map中获取参数进行校验 可以使用map.get("auth")来进行校验
while(iterator.hasNext()){
String att = (String)iterator.next();
if(Objects.equals(att,"auth") && Objects.isNull(map.get(att))){
String json = JSON.toJSONString(Helper.setResultData(CodeEnum.BAD_REQUEST_FORBIDDEN_FALSE_CHANNEL,
"参数auth为空。"));
returnJson(response, json);
return false;
} else if(Objects.equals(att,"auth")) {
auth =map.get(att).toString();
break;
}
}
}
//拆分
if (auth.contains("_")) {
auth = auth.split("_")[0];
}
//对入参进行权限校验
if(MD5Util.validate(auth))
return true;
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
private void returnJson(HttpServletResponse response, String json) {
PrintWriter writer = null;
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=utf-8");
try {
writer = response.getWriter();
writer.print(json);
} catch (IOException e) {
LOGGER.error("response error:{}",e);
} finally {
if (writer != null)
writer.close();
}
}
}
request.getInputStream()只能读取一次的解决方案: