在写后台webapi时,接口总是需要定义一定的参数对象与前端请求进行呼应,然而在一些服务接口数量多,参数多,请求方式多的情况下,总是会出现获取不到前端请求参数数据。因此前后端之间交互的耦合又增高了。
前端发起微服务请求时,POST和GET、加上传输的数据类型json 、text,在Springboot里解析出来的方法五花八门,有的用RequestBody,有的又使用QueryString,用错了,参数就不知道传哪去了。其实,传输的参数都在Request对象中,都是一个一个键值对,因此,我就想着Controller所有服务接口就只统一传一个Request作为参数,将数据读取到一个静态Map
直接上代码:
///处理Request中的参数,并统一将key处理为小写,前端传递参数可忽略大小写了 public static MapgetRequestParas(HttpServletRequest request) throws Exception { Map combineResultMap = new HashMap ();//合并是处理既在URL里传参又在data对象中传参,最终统一返回 // 创建参数队列 Map resultParas = new HashMap (); Map otherParams = new HashMap (); if (request.getMethod().equalsIgnoreCase("POST")) { //POST下处理 Enumeration 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
在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 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 params = WebHelper.RequestParams;//从静态变量获取传参,
//都是键值对,非常方便
String userid =StringHelper.handleNull(params.get("userid")) ;
String sn = StringHelper.handleNull(params.get("sn")) ;
...............
}
...................
}



