开发者

Springboot修改post请求接口入参或重新赋值方式

目录
  • 前言
    • BodyReaderHttpServletRequestWrapper
    • DefaultDataFillHandlerMethodArgumentResolver
    • UserDefaultDataFill
  • 总结

    前言

    很久之前写过一篇就是自动填充接口参数的,利用的 HandlerMethodArgumentResolver 自定义注解

    Springboot Controller接口默认自动填充 业务实体参数值

    现在这一篇也差不多,达到的目的就是重新去给post请求的参数赋值、修改啥的。

    不多说,开始。

    首先知道一点,post请求的参数,一旦取出来就没了,因为是流数据。

    所以老样子,我们写多一个HttpServletRequestWrapper :

    BodyReaderHttpServletRequestWrapper

    import org.apache.commons.lang3.StringUtils;
    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;
    import java.nio.charset.StandardCharsets;
    import java.util.Enumeration;
    import java.util.Map;
    import java.util.Vector;
    
    /**
     * @Author : JCccc
     * @CreateTime : 2020/3/27
     * @Description :
     **/
    public class BodyReaderHttpServletRequestWrapper extends HttpServletRequestWrapper {
    
        private final byte[] body;
    
        /**
         * 所有参数的集合
         */
        private Map<String, String[]> parameterMap;
    
    
        public BodyReaderHttpServletRequestWrapper(HttpServletRequest request) throws IOException {
            super(request);
            BufferedReader reader = request.getReader();
            body = readBytes(reader);
            parameterMap = request.getParameterMap();
        }
    
    
        @Override
        public BufferedReader getReader() throws IOException {
    
            ServletInputStream inputStream = getInputStream();
    
            if (null == inputStream) {
                return null;
            }
    
            return new BufferedReader(new InputStreamReader(inputStream));
        }
    
        @Override
        public Enumeration<String> getParameterNames() {
            Vector<String> vector = new Vector<>(parameterMap.keySet());
            return vector.elements();
        }
    
        @Override
        public ServletInputStream getInputStream() throws IOException {
    
            if (body == null) {
                return null;
            }
    
            final ByteArrayInputStream bais = new ByteArrayInputStream(body);
            return new ServletInputStream() {
    
                @Override
                public boolean isFinished() {
                    return false;
                }
    
                @Override
                public boolean isReady() {
                    return false;
                }
    
                @Override
                public void setReadListener(ReadListener listener) {
    
                }
    
                @Override
                public intJTHQOsrYey read() throws IOException {
                    return baisandroid.read();
                }
            };
        }
    
        /**
         * 通过BufferedReader和字符编码集转换成byte数组
         *
         * @param br
         * @return
         * @throws IOException
         */
        private byte[] readBytes(BufferedReader br) throws IOException {
            String str;
            StringBuilder retStr = new StringBuilder();
            while ((str = br.readLine()) != null) {
                retStr.append(str);
            }
            if (StringUtils.isNotBlank(retStr.toString())) {
                return retStr.toString().getBytes(StandardCharsets.UTF_8);
            }
            return null;
        }
    }

    然后是我们这一期的核心,

    DefaultDataFillHandlerMethodArgumentResolver

    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONObject;
    import com.speediance.admin.auth.ShiroUtils;
    import com.speediance.admin.dto.req.UserDefaultDataFill;
    import org.springframework.beans.BeanUtils;
    import org.springframework.beans.BeanWrapper;
    import org.springframework.beans.BeanWrapphpperImpl;
    import org.springframework.core.MethodParameter;
    import org.springframework.stereotype.Component;
    import org.springframework.web.bind.support.WebDataBinderFactory;
    import org.springframework.web.context.request.NativeWebRequest;
    import org.springframework.web.method.support.HandlerMethodArgumentResolver;
    import org.springframework.web.method.support.ModelAndViewContainer;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.BufferedReader;
    import java.util.Date;
    import java.util.Objects;
    
    @Component
    public class DefaultDataFillHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    
        @Override
        public boolean supportsParameter(MethodParameter parameter) {
            return parameter.hASParameterAnnotation(UserDefaultDataFill.class);
        }
    
        @Override
        public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
                                      NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
            HttpServletRequest request = webRequest.getNativeRequest( HttpServletRequest.class );
            BodyReaderHttpServletRequestWrapper myRequestWrapper = new BodyReaderHttpServletRequestWrapper((HttpServletRequest) request);
            // 从Request的包装类中读取数据
            BufferedReader reader = myRequestWrapper.getReader();
            StringBuilder sb = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                sb.append(line);
            }
            reader.close();
            phpJSONObject jsonObject javascript= JSON.parseobject(sb.toString());
            Object bean = BeanUtils.instantiateClass(parameter.getParameterType());
            BeanWrapper beanWrapper = new BeanWrapperImpl(bean);
            //重新赋值
            for (String key : jsonObject.keySet()) {
                beanWrapper.setPropertyValue(key,jsonObject.get(key));
            }
            Long userId = //比如从数据库查出来 或者从token解析出来;
       
     
            //举例子给如入参自动填充 更新操作人
            beanWrapper.setPropertyValue("updateUserId", userId);
          
            return bean;
        }
    
    
    }

    然后就是重写一个自定义注解 ,相当于需要填充数据或者进入到参数修改,我们采用它标注:

    UserDefaultDataFill

    import java.lang.annotation.*;
    
    
    @Target(ElementType.PARAMETER)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    public @interface UserDefaultDataFill {
    
    }

    然后就OK了,看看怎么用:

    比如说一个更新接口,我们想默认填充上入参里面的 修改用户ID (简单举例,其余业务要修改值,赋值自己套用就可以)

    Springboot修改post请求接口入参或重新赋值方式

    Springboot修改post请求接口入参或重新赋值方式

    然后可以看到我们的参数解析器里面的代码 (其实就是复制流拿出参数,修改完变成当前接口的bean):

    Springboot修改post请求接口入参或重新赋值方式

    OK,就到这。

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜