在讲解这个问题之前,先来聊聊我程序的设计,为移动端提供接口的同学们都知道,在接口通讯的过程中,数据是需要加密传输的,博主设计的也不例外,请看下面的内容:
parameter
参数是一段加密串,接下来在看我们的接口定义部分:
可以看到,接口需要的参数是一个User
对象,现在有个问题,怎么将加密的数据解密并将解密出的数据映射到User
对象中呢? 其实很简单,我们定义一个Filter
,过滤请求app/**
的路径,首先对其进行解密,然后将参数放入request.parameter
中,但是我们都知道request.parameter
中的数据只能进行读操作,不能进行写操作,怎么解决呢? 这里就引入一个类 javax.servlet.http.HttpServletRequestWrapper
,是一个扩展的通用接口,也就是会对request
做一次包装,我们继承并重写这个方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;import java.util.Enumeration;import java.util.HashMap;import java.util.Map;import java.util.Vector;public class ParameterRequestWrapper extends HttpServletRequestWrapper { private Map<String, String[]> params = new HashMap<>(); public ParameterRequestWrapper (HttpServletRequest request) { super (request); this .params.putAll(request.getParameterMap()); } public ParameterRequestWrapper (HttpServletRequest request, Map<String, Object> extendParams) { this (request); addAllParameters(extendParams); } @Override public Enumeration<String> getParameterNames () { return new Vector(params.keySet()).elements(); } @Override public String getParameter (String name) { String[] values = params.get(name); if (values == null || values.length == 0 ) { return null ; } return values[0 ]; } @Override public String[] getParameterValues(String name) { String[] values = params.get(name); if (values == null || values.length == 0 ) { return null ; } return values; } public void addAllParameters (Map<String, Object> otherParams) { for (Map.Entry<String, Object> entry : otherParams.entrySet()) { addParameter(entry.getKey(), entry.getValue()); } } public void addParameter (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)}); } } } }
大多数情况下我们都是使用Spring
作为开发框架,博主也不例外,定义过滤器,继承Spring
的OncePerRequestFilter
。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import org.springframework.stereotype.Component;import org.springframework.web.filter.OncePerRequestFilter;import javax.servlet.FilterChain;import javax.servlet.ServletException;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import java.io.IOException;import java.util.HashMap;import java.util.Map;@Component public class RequestParameterFilter extends OncePerRequestFilter { static final String AUTH_PATH = "/app/" ; @Override protected void doFilterInternal (HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { if (request.getRequestURI().indexOf(AUTH_PATH) != -1 ) { Map paramter = new HashMap(16 ); paramter.put("username" , "admin" ); paramter.put("password" , "password" ); ParameterRequestWrapper wrapper = new ParameterRequestWrapper(request, paramter); filterChain.doFilter(wrapper, response); return ; } filterChain.doFilter(request, response); } }
这样controller
获取到的就是解密后的参数了,写这篇文章的我还不太了解原理,只是会用,但是用也是一种成长,比如这样用法,这篇博文我根据自己程序解决方式思想引入的,编程思想最重要的,我们必须要好好学习,不断进步。
简书:使用ccze工具在Linux上着色日志文件