问题描述:we wanna shift application/x-www-form-urlencoded to application/json.
前端上送的报文格式为POST+application/x-www-form-urlencoded,后端接受的格式为POST+application/json,前端保持不变的情况下,后端需要将form格式的报文转换成json格式报文,并且在controller中用@RequestBody接受前端form表单中的数据
解决方法:实现自定义messageConvertor 后端可以使用@RequesetBody接收请求
1.使用环境
jdk 1.8
springboot 2.x
springmvc
2.参考代码
? ? ? ? 2.1 编写自定义messageConvertor 通过FormHttpMessageConverter对象接收前端的报文,并得到前端form表单中的key-value的map对象,通过JSONOject 将map转json
package com.lkyl.httpConfig;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.lkyl.base.BaseRequest;
import com.lkyl.base.Header;
import com.lkyl.exception.CommonCode;
import com.lkyl.exception.CommonException;
import com.lkyl.util.BusinessContext;
import com.lkyl.util.ContextUtil;
import com.lkyl.util.DESTool;
import com.lkyl.util.ObjectUtils;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.AbstractHttpMessageConverter;
import org.springframework.http.converter.FormHttpMessageConverter;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.util.StringUtils;
import java.io.IOException;
import java.io.Serializable;
import java.util.Map;
public class BaseRequestMessageConverter extends AbstractHttpMessageConverter<BaseRequest> {
private static final FormHttpMessageConverter formHttpMessageConverter = new FormHttpMessageConverter();
private static final ObjectMapper mapper = new ObjectMapper();
/**
* 如果@RequestBody 对应的bean是BaseRequest的子类,则处理,否则不做处理
* @param aClass
* @return
*/
@Override
protected boolean supports(Class<?> aClass) {
return aClass.getSuperclass() == BaseRequest.class;
}
@Override
protected BaseRequest<Serializable> readInternal(Class<? extends BaseRequest> aClass, HttpInputMessage httpInputMessage) throws IOException, HttpMessageNotReadableException {
String body = null;
Map<String, String> vals;
JSONObject jsonObject = null;
vals = formHttpMessageConverter.read(null, httpInputMessage).toSingleValueMap();
try{
// JSONObject.toJSONString(request.getParameterMap());
String jsonStr = JSONObject.toJSONString(vals);
if(!StringUtils.isEmpty(jsonStr)){
jsonStr = jsonStr.replaceAll("\\[", "").replaceAll("\\]", "");
}
jsonObject = JSON.parseObject(jsonStr);
}catch(Exception e){
}
if(ObjectUtils.isNotEmpty(jsonObject)) {
JSONObject json = new JSONObject();
json.put("header", jsonObject);
//des解密请求报文
String desKey = ContextUtil.getBean(Environment.class).getProperty("centerBank.desKey");
if (ObjectUtils.isNotEmpty(jsonObject.get("data"))) {
String dataRaw = jsonObject.get("data").toString();
String data = null;
try {
data = DESTool.decrypt(desKey, dataRaw);
} catch (Exception e) {
throw new CommonException(CommonCode.EXCEPTION, "decode error");
}
JSONObject jsonData = JSON.parseObject(data);
jsonObject.put("transID", jsonData.get("transID"));
for (Map.Entry<String, Object> entry : jsonData.entrySet()) {
if (jsonData.get(entry.getKey()).toString().contains("|")) {
jsonData.put(entry.getKey(), JSON.parseObject(this.convert2JsonStr(jsonData.get(entry.getKey()).toString())));
}
}
json.put("body", jsonData);
body = json.toJSONString();
} else {
body = "{}";
}
}
BusinessContext businessContext = new BusinessContext();
businessContext.setHeader(ObjectUtils.JSONObject2Bean(JSON.parseObject(jsonObject.toString()), Header.class));
ContextUtil.setBusinessContext(businessContext);
return mapper.readValue(body, aClass);
}
@Override
protected void writeInternal(BaseRequest serializableBaseRequest, HttpOutputMessage httpOutputMessage) throws IOException, HttpMessageNotWritableException {
}
private String convert2JsonStr(String str){
if(StringUtils.isEmpty(str)){
return "{}";
}
String [] kv = str.split("\\|");
String [] itemKv;
StringBuilder sb = new StringBuilder("{");
for(String item : kv){
itemKv = item.split(":");
sb.append("\""+itemKv[0] +"\":\""+itemKv[1]+"\",");
}
return sb.substring(0, sb.length()-1) + "}";
}
}
? ? ? ? 2.2 将自定义的messageConvertor注册到mvc中的messageConvertor列表中
package com.lkyl.httpConfig;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.List;
@Configuration
public class HttpForm2JsonConverterConfig implements WebMvcConfigurer {
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(converter());
}
private BaseRequestMessageConverter converter() {
BaseRequestMessageConverter converter = new BaseRequestMessageConverter();
MediaType mediaType = new MediaType("application", "x-www-form-urlencoded", Charset.forName("UTF-8"));
converter.setSupportedMediaTypes(Arrays.asList(mediaType));
return converter;
}
}
? ? ? ? 2.3 controller 使用@RequestBody接受请求参数
????????
|