• spring boot 解决 @RequestBody只能读取一次的问题(代码部分)


      

    import com.alibaba.fastjson.JSON;
    import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
    import com.yicheplatform.shenzhen.constant.RedisConstants;
    import com.yicheplatform.shenzhen.pojo.po.SysApiuser;
    import com.yicheplatform.shenzhen.service.ISysApiuserService;
    import com.yicheplatform.shenzhen.utils.ServletUtil;
    import org.apache.commons.lang3.StringUtils;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.stereotype.Component;
    import org.springframework.web.servlet.HandlerInterceptor;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.Map;
    import static com.yicheplatform.shenzhen.exception.ErrorCodeEnum.getDesc;
    import static com.yicheplatform.shenzhen.interceptor.ResponseData.buildStateFail;
    import static com.yicheplatform.shenzhen.interceptor.SignUtils.getSign;
    import static com.yicheplatform.shenzhen.interceptor.SignUtils.sortByKey;
    import static com.yicheplatform.shenzhen.utils.MapAndStringUtils.getStringToMap;
    import static com.yicheplatform.shenzhen.utils.MapRemoveNullUtil.removeNullValue;

    /**
    * @author puxiaozhe
    * @description sign验证
    * @date 2020-08-08
    **/
    @Component
    public class SignInterceptor implements HandlerInterceptor {

    private static final Logger log = LoggerFactory.getLogger("SignInterceptor");

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private ISysApiuserService iSysApiuserService;

    /**
    * @param request:请求对象
    * @param response:响应对象
    * @param handler:处理对象:controller中的信息
    * @throws Exception
    * @return:true表示正常,false表示被拦截
    */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler){


    // 获取body信息转换为Map
    Map<String, String> newMap = null;
    newMap = getStringToMap(getBody(request));

    // 依次检查传入值是否存在
    String appId = newMap.get("appId");
    if (StringUtils.isBlank(appId)) {
    ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildFail("appId 参数未传入")));
    return false;
    }
    String comId = newMap.get("comId");
    if (StringUtils.isBlank(comId)) {
    ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildFail("comId 参数未传入")));
    return false;
    }
    String sign = newMap.get("sign");
    if (StringUtils.isBlank(sign)) {
    ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildFail("sign 签名未传入")));
    return false;
    }
    // 查询缓存中的值
    StringBuffer redisKey = new StringBuffer(RedisConstants.REDIS_KEY_API_USER).append(":").append(appId).append(":").append(comId);
    log.info("//缓存key值:" + redisKey);
    String secretKey = (String) redisTemplate.opsForValue().get(redisKey);
    String signEncrypt = null;
    // 获取ve参数
    String ve = newMap.get("ve");
    // 移除map中空的value值
    removeNullValue(newMap);
    if (null == secretKey) {
    // 数据库中查询私钥
    SysApiuser oldApiUser = iSysApiuserService.getOne(new QueryWrapper<SysApiuser>().lambda().eq(SysApiuser::getAppid, appId).eq(SysApiuser::getComid, comId));
    if (null != oldApiUser) {
    // 针对传进的map排序
    Map<String, String> signEncryptMap = sortByKey(newMap, ve);
    // 获取签名
    signEncrypt = getSign(signEncryptMap, oldApiUser.getSecretkey());
    log.info("signEncrypt 添加至缓存,key:" + redisKey + ",value:" + oldApiUser.getSecretkey());
    redisTemplate.opsForValue().set(redisKey, oldApiUser.getSecretkey());
    //后端MD5签名校验与前端签名sign值比对
    if (!signEncrypt.equals(sign)) {
    log.info("签名失败,请核实");
    ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildFail("签名失败,请核实")));
    return false;
    }
    } else {
    log.info("数据库表中未配置相关用户的信息");
    ServletUtil.renderString(response, JSON.toJSONString(ResponseData.buildFail("数据库表中未配置相关用户的信息")));
    return false;
    }
    } else {
    // 针对传进的map排序
    Map<String, String> signEncryptMap = sortByKey(newMap, ve);
    // 获取签名
    signEncrypt = getSign(signEncryptMap, secretKey);
    //后端MD5签名校验与前端签名sign值比对
    if ( null != signEncrypt && !signEncrypt.equals(sign)) {
    log.info(getDesc(0x02) + " 签名失败,请核实");
    ServletUtil.renderString(response, JSON.toJSONString(buildStateFail(getDesc(0x02) + " 签名失败,请核实")));
    return false;
    }
    }
    return true;
    }

    /**
    * 获取body信息
    * @param request
    * @return
    */
    private String getBody(HttpServletRequest request) {
    InputStream is = null;
    StringBuilder sb = new StringBuilder();
    try {
    is = request.getInputStream();
    byte[] b = new byte[4096];
    for (int n; (n = is.read(b)) != -1; ) {
    sb.append(new String(b, 0, n));
    }
    } catch (IOException e) {
    e.printStackTrace();
    }
    return sb.toString();
    }
    }


    ——————————————————————————————————————————————————————————————————————————————————————————————



    import com.yicheplatform.shenzhen.utils.CharsetUtils;
    import com.yicheplatform.shenzhen.utils.MD5;
    import org.springframework.util.StringUtils;
    import org.springframework.web.util.UriUtils;

    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.ObjectOutputStream;
    import java.nio.charset.StandardCharsets;
    import java.util.*;


    public class SignUtils {

    /**
    * 获取key的方法
    *
    * @param inMap
    * @param keys
    * @return
    */
    private static StringBuffer getKeys(Map<String, String> inMap, List<String> keys) {

    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < keys.size(); i++) {
    String key = keys.get(i);
    if (!key.equals("sign") && !StringUtils.isEmpty(key)) {
    String value = null;
    Object bytes = null;
    boolean bl = false;
    if (inMap.get(key) instanceof String) {
    value = inMap.get(key);
    } else {
    bytes = inMap.get(key);
    bl = true;
    }
    sb.append(key);
    sb.append("=");
    if (bl) {
    sb.append(bytes);
    } else {
    sb.append(value == null ? "" : value);
    }
    sb.append("&");
    }
    }
    return sb;
    }


    /**
    * ascii 值升序排列
    *
    * @param map
    * @return
    */
    public static Map<String, String> sortByKey(Map<String, String> map, String ve) {
    //创建一个带有比较器的TreeMap
    Map<String, String> treeMap = new TreeMap<>(String::compareTo);
    //是否需要对参数进行编码
    if (ve != null && ve.equals("1")) {
    for (Map.Entry<String, String> entry : map.entrySet()) {
    String key = urlEncode(entry.getKey());
    treeMap.put(key, entry.getValue());
    }
    } else {
    //将你的map传入treeMap
    treeMap.putAll(map);
    }
    return treeMap;
    }

    /**
    * 获取sign 签名
    *
    * @param inMap
    * @param secretKey
    * @return
    */
    public static String getSign(Map<String, String> inMap, String secretKey) {
    List<String> keys = new ArrayList<String>(inMap.keySet());
    Collections.sort(keys);
    StringBuffer sb = null;
    sb = getKeys(inMap, keys);
    sb.append("requestKey").append("=").append(secretKey);
    String sign = MD5.MD5Encode(sb.toString(), CharsetUtils.utf);
    return sign;
    }

    /**
    * 是否需要对参数进行编码
    *
    * @param source
    * @return
    */
    public static String urlEncode(String source) {
    return UriUtils.encode(source, StandardCharsets.UTF_8);
    }


    /**
    * Object 转数组
    *
    * @param obj
    * @return
    */
    public static byte[] toByteArray(Object obj) {
    byte[] bytes = null;
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    try {
    ObjectOutputStream oos = new ObjectOutputStream(bos);
    oos.writeObject(obj);
    oos.flush();
    bytes = bos.toByteArray();
    oos.close();
    bos.close();
    } catch (IOException ex) {
    ex.printStackTrace();
    }
    return bytes;
    }


    public static void main(String[] args) {

    // System.out.println(urlEncode("傻瓜蛋bbbbsadghthas"));
    // Map<String,String> map = new HashMap<>();
    // map.put("digaln", "1");
    // map.put("adgdge", "hello");
    // map.put("fgfg", "abc");
    // map.put("啥", "455456");
    // map.put("zff", "72");
    // map.put("sgfsge", "4242");
    // map.put("bgsof", "424");
    // System.out.println("排序前:" + map);
    // Map<String, String> s = sortByKey(map,"2");
    // String sign = getSign(s,"dgoigjoihagooaeag");
    // System.out.println("排序后:" + s );

    }

    }


    ——————————————————————————————————————————————————————————————————————————————————————————————


    import org.springframework.stereotype.Component;

    import javax.servlet.*;
    import javax.servlet.annotation.WebFilter;
    import javax.servlet.http.HttpServletRequest;
    import java.io.IOException;


    /**
    * @author puxiaozhe
    * @description 继承过滤器
    * @date 2020-08-12
    **/
    @Component
    @WebFilter(filterName="HttpServletRequestReplacedFilter",urlPatterns="/*")
    public class HttpServletRequestReplacedFilter implements Filter {


    @Override
    public void init(FilterConfig arg0) throws ServletException {

    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    ServletRequest requestWrapper = null;
    if (request instanceof HttpServletRequest) {
    requestWrapper = new RequestReaderHttpServletRequestWrapper((HttpServletRequest) request);
    }
    //获取请求中的流如何,将取出来的字符串,再次转换成流,然后把它放入到新request对象中。
    // 在chain.doFiler方法中传递新的request对象
    if (requestWrapper == null) {
    chain.doFilter(request, response);
    } else {
    chain.doFilter(requestWrapper, response);
    }
    }

    @Override
    public void destroy() {

    }
    }


    ——————————————————————————————————————————————————————————————————————————————————————————————



    import org.springframework.util.StreamUtils;

    import javax.servlet.ReadListener;
    import javax.servlet.ServletInputStream;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletRequestWrapper;
    import java.io.BufferedReader;
    import java.io.ByteArrayInputStream;
    import java.io.IOException;
    import java.io.InputStreamReader;

    /**
    * @author puxiaozhe
    * @description 继承HttpServletRequestWrapper类
    * @date 2020-08-12
    **/
    public class RequestReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {

    private byte[] requestBody = null;//用于将流保存下来

    public RequestReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException{
    super(request);
    requestBody = StreamUtils.copyToByteArray(request.getInputStream());
    }

    @Override
    public ServletInputStream getInputStream() throws IOException {

    final ByteArrayInputStream bais = new ByteArrayInputStream(requestBody);

    return new ServletInputStream() {

    @Override
    public int read() throws IOException {
    return bais.read();
    }

    @Override
    public boolean isFinished() {
    return false;
    }

    @Override
    public boolean isReady() {
    return false;
    }

    @Override
    public void setReadListener(ReadListener readListener) {

    }
    };
    }

    @Override
    public BufferedReader getReader() throws IOException{
    return new BufferedReader(new InputStreamReader(getInputStream()));
    }

    }


    import com.yicheplatform.shenzhen.utils.ClientUtils;
    import lombok.Data;

    import java.io.Serializable;

    /**
    * @Description:
    * @Author: zhangdonghai
    * @Date: Create in 2020/6/29
    */
    @Data
    public class ResponseData<T> implements Serializable {

    private static final long serialVersionUID = 1L;

    private String message;//错误提示中文

    private T obj;//数据信息/错误详细信息

    private Integer state;

    public ResponseData() {
    }

    public ResponseData(String msg, Integer state, Object result) {
    }

    public ResponseData(Integer state, String message, T obj) {
    this.state = state;
    this.message = message;
    this.obj = obj;
    }

    public static ResponseData buildOk() {
    return new ResponseData(ClientUtils.STATE_SUCCESS, ClientUtils.OK_MSG, null);
    }

    public static ResponseData buildOk(String msg) {
    return new ResponseData(ClientUtils.STATE_SUCCESS, msg, null);
    }

    public static ResponseData buildOk(String msg, Object obj) {
    return new ResponseData(ClientUtils.STATE_SUCCESS, msg, obj);
    }

    public static ResponseData buildOk(Object result) {
    return new ResponseData(ClientUtils.STATE_SUCCESS, ClientUtils.OK_MSG, result);
    }

    public static ResponseData buildFail(String message,int state,Object o) {
    return new ResponseData( message, ClientUtils.STATE_FAIL, null);

    }

    public static ResponseData buildStateFail(String message) {
    return new ResponseData(ClientUtils.STATE_SYSTEM_ERROR,message,null);
    }

    public static ResponseData buildFail(String msg) {
    return new ResponseData(ClientUtils.STATE_FAIL, msg, null);
    }

    public static ResponseData buildFail(String msg, Object result) {
    return new ResponseData(ClientUtils.STATE_FAIL, msg, result);
    }

    public static ResponseData buildFail(int state, String msg,Object o) {
    return new ResponseData(ClientUtils.STATE_FAIL, msg, null);
    }

    public static ResponseData buildFail(String msg, Integer state, Object result) {
    return new ResponseData(msg, ClientUtils.STATE_FAIL, result);
    }

    public String getMessage() {
    return message;
    }

    public void setMessage(String message) {
    this.message = message;
    }

    public T getObj() {
    return obj;
    }

    public void setObj(T obj) {
    this.obj = obj;
    }

    }




  • 相关阅读:
    sql注入漏洞与防范
    微信小程序-工具,弹出当前系统代理不是安全代理处理方法
    微信小程序-02 小程序关注组件
    微信小程序-01 小数保留二位
    http 转hhttps
    php 函数-ksort
    iOS 原生二维码扫描
    iOS 打包错误 all-product-headers.yaml' not found
    iOS Tableview点击cell 会往上跳
    WKWebView 使用
  • 原文地址:https://www.cnblogs.com/pxzbky/p/13498818.html
Copyright © 2020-2023  润新知