#maven
commons-codec
commons-codec
1.9
#在spring boot的启动类中加入注解
@ServletComponentScan
#IdentifyingCodeFilter 类
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.annotation.Order;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
/**
*
* 功能:验证码校验过滤
*
*
* @ClassName: IdentifyingCodeFilter
*/
// @Order该注解的参数表示多个过滤器的执行顺序,越小则优先执行
// @WebFilter 的 urlPatterns 可以写多个url,如 urlPatterns ={"/test1","test2"}
@Order(1)
@WebFilter(filterName = "identifyingCodeFilter",urlPatterns = "/*")
public class IdentifyingCodeFilter implements Filter {
static Logger log = LoggerFactory.getLogger(IdentifyingCodeFilter.class);
String[] strUrl = {"/codeFilter" };
@Override
public void init(FilterConfig arg0) throws ServletException {
log.info("执行校验过滤器IdentifyingCodeFilterr--init方法完成");
}
@Override
public void destroy() {
log.info("执行校验过滤器IdentifyingCodeFilter--destroy方法完成");
}
/**
*
* 功能:过滤 接口
*
* @param req
* @param res
* @param chain
* @throws IOException
* @throws ServletException
* @see javax.servlet.Filter#doFilter(javax.servlet.ServletRequest,
* javax.servlet.ServletResponse, javax.servlet.FilterChain)
*/
@Override
public void doFilter(ServletRequest req, ServletResponse res,FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
req.setCharacterEncoding("utf-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
boolean b = false;
String userName = req.getParameter("userName");
String url = request.getRequestURI();
for (int i = 0; i < strUrl.length; i++) {
if(url.contains(strUrl[i])){
b = true;
break;
}
}
if (b) {
try {
Map m = new HashMap<>(request.getParameterMap());
if(StringUtils.isNotBlank(userName)) {
/**变更request的参数**/
String tParam = AES128.decryptAES(userName.replaceAll(" ","+"), "7t3e506jaa10xbd4");
m.put("userName", new String[]{tParam});
/**解密后的参数重新放入request*/
ParameterRequestWrapper prw = new ParameterRequestWrapper(request, m);
request = prw;
chain.doFilter(request, response);
}
} catch (Exception e) {
// 这里写业务逻辑
doException(response);
System.out.println("参数校验未通过");
}
} else {
chain.doFilter(request, response);
}
log.info("执行校验过滤器IdentifyingCodeFilter--doFilter方法完成");
}
private void doException(HttpServletResponse response){
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json;charset=UTF-8");
PrintWriter writer = null;
try {
writer = response.getWriter();
writer.write("{\n" +
" \"status\": \"100\",\n" +
" \"showMessage\": \"参数校验未通过\"\n" +
"}");
} catch (Exception e) {
} finally {
try {
if (null != writer) {
writer.close();
}
} catch (Exception e) {
}
writer = null;
}
return;
}
}
#ParameterRequestWrapper 类
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map params;
public ParameterRequestWrapper(HttpServletRequest request, Map newParams) {
super(request);
this.params = newParams;
//addParameterMap(request);
}
@Override
public String getParameter(String name) {
String result = "";
Object v = params.get(name);
if (v == null) {
result = null;
} else if (v instanceof String[]) {
String[] strArr = (String[]) v;
if (strArr.length > 0) {
result = strArr[0];
} else {
result = null;
}
} else if (v instanceof String) {
result = (String) v;
} else {
result = v.toString();
}
return result;
}
@Override
public Map getParameterMap() {
return params;
}
@Override
public Enumeration getParameterNames() {
return new Vector(params.keySet()).elements();
}
@Override
public String[] getParameterValues(String name) {
String[] result = null;
Object v = params.get(name);
if (v == null) {
result = null;
} else if (v instanceof String[]) {
result = (String[]) v;
} else if (v instanceof String) {
result = new String[] { (String) v };
} else {
result = new String[] { v.toString() };
}
return result;
}
}
#AES128 类
import org.apache.commons.codec.binary.Base64;
import sun.misc.BASE64Decoder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.IOException;
/**
*
* 功能:AES128位对称加密类,该类参数需要16位字符串秘钥及待加/解密字符串
*
参考文章:
* http://blog.csdn.net/coyote1994/article/details/52368921
*
http://jueyue.iteye.com/blog/1830792
*
* @ClassName: AES128
*/
public class AES128 {
/**
* 定义一个初始向量,需要与iOS端的统一,使用CBC模式,需要一个向量iv,可增加加密算法的强度
*/
private static final String IV_STRING = "16-Bytes--String";
/**
*
* 功能:AES128加密方法
*
* @author tangy
* @date 2016年10月27日
* @param content 待加密内容
* @param key 加密密钥(16位字符串)
* @return 加密后的字符串(结果已经过base64加密)
* @throws Exception
*/
public static String encryptAES(String content, String key)
throws Exception {
byte[] byteContent = content.getBytes("UTF-8");
// 注意,为了能与 iOS 统一
// 这里的 key 不可以使用 KeyGenerator、SecureRandom、SecretKey 生成
byte[] enCodeFormat = key.getBytes();
SecretKeySpec secretKeySpec = new SecretKeySpec(enCodeFormat, "AES");
byte[] initParam = IV_STRING.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
// 指定加密的算法、工作模式和填充方式
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivParameterSpec);
byte[] encryptedBytes = cipher.doFinal(byteContent);
// 同样对加密后数据进行 base64 编码
return Base64.encodeBase64String(encryptedBytes);
}
/**
*
* 功能:解密函数
*
* @param content 待解密字符串
* @param key 解密秘钥(16位字符串,需要与加密字符串一致)
* @return
* @throws Exception
*/
public static String decryptAES(String content, String key)
throws Exception {
// 先base64 解码
byte[] encryptedBytes = Base64.decodeBase64(content);
byte[] enCodeFormat = key.getBytes();
SecretKeySpec secretKey = new SecretKeySpec(enCodeFormat, "AES");
//使用CBC模式,需要一个向量iv,可增加加密算法的强度
byte[] initParam = IV_STRING.getBytes();
IvParameterSpec ivParameterSpec = new IvParameterSpec(initParam);
//"算法/模式/补码方式"
Cipher cipher = Cipher.getInstance("AES/CBC/PKCS5Padding");
cipher.init(Cipher.DECRYPT_MODE, secretKey, ivParameterSpec);
byte[] result = cipher.doFinal(encryptedBytes);
if(result.length==0){
throw new IllegalBlockSizeException();
}
return new String(result, "UTF-8");
}
/**
* 测试函数
*/
public static void main(String[] args) throws Exception {
String content="159********";
//必须为16位
String key="7t3e506jaa10xbd4";
String deKey="7t3e506jaa10xbd4";
String enstring = encryptAES(content, key);
String destring = decryptAES(enstring,deKey);
System.out.println("原始字符串:"+content);
System.out.println("加密后字符串:"+enstring);
System.out.println("长度:"+enstring.length());
System.out.println("解密后字符串:"+destring);
}
}