在写后台webapi时,接口总是需要定义一定的参数对象与前端请求进行呼应,然而在一些服务接口数量多,参数多,请求方式多的情况下,总是会出现获取不到前端请求参数数据。因此前后端之间交互的耦合又增高了。
前端发起微服务请求时,POST和GET、加上传输的数据类型json 、text,在Springboot里解析出来的方法五花八门,有的用RequestBody,有的又使用QueryString,用错了,参数就不知道传哪去了。其实,传输的参数都在Request对象中,都是一个一个键值对,因此,我就想着Controller所有服务接口就只统一传一个Request作为参数,将数据读取到一个静态Map<String,Object> 对象中,后面具体实现层在从这个变量中处理逻辑数据。
直接上代码:
///处理Request中的参数,并统一将key处理为小写,前端传递参数可忽略大小写了
public static Map<String, Object> getRequestParas(HttpServletRequest request) throws Exception {
Map<String, Object> combineResultMap = new HashMap<String, Object>();//合并是处理既在URL里传参又在data对象中传参,最终统一返回
// 创建参数队列
Map<String, Object> resultParas = new HashMap<String, Object>();
Map<String, Object> otherParams = new HashMap<String, Object>();
if (request.getMethod().equalsIgnoreCase("POST")) {
//POST下处理
Enumeration<String> postNames = request.getParameterNames();
while (postNames.hasMoreElements()) {
String name = postNames.nextElement();
String value = request.getParameter(name);
resultParas.put(name.toLowerCase(), getDecodeValue(value));
}
combineResultMap.putAll(resultParas);
//--------------在combineResultMap.putAll方法中会有后面覆盖相同key数据情况,POST传递以body中数据为准,
// --------------所以解析body放后面
String applicationJSONType = "application/json";
String contentType = request.getContentType();
if (StringUtils.isNull(contentType) == false && contentType.toLowerCase().contains(applicationJSONType)) {
BufferedReader streamReader = new BufferedReader(new InputStreamReader(request.getInputStream(), "UTF-8"));
StringBuilder responseStrBuilder = new StringBuilder();
String inputStr;
while ((inputStr = streamReader.readLine()) != null) {
responseStrBuilder.append(inputStr);
}
if (StringUtils.isNull(responseStrBuilder.toString()) == false) {
otherParams = JSON.parseObject(responseStrBuilder.toString(), Map.class);
combineResultMap.putAll(MapHelper.key2Lower(otherParams));
}
}
} else {
//GET 下处理
String queryString = request.getQueryString();
if (queryString != null) {
String[] paras = queryString.split("&");
for (String kv : paras) {
int splitIndex = kv.indexOf('=');
if (splitIndex != -1) {
String name = kv.substring(0, splitIndex);
String value = kv.substring(splitIndex + 1);
resultParas.put(name.toLowerCase(), getDecodeValue(value));
}
}
}
combineResultMap.putAll(resultParas);
}
return combineResultMap;
}
这个方法就将所有参数接收到Map<String,Object>对象中了,经过多次试验,满足前端各种类型的请求。
在RequestBody传参时,有个非常恶心的就是后端响应时,第一次可以读取参数数据,当逻辑中再次访问参数对象时,参数,没了!找了很多资料也没找到哪的问题,因此,我只能在初始化服务校验拦截类中抽取参数,放到全局静态变量中。
@Component("authInterceptor")
public class AuthInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
response.setHeader("Content-type", "application/json;charset=UTF-8");
response.setStatus(HttpServletResponse.SC_OK);
WebHelper.SetRequestParams(request);//读一遍参数;
}
public class WebHelper {
public static Map<String, Object> RequestParams = null;//全局静态变量存储传参
public static void SetRequestParams(HttpServletRequest request) throws Exception {
RequestParams = SpringContextHelper.getRequestParas(request);
}
}
经过上面整合,在应用时就方便多了。
Controller:
@Validated
@RestController
@RequestMapping("/user")
public class UserController extends BaseController {
@Autowired
private UserService sysUserService;
@RequestMapping(value = "/get", method = {RequestMethod.GET, RequestMethod.POST})
public Object query(HttpServletRequest request) {
try {
return sysUserService.QueryUser(request) ;
} catch (Exception e) {
throw new Exception("用户查询失败!" + e.getMessage(), e);
}
}
@RequestMapping(value = "/details/get", method = {RequestMethod.GET, RequestMethod.POST})
public Object queryDetail(HttpServletRequest request) throws Exception {
try {
return sysUserService.QueryUserDetail(request);
} catch (Exception e) {
throw new Exception("用户查询失败!" + e.getMessage(), e);
}
}
}
Service :
@Service
public class UserService extends BaseService {
public Object QueryUser(HttpServletRequest request) throws Exception {
Map<String, Object> params = WebHelper.RequestParams;//从静态变量获取传参,
//都是键值对,非常方便
String userid =StringHelper.handleNull(params.get("userid")) ;
String sn = StringHelper.handleNull(params.get("sn")) ;
...............
}
...................
}