注:文章皆为个人纪录,可用性请以最终结果为准,若有错还请大佬们指出,谢谢!
在实际Java开发过程中,经常需要在Controller层中,针对不同的请求方式与不同类型的请求参数做不同的处理,此文章旨在解决上述问题,做到参数统一
步骤一:创建Controller的公共父类
@Slf4j
public abstract class AbstractController {
private static final String PAGE_INDEX_PARAM_NAME = "page"; //分页页码 参数名
private static final String PAGE_SIZE_PARAM_NAME = "pageSize"; //分页条数 参数名
private static final int DEFAULT_PAGE_INDEX = 1; // 默认页码: 第一页
private static final int DEFAULT_PAGE_SIZE = 15; // 默认条数: 15
@Autowired
protected HttpServletRequest request;
@Autowired
protected HttpServletResponse response;
@Autowired
protected RequestBean requestBean;
protected int getPageIndex() {
String page = request.getParameter(PAGE_INDEX_PARAM_NAME);
return (page == null || Integer.parseInt(page) <= 0) ? DEFAULT_PAGE_INDEX : Integer.parseInt(page);
}
protected int getPageSize() {
return DEFAULT_PAGE_SIZE;
}
/**
* 获取Ipage分页信息, 默认不允许获取全部数据
**/
protected IPage getIPage() {
return new Page(getPageIndex(), getPageSize());
}
/**
* 获取Ipage分页信息, 默认不允许获取全部数据 - 简单分页
* @return
*/
protected IPage getISamplePage() {
return new Page(getPageIndex(), getPageSize(), false);
}
/**
* 获取json格式的请求参数
**/
protected JSONObject getReqParamJSON() {
JSONObject object = requestBean.getReqParamJSON();
log.info("request params body {}", object);
return object;
}
/**
* 获取对象类型
**/
protected <T> T getObject(Class<T> clazz) {
JSONObject params = getReqParamJSON();
T result = params.toJavaObject(clazz);
if (result instanceof BaseModel) {
//如果属于BaseModel, 处理apiExtVal
}
return result;
}
/** 获取请求参数值 String 类型相关函数 **/
protected String getValString(String key) {
return getVal(key, String.class);
}
/** 获取请求参数值 Integer 类型相关函数 **/
protected Integer getValInteger(String key) {
return getVal(key, Integer.class);
}
protected String getValStringRequired(String key) {
return getValRequired(key, String.class);
}
protected Integer getValIntegerRequired(String key) {
return getValRequired(key, Integer.class);
}
/** 获取请求参数值 Integer 类型相关函数 附带默认值 **/
protected Integer getValIntegerDefault(String key, Integer defaultValue) {
return getValDefault(key, defaultValue, Integer.class);
}
/** 获取请求参数值 String 类型相关函数 附带默认值 **/
protected String getValStringDefault(String key, String defaultValue) {
return getValDefault(key, defaultValue, String.class);
}
/** 获取请求参数值 [ T 类型 ], [ 非必填 ] **/
protected <T> T getVal(String key, Class<T> cls) {
return getReqParamJSON().getObject(key, cls);
}
/** 获取请求参数值 [ T 类型 ], [ 必填 ] **/
protected <T> T getValRequired(String key, Class<T> cls) {
T value = getVal(key, cls);
if(ObjectUtils.isEmpty(value)) {
throw new CommonException(ApiResCodeEnum.PARAMS_ERROR, key);
}
return value;
}
/** 获取请求参数值 [ T 类型 ], [ 如为null返回默认值 ] **/
protected <T> T getValDefault(String key, T defaultValue, Class<T> cls) {
T value = getVal(key, cls);
if(value == null) {
return defaultValue;
}
return value;
}
}
步骤二:创建请求参数统一处理的Bean
@Slf4j
@Component
public class RequestBean {
@Autowired(required = false)
protected HttpServletRequest request; //自动注入request
/**
* reqContext对象中的key: 转换好的json对象
*/
private static final String REQ_CONTEXT_KEY_PARAMJSON = "REQ_CONTEXT_KEY_PARAMJSON";
/**
* JSON 格式通过请求主体(BODY)传输 获取参数
**/
public String getReqParamFromBody() {
String body = "";
if (isConvertJSON()) {
try {
String str;
while ((str = request.getReader().readLine()) != null) {
body += str;
}
return body;
} catch (Exception e) {
log.error("请求参数转换异常! params=[{}]", body);
throw new CommonException(ApiResCodeEnum.PARAMS_ERROR);
}
} else {
return body;
}
}
/**
* request.getParameter 获取参数 并转换为JSON格式
**/
public JSONObject reqParam2JSON() {
JSONObject returnObject = new JSONObject();
if (isConvertJSON()) {
String body = "";
try {
String str;
while ((str = request.getReader().readLine()) != null) {
body += str;
}
if (StringUtils.isEmpty(body)) {
return returnObject;
}
return JSONObject.parseObject(body);
} catch (Exception e) {
log.error("请求参数转换异常! params=[{}] exception={}", body, e);
throw new CommonException(ApiResCodeEnum.PARAMS_ERROR);
}
}
// 参数Map
Map properties = request.getParameterMap();
// 返回值Map
Iterator entries = properties.entrySet().iterator();
Map.Entry entry;
String name;
String value = "";
while (entries.hasNext()) {
entry = (Map.Entry) entries.next();
name = (String) entry.getKey();
Object valueObj = entry.getValue();
if (null == valueObj) {
value = "";
} else if (valueObj instanceof String[]) {
String[] values = (String[]) valueObj;
for (int i = 0; i < values.length; i++) {
value = values[i] + ",";
}
value = value.substring(0, value.length() - 1);
} else {
value = valueObj.toString();
}
if (!name.contains("[")) {
returnObject.put(name, value);
continue;
}
//添加对json对象解析的支持 example: {ps[abc] : 1}
String mainKey = name.substring(0, name.indexOf("["));
String subKey = name.substring(name.indexOf("[") + 1, name.indexOf("]"));
JSONObject subJson = new JSONObject();
if (returnObject.get(mainKey) != null) {
subJson = (JSONObject) returnObject.get(mainKey);
}
subJson.put(subKey, value);
returnObject.put(mainKey, subJson);
}
return returnObject;
}
/**
* 获取json格式的请求参数
**/
public JSONObject getReqParamJSON() {
//将转换好的reqParam JSON格式的对象保存在当前请求上下文对象中进行保存;
// 注意1: springMVC的CTRL默认单例模式, 不可使用局部变量保存,会出现线程安全问题;
// 注意2: springMVC的请求模式为线程池,如果采用ThreadLocal保存对象信息,可能会出现不清空或者被覆盖的问题。
Object reqParamObject = RequestContextHolder.getRequestAttributes().getAttribute(REQ_CONTEXT_KEY_PARAMJSON, RequestAttributes.SCOPE_REQUEST);
if (reqParamObject == null) {
JSONObject reqParam = reqParam2JSON();
RequestContextHolder.getRequestAttributes().setAttribute(REQ_CONTEXT_KEY_PARAMJSON, reqParam, RequestAttributes.SCOPE_REQUEST);
return reqParam;
}
return (JSONObject) reqParamObject;
}
/**
* 判断请求参数是否转换为json格式
*/
private boolean isConvertJSON() {
String contentType = request.getContentType();
//有contentType && json格式, get请求不转换
// && request.getMethod().equalsIgnoreCase("GET")
if (contentType != null
&& contentType.toLowerCase().indexOf("application/json") >= 0) { //application/json 需要转换为json格式;
return true;
}
return false;
}
/**
* 获取客户端ip地址
**/
public String getClientIp() {
String ipAddress = null;
ipAddress = request.getHeader("x-forwarded-for");
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getHeader("WL-Proxy-Client-IP");
}
if (ipAddress == null || ipAddress.length() == 0 || "unknown".equalsIgnoreCase(ipAddress)) {
ipAddress = request.getRemoteAddr();
}
// 对于通过多个代理的情况,第一个IP为客户端真实IP,多个IP按照','分割
if (ipAddress != null && ipAddress.length() > 15) {
if (ipAddress.indexOf(",") > 0) {
ipAddress = ipAddress.substring(0, ipAddress.indexOf(","));
}
}
return ipAddress;
}
}
步骤三:使用示例
@RequestMapping("/api")
public class DisbursementController extends AbstractController{
@RequestMapping(value = "/test/requestParamCommon", method = RequestMethod.GET) // 可以在url中添加参数,添加后照样可以用@PathVarible("param") 去接,也可以用getObject(Map.class)接收;POST请求直接将GET改为POST即可
@SuppressWarnings("unchecked")
public ApiResponse disbursementAllList() {
Map<String, Object> map = getObject(Map.class); // 用Map接就用Map.class,用T接就用T的反射对象就好
return ApiResponse.ok("success");
}
}
别以为有很多东西就懒得尝试了!!
步骤一与步骤二中很多部分都是扩展功能,具体实现标题中的功能调用 getObject(T) 方法即可,相关代码部门极少