HandlerMethodArgumentResolver
<mvc:annotation-driven>
<mvc:argument-resolvers>
<bean class="ccx.common.springext.resolver.JsonArgumentResolver" />
</mvc:argument-resolvers>
</mvc:annotation-driven>
<bean id="exceptionHandler" class="ccx.common.springext.resolver.DefaultExceptionResolver"/>
<bean id="resultLoad" name="ResultLoad" class="com.ccx.framework.result.ResultLoad"></bean>
如果遇到
org.xml.sax.SAXParseException; lineNumber: 44; columnNumber: 26; cvc-complex-type.2.1: 元素 'mvc:annotation-driven' 必须不含字符或元素信息项 [子级], 因为该类型的内容类型为空。
可以改为3.1以上,3.0 不支持mvc:annotation-driven
http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
package ccx.common.springext.resolver;
import java.io.BufferedReader;
import java.io.IOException;
import java.lang.reflect.Method;
import javax.servlet.http.HttpServletRequest;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.core.MethodParameter;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;
import ccx.common.code.IResult;
import ccx.common.code.ResultKey;
import ccx.common.entity.Request;
import ccx.common.exception.ParameterException;
import ccx.common.util.StringUtil;
import ccx.common.util.UserTokenTools;
import ccx.common.util.rsa.RSA;
import ccx.common.util.rsa.RSAKeys;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
/**
* json格式校验
*
* @author sunlihuo
*
*/
public class JsonArgumentResolver implements HandlerMethodArgumentResolver {
private static final Logger logger = LogManager.getLogger(JsonArgumentResolver.class);
private static final String JSONBODYATTRIBUTE = "JSON_REQUEST_BODY";
private IResult resultLoad;
@Override
public boolean supportsParameter(MethodParameter parameter) {
if (parameter.hasParameterAnnotation(JsonRequestBody.class)) {
WebApplicationContext wac = ContextLoader.getCurrentWebApplicationContext();
resultLoad = (IResult) wac.getBean("resultLoad");
return true;
}
return false;
}
@Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String uri = servletRequest.getRequestURI();
String jsonEncode = getRequestBody(webRequest);
String jsonDecode = JsonDecode(jsonEncode);
JSONObject json = toJsonObject(jsonDecode);
CheckLogin(uri, json);
Object obj = null;
Method method = parameter.getMethod();
Class<?>[] zlasss = method.getParameterTypes();
for (Class<?> zlass : zlasss) {
if (Request.class.isAssignableFrom(zlass)) {
try {
obj = JSONObject.toBean(json, zlass);
} catch (Exception e) {
throw new ParameterException(20000, "json to bean error", e);
}
continue;
}
}
return obj;
}
/**
* app json统一解密
*
* @param jsonEncode
* @return
*/
private String JsonDecode(String jsonEncode) {
String requestBody = jsonEncode;
if (true) {
try {
requestBody = RSA.decrypt(jsonEncode, RSAKeys.default_private_key, "utf-8");
} catch (Exception e) {
logger.error("请求报文解密失败,非法请求 = " + requestBody, e);
throw new ParameterException(resultLoad.getResult(ResultKey.JSON_FORMAT_ERROR));
} finally {
if (StringUtil.isEmpty(requestBody)) {
throw new ParameterException(resultLoad.getResult(ResultKey.msg_unpass_fail));
}
}
}
return requestBody;
}
/**
*
* @param jsonDecode
* @return
*/
private JSONObject toJsonObject(String jsonDecode) {
JSONObject val = null;
try {
val = JSONObject.fromObject(jsonDecode);
} catch (Exception e) {
throw new ParameterException(resultLoad.getResult(ResultKey.JSON_FORMAT_ERROR));
}
return val;
}
private JSONArray toJsonArray(String jsonDecode) {
JSONArray array = null;
try {
array = JSONArray.fromObject(jsonDecode);
} catch (Exception e) {
throw new ParameterException(resultLoad.getResult(ResultKey.JSON_FORMAT_ERROR));
}
return array;
}
/**
* 校验登录
*
* @param requestJson
* @return
*/
private void CheckLogin(String uri, JSONObject requestJson) {
boolean checkLogin = false;
if (uri.toLowerCase().indexOf("/private") != -1) {
checkLogin = true;
}
if (checkLogin) {
String token = requestJson.getString("token");
if (StringUtil.isEmpty(token)) {
throw new ParameterException(resultLoad.getResult(ResultKey.login_expire));
}
String checkToken = UserTokenTools.refreshToken(token);
if (null == checkToken) {
throw new ParameterException(resultLoad.getResult(ResultKey.login_expire));
}
}
}
/**
* 取请求参数
*
* @param webRequest
* @return
*/
private String getRequestBody(NativeWebRequest webRequest) {
HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);
String jsonBody = (String) webRequest.getAttribute(JSONBODYATTRIBUTE, NativeWebRequest.SCOPE_REQUEST);
if (jsonBody == null) {
try {
BufferedReader reader = servletRequest.getReader();
StringBuilder sb = new StringBuilder();
char[] buf = new char[1024];
int rd;
while ((rd = reader.read(buf)) != -1) {
sb.append(buf, 0, rd);
}
jsonBody = sb.toString();
webRequest.setAttribute(JSONBODYATTRIBUTE, jsonBody, NativeWebRequest.SCOPE_REQUEST);
} catch (IOException e) {
throw new ParameterException(20000, "Request reader 失败");
} catch (IllegalStateException e) {
throw new ParameterException(20000, "getInputStream() has already been called for this request");
}
}
return jsonBody;
}
}