Springboot后台参数拦截,解码或者接口拦截等
一.使用场景:
2.如接口调用过程中,每次调用都需要传送一个token,我们怎样去对接口进行拦截
所以本文就来讲一讲自己在工作中的全局解码的实现方式:
前端编码的方式参考前一篇随笔:https://www.cnblogs.com/KdeS/p/12073331.html
二.定义一个Filter或者OncePerRequestFilter
这里会引入一个类 javax.servlet.http.HttpServletRequestWrapper
,是一个扩展的通用接口,也就是会对request
做一次包装,我们需要继承并重写这个方法。
2.1 代码部分如下
package com.grand.p1upgrade.filter; import java.util.HashMap; import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequestWrapper; public class MyHttpServletRequestWrapper extends HttpServletRequestWrapper{ // 用于存储请求参数 private Map<String , String[]> params = new HashMap<String, String[]>(); public MyHttpServletRequestWrapper(HttpServletRequest request) { super(request); // 把请求参数添加到我们自己的map当中 this.params.putAll(request.getParameterMap()); } public void setParameters(Map<String, Object> extraParams) { for (Map.Entry<String, Object> entry : extraParams.entrySet()) { setParameter(entry.getKey(), entry.getValue()); } } /** * 添加参数到map中 * @param name * @param value */ public void setParameter(String name, Object value) { if (value != null) { if (value instanceof String[]) { params.put(name, (String[]) value); } else if (value instanceof String) { params.put(name, new String[]{(String) value}); } else { params.put(name, new String[]{String.valueOf(value)}); } } } /** * 重写getParameter,代表参数从当前类中的map获取 * @param name * @return */ @Override public String getParameter(String name) { String[]values = params.get(name); if(values == null || values.length == 0) { return null; } return values[0]; } /** * 重写getParameterValues方法,从当前类的 map中取值 * @param name * @return */ @Override public String[] getParameterValues(String name) { return params.get(name); } }
2.2 继承OncePerRequestFilter覆盖doFilterInternal对密码解码
package com.grand.p1upgrade.filter; import java.io.IOException; import java.util.Base64; import javax.servlet.FilterChain; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.stereotype.Component; import org.springframework.web.filter.OncePerRequestFilter; /** * 参数过滤,对所有请求接口的请求进行拦截是否有pwd参数,有则解密,并将参数放入request.parameter中 * * @author SanLi * Created by 2689170096@qq.com/SanLi on 2018/1/28 */ //@Component public class RequestParameterFilter extends OncePerRequestFilter { @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { String pwd=request.getParameter("pwd"); if(pwd!=null) { pwd= new String(Base64.getDecoder().decode(pwd), "UTF-8"); MyHttpServletRequestWrapper wrapper = new MyHttpServletRequestWrapper(request); wrapper.setParameter("pwd",pwd); /** * 1.一般filter都是一个链,web.xml 里面配置了几个就有几个。一个一个的连在一起 * request -> filter1 -> filter2 ->filter3 -> …. -> request resource. * * 2.chain.doFilter将请求转发给过滤器链下一个filter , 如果没有filter那就是你请求的资源 */ filterChain.doFilter(wrapper, response); } return; } }
2.2 继承Filter对密码解码
package com.grand.p1upgrade.filter; import java.io.IOException; import java.util.Base64; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang.StringUtils; import org.springframework.stereotype.Component; import lombok.extern.java.Log; /** * 过滤所有的请求,包含静态资源,如果请求cookie中含有token或请求为静态资源,则放行请求,否则进入到登陆页面 */ @Log @Component public class TokenFilter implements Filter{ @Override public void init(FilterConfig filterConfig) throws ServletException {} @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain chain) throws IOException, ServletException { MyHttpServletRequestWrapper wrapper = null; String token = null; HttpServletRequest request= (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String uri = request.getRequestURI(); //参数过滤,对所有请求接口的请求进行拦截是否有pwd参数,有则解密,并将参数放入request.parameter中 String pwd=request.getParameter("pwd"); wrapper = new MyHttpServletRequestWrapper(request); if(pwd!=null) { pwd= new String(Base64.getDecoder().decode(pwd), "UTF-8"); wrapper.setParameter("pwd",pwd); } if(uri.contains("/login"))||uri.contains("/static")){ //通过,不拦截 chain.doFilter(wrapper,response); }else{ // 拦截请求,判断cookie中是否有token,没有则跳转到登陆页,有则放行 Cookie[] cookies = request.getCookies(); if(cookies!=null){ for (Cookie cookie : cookies) { if("token".equals(cookie.getName())){ // 前端传递过来的token包含两部分:key,value token = cookie.getValue(); } } } // token有值,且包含"_",就通过 if(StringUtils.isNotEmpty(token)&&token.contains("_")){ chain.doFilter(wrapper,response); }else{ response.setStatus(401); // 需要权限 } } } @Override public void destroy() {} }
总结:
在我使用的过程中继承OncePerRequestFilter或者是继承Filter同样都能达到我们想要的效果。
作者:皓月无边*半步青莲
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· Docker 太简单,K8s 太复杂?w7panel 让容器管理更轻松!