aes加解密后续问题contentType不是application/json时候后台解析请求对象request
阅读原文时间:2023年07月09日阅读:1

一、post请求的三种content-type

1、application/x-www-form-urlencoded 主要用于如下:
1.1: 最常见的POST提交数据方式。
1.2:原生form默认的提交方式(可以使用enctype指定提交数据类型)。
1.3:jquery,zepto等默认post请求提交的方式。

2、multipart/form-data
使用表单上传文件时,必须指定表单的 enctype属性值为 multipart/form-data. 请求体被分割成多部分,每部分使用 --boundary分割;

3、application/json
在http请求中,ContentType都是默认的值 application/x-www-form-urlencoded, 这种编码格式的特点是:name/value值对,
每组之间使用&连接,而name与value之间是使用 = 连接,比如 key=xxx&name=111&password=123456; 键值对一般的情况下是没有什么问题的,
是很简单的json形式;对于一些复制的数据对象,对象里面再嵌套数组的话,建议使用application/json传递比较好,开发那边也会要求使用application/json。因为他们那边不使用application/json的话,使用默认的application/x-www-form-urlencoded传递的话,开发那边先要解析成如上那样的,然后再解析成json对象,如果对于比上面更复杂的json对象的话,那么他们那边是很解析的,所以直接json对象传递的话,对于他们来说更简单。通过json的形式将数据发送给服务器。json的形式的优点是它可以传递结构复杂的数据形式,比如对象里面嵌套数组这样的形式等。

所以,application/json是现在最常用的请求contentType;

二、当前端发生ajax请求进行aes加密后,后台的请求对象要进行封装,而contentType不是application/json时候,后台要额外再封装一个请求对象,进行解析,成json对象,post请求;

1、前端公共js封装ajax请求的地方,对参数处理进行修改:

var param;
if(GLOBAL_CONFIG.aesOpen=='1'){
var p=self.param||{};
if(self.contentType=='application/json'){
var rsaStr=FWRSAHelper.encrypt(self.param);
param=JSON.stringify({p:encrypt(rsaStr,GLOBAL_CONFIG.aecKey)});
}else{
var rsaStr=FWRSAHelper.encrypt(JSON.stringify(self.param));
param={p:encrypt(rsaStr,GLOBAL_CONFIG.aecKey)};
}
}else{
param=self.param;
}

2、后台请求过滤器java代码中修改:

            WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse) response);

            if("application/json".equals(contentType)){
WrapperedRequest wrapRequest = new WrapperedRequest((HttpServletRequest) request, rsaResult);
chain.doFilter(wrapRequest, wrapResponse);
}else{
JSONObject jsonObject=JSONObject.parseObject(rsaResult);
HashMap newParam=new HashMap();
Iterator it = jsonObject.keySet().iterator();
while(it.hasNext()){
String key = it.next();
Object value = jsonObject.getString(key);
newParam.put(key,value);
}
ParameterRequestWrapper wrapRequest=new ParameterRequestWrapper(request,newParam);
chain.doFilter(wrapRequest, wrapResponse);
}

其中,原先的代码不动,在对参数解密之后,如果contentType不是application/json时候,要对参数再进行一次解析,再封装一个请求对象;

封装的新的请求对象类:

package com.xxx.common.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import java.util.Enumeration;
import java.util.Map;
import java.util.Vector;

/**
* 该类用于改写request.getParameterNames里的值
* 使用方法:HashMap newParam=new HashMap(request.getParameterMap());
* ParameterRequestWrapper wrapRequest=new ParameterRequestWrapper(request,newParam);
* */
public class ParameterRequestWrapper extends HttpServletRequestWrapper {
private Map params;

public ParameterRequestWrapper(HttpServletRequest request, Map newParams) {  
    super(request);  
    this.params = newParams;  
}

public Map getParameterMap() {  
    return params;  
}

public Enumeration getParameterNames() {  
    Vector l = new Vector(params.keySet());  
    return l.elements();  
}

public String\[\] getParameterValues(String name) {  
    Object v = params.get(name);  
    if (v == null) {  
        return null;  
    } else if (v instanceof String\[\]) {  
        return (String\[\]) v;  
    } else if (v instanceof String) {  
        return new String\[\] { (String) v };  
    } else {  
        return new String\[\] { v.toString() };  
    }  
}

public String getParameter(String name) {  
    Object v = params.get(name);  
    if (v == null) {  
        return null;  
    } else if (v instanceof String\[\]) {  
        String\[\] strArr = (String\[\]) v;  
        if (strArr.length > 0) {  
            return strArr\[0\];  
        } else {  
            return null;  
        }  
    } else if (v instanceof String) {  
        return (String) v;  
    } else {  
        return v.toString();  
    }  
}  

}