欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

SpringBoot实现任意位置获取HttpServletRequest对象

程序员文章站 2022-03-07 11:38:25
目录任意位置获取httpservletrequest对象方法一方法二httpservletrequest只能读取一次的解决任意位置获取httpservletrequest对象方法一//获取reques...

任意位置获取httpservletrequest对象

方法一

//获取requestattributes
 requestattributes requestattributes = requestcontextholder.getrequestattributes();
 //从获取requestattributes中获取httpservletrequest的信息
 httpservletrequest request = (httpservletrequest)requestattributes.resolvereference(requestattributes.reference_request);

方法二

servletrequestattributes attributes = (servletrequestattributes)requestcontextholder.getrequestattributes();
httpservletrequest request = attributes.getrequest();

httpservletrequest只能读取一次的解决

业务逻辑,通过filter读取请求的request,获取token,并将token传递后面流程使用

bodyreaderhttpservletrequestwrapper:

public class bodyreaderhttpservletrequestwrapper extends httpservletrequestwrapper {
    private final byte[] body;
    public bodyreaderhttpservletrequestwrapper(httpservletrequest request) throws ioexception {
        super(request);
        body = httphelper.getbodystring(request).getbytes(charset.forname("utf-8"));
    }
    @override
    public bufferedreader getreader() throws ioexception {
        return new bufferedreader(new inputstreamreader(getinputstream()));
    }
    @override
    public servletinputstream getinputstream() throws ioexception {
        final bytearrayinputstream bytearrayinputstream = new bytearrayinputstream(body);
        return new servletinputstream() {
            @override
            public int read() throws ioexception {
                return bytearrayinputstream.read();
            }
            @override
            public boolean isfinished() {
                return false;
            }
            @override
            public boolean isready() {
                return false;
            }
            @override
            public void setreadlistener(readlistener readlistener) {
            }
        };
    }
}

repeatreadfilter:

/**
 * 封装httpservletrequest为可重复读取请求
 **/
public class repeatreadfilter implements filter {
    @override
    public void init(filterconfig filterconfig) throws servletexception {
    }
    @override
    public void dofilter(servletrequest request, servletresponse response, filterchain chain)
            throws ioexception, servletexception {
        httpservletrequest httpservletrequest = (httpservletrequest) request;
        // 防止流读取一次后就没有了, 所以需要将流继续写出去
        servletrequest requestwrapper = new bodyreaderhttpservletrequestwrapper(httpservletrequest);
        //获取用户凭证
        string token = httpservletrequest.getheader(constants.user_token);
        if(stringutils.isblank(token)){
            token = httpservletrequest.getparameter(constants.user_token);
        }
        //=================获取json格式的token字段=========================
        string body = httphelper.getbodystring(requestwrapper);
        if (stringutils.isnotblank(body)) {
            jsonobject jsonobject = jsonobject.parseobject(body);
            object obj = jsonobject.get("token");
            if (null != obj) {
                token = obj.tostring();
            }
        }
        requestwrapper.setattribute(constants.user_token,token);
        chain.dofilter(requestwrapper, response);
    }
    @override
    public void destroy() {
    }
}

filterconfig:

@configuration
public class filterconfig {
    @bean
    public filterregistrationbean registfilter() {
        filterregistrationbean registration = new filterregistrationbean();
        registration.setfilter(new repeatreadfilter());
        registration.addurlpatterns("/app/*");
        registration.setname("urlfilter");
        registration.setorder(1);
        return registration;
    }
}

authorizationinterceptor:

@component
public class authorizationinterceptor extends handlerinterceptoradapter {
    @override
    public boolean prehandle(httpservletrequest request, httpservletresponse response, object handler) throws exception {
        authignore annotation;
        if(handler instanceof handlermethod) {
            annotation = ((handlermethod) handler).getmethodannotation(authignore.class);
        }else{
            return true;
        }
        //如果有@authignore注解,则不验证token
        if(annotation != null){
            return true;
        }
        //获取用户凭证
        string token = request.getheader(constants.user_token);
        if(stringutils.isblank(token)){
            token = request.getparameter(constants.user_token);
        }
        if(stringutils.isblank(token)){
            object obj = request.getattribute(constants.user_token);
            if(null!=obj){
                token=obj.tostring();
            }
        }
        //token凭证为空
        if(stringutils.isblank(token)){
            throw new authexception(constants.user_token + "不能为空", httpstatus.unauthorized.value());
        }
        return true;
    }
}

webmvcconfig:

@configuration
public class webmvcconfig extends webmvcconfigureradapter {
    @autowired
    private authorizationinterceptor authorizationinterceptor;
//    @autowired
//    private loginuserhandlermethodargumentresolver loginuserhandlermethodargumentresolver;
    @override
    public void addinterceptors(interceptorregistry registry) {
        registry.addinterceptor(authorizationinterceptor).addpathpatterns("/**");
        super.addinterceptors(registry);
    }
    @override
    public void addargumentresolvers(list<handlermethodargumentresolver> argumentresolvers) {
        //argumentresolvers.add(loginuserhandlermethodargumentresolver);
    }
    @override
    public void configuremessageconverters(list<httpmessageconverter<?>> converters) {
        super.configuremessageconverters(converters);
    }
    @override
    public void extendmessageconverters(list<httpmessageconverter<?>> converters) {
    }
}

在filter中读取token,在interceptor中进行读取判断使用

httphelper:

public class httphelper {
    /**
     * 获取请求body
     *
     * @param request
     * @return
     */
    public static string getbodystring(servletrequest request) {
        stringbuilder sb = new stringbuilder();
        inputstream inputstream = null;
        bufferedreader reader = null;
        try {
            inputstream = request.getinputstream();
            reader = new bufferedreader(new inputstreamreader(inputstream, charset.forname("utf-8")));
            string line = "";
            while ((line = reader.readline()) != null) {
                sb.append(line);
            }
        } catch (ioexception e) {
            e.printstacktrace();
        } finally {
            if (inputstream != null) {
                try {
                    inputstream.close();
                } catch (ioexception e) {
                    e.printstacktrace();
                }
            }
            if (reader != null) {
                try {
                    reader.close();
                } catch (ioexception e) {
                    e.printstacktrace();
                }
            }
        }
        return sb.tostring();
    }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。