前言
现在有一个需求场景:每一个请求我都需要在请求头里面加上token这个请求头,作为一种校验机制,传统的接口可以通过设置一个全局的变量,然后通过页面携带过来(大概就是先将我们的token放在session中,写一个服务用来获取session中的token,然后主页面用 ajax 调用接口,将 token放在隐藏域中,然后将请求头放进来,用 ajax 方法,这里不想细说了),但是有一个情况是通过页面传递的并不一定都会适用所有接口,比如上传和下载的接口有时候请求头里面就没有token 参数,可能是上传和下载是用表单提交的。
这个时候如何将请求头通过后台的方法加进来?
想到用过滤器,用后台方法强制加入请求头。
我这里加的是将用户唯一标识加在请求头上,并在自己需要的时候自己获取
1.创建拦截器
核心代码为 addheader方法,将userid添加到请求头中
package com.kaying.luck.interceptor;
import com.kaying.luck.dao.draw.user.userdao;
import com.kaying.luck.exception.serviceexception;
import com.kaying.luck.pojo.draw.user.dos.userdo;
import com.kaying.luck.response.enums.apiresponsecodeenum;
import com.kaying.luck.utils.applicationcontext.myapplicationcontext;
import org.apache.commons.lang3.stringutils;
import org.apache.tomcat.util.http.mimeheaders;
import org.springframework.beans.factory.annotation.autowired;
import org.springframework.stereotype.component;
import org.springframework.web.servlet.handlerinterceptor;
import org.springframework.web.servlet.modelandview;
import javax.servlet.http.httpservletrequest;
import javax.servlet.http.httpservletresponse;
import java.lang.reflect.field;
import java.util.hashmap;
import java.util.map;
/**
* @author csp
* @create 2021-11-23 14:54
* @description
*/
@component
public class baseinterceptor implements handlerinterceptor {
@autowired
private userdao userdao = myapplicationcontext.getbean(userdao.class);
@override
public boolean prehandle(httpservletrequest request, httpservletresponse response, object o) throws exception {
string userid = request.getheader("userid");
if (stringutils.isblank(userid)){
throw new serviceexception(apiresponsecodeenum.error_user_id, "未查询到用户信息");
}
userdo userdo = userdao.getuserbyuserid(userid);
if (userdo == null) {
userdo = new userdo();
userdo.setid(null);
userdo.setuserid(userid);
userdo.setuserorderstatus(0);
userdao.insert(userdo);
}
map<string,string> map=new hashmap<>();
map.put("userid",userid);
addheader(request,map);
return true;
}
private void addheader(httpservletrequest request, map<string, string> headermap) {
if (headermap==null||headermap.isempty()){
return;
}
class<? extends httpservletrequest> c=request.getclass();
//system.out.println(c.getname());
system.out.println("request实现类="+c.getname());
try{
field requestfield=c.getdeclaredfield("request");
requestfield.setaccessible(true);
object o=requestfield.get(request);
field coyoterequest=o.getclass().getdeclaredfield("coyoterequest");
coyoterequest.setaccessible(true);
object o2=coyoterequest.get(o);
system.out.println("coyoterequest实现类="+o2.getclass().getname());
field headers=o2.getclass().getdeclaredfield("headers");
headers.setaccessible(true);
mimeheaders mimeheaders=(mimeheaders) headers.get(o2);
for (map.entry<string,string> entry:headermap.entryset()){
mimeheaders.removeheader(entry.getkey());
mimeheaders.addvalue(entry.getkey()).setstring(entry.getvalue());
}
}catch (exception e){
e.printstacktrace();
}
}
@override
public void posthandle(httpservletrequest httpservletrequest, httpservletresponse response, object o, modelandview modelandview) throws exception {
response.setheader("access-control-allow-origin", "*");
response.setheader("access-control-allow-methods", "get, post, put, delete, options");
response.setheader("access-control-max-age", "3600");
response.setheader("access-control-allow-headers", "*");
response.setheader("access-control-allow-credentials", "true");
}
@override
public void aftercompletion(httpservletrequest httpservletrequest, httpservletresponse httpservletresponse, object o, exception e) throws exception {
}
}2.配置拦截器
拦截器需要配置才能使用
package com.kaying.luck.config.interceptor;
import com.kaying.luck.interceptor.baseinterceptor;
import org.springframework.context.annotation.configuration;
import org.springframework.web.servlet.config.annotation.corsregistry;
import org.springframework.web.servlet.config.annotation.interceptorregistry;
import org.springframework.web.servlet.config.annotation.webmvcconfigurer;
/**
* 拦截器需要配置才可以使用,也可以在这里注入其他的类
*
* @author yt
* @create 2022/10/17 14:26
*/
@configuration
public class baseinterceptorconfig implements webmvcconfigurer {
@override
public void addinterceptors(interceptorregistry registry) {
// 添加拦截器
registry.addinterceptor(new baseinterceptor())
//添加拦截路径
.addpathpatterns("/**")
//排除的拦截路径(此路径不拦截)
.excludepathpatterns("/swagger/**","/error","/download/**","/wx/**","/address/**","/management/**","/callback/**",
"/favicon.ico","/swagger2/**", "/swagger*", "/swagger*/**", "/webjars/**", "/doc.html", "/swagger-ui.html", "/swagger-resources/**", "/v2/api-docs**");
}
/**
* 开启跨域
*/
@override
public void addcorsmappings(corsregistry registry) {
// 设置允许跨域的路由
registry.addmapping("/**")
// 设置允许跨域请求的域名
.allowedoriginpatterns("*")
// 是否允许证书(cookies)
.allowcredentials(true)
// 设置允许的方法
.allowedmethods("*")
// 跨域允许时间
.maxage(3600);
}
}4.在要拦截的方法
接收参数上添加 @requestheader注解
@apioperation(value = "根据用户userid查询用户信息")
@getmapping("get/user")
public apiresponse<userdo> getuserbyuserid( @requestheader("userid") string userid) {
system.out.println("userid = " + userid);
if (stringutils.isblank(userid)) {
throw new serviceexception(apiresponsecodeenum.fail, "获取用户信息失败");
}
userdo userdo = userloginservice.getuserbyuserid(userid);
return apiresponse.success(userdo);
}5.测试访问是可以拿到userid的

总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。
发表评论