java 自定义注解 生成json_Spring自定义注解实现json参数传递

实现(POST,GET)传参自动转换成Json对象,所有参数为Json格式然后再Base64加密

Spring Request详解:

Spring 的DispatcherServlet 实现了Servlet方法,来处理一次请求

DispatcherServlet主要是执行了两个方法doService(HttpServletRequest request, HttpServletResponse response),doDispatch(HttpServletRequest request, HttpServletResponse response)

在doDispatch方法中

// Determine handler for the current request.

mappedHandler = getHandler(processedRequest);

获取当前请求的handler,也就是获取到执行当前request的bean。

HandlerMapping有多个实现,具体的还需自己看下实现

// Determine handler adapter for the current request.

HandlerAdapterha = getHandlerAdapter(mappedHandler.getHandler());

获取到当前请求的HandlerAdapter

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

for (HandlerMapping hm : this.handlerMappings) {

if (logger.isTraceEnabled()) {

logger.trace(

"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");

}

HandlerExecutionChain handler = hm.getHandler(request);

if (handler != null) {

return handler;

}

}

return null;

}

获取ha.supports(handler) 返回为true的HandlerAdapter

eg.

如果这个bean实现了HttpRequestHandler接口则返回HttpRequestHandlerAdapter

@Override

public boolean supports(Object handler) {

return (handler instanceof HttpRequestHandler);

}

如果这个bean实现了Controller接口则返回SimpleControllerHandlerAdapter

@Override

public boolean supports(Object handler) {

return (handler instanceof Controller);

}

目前常用的方式是通过@Controller、@RequestMapping和Spring配置中添加

此时使用的是RequestMappingHandlerAdapter

RequestMappingHandlerAdapter 主要实现了请求参数的封装处理,返回参数的封装处理,支持注入argumentResolvers、returnValueHandlers、messageConverters等来实现扩展

RequestMappingHandlerAdapter.invokeHandlerMethod.invokeAndHandle.invokeForRequest.getMethodArgumentValues

if (this.argumentResolvers.supportsParameter(parameter)) {

try {

args[i] = this.argumentResolvers.resolveArgument(

parameter, mavContainer, request, this.dataBinderFactory);

continue;

}

catch (Exception ex) {

if (logger.isDebugEnabled()) {

logger.debug(getArgumentResolutionErrorMessage("Error resolving argument", i), ex);

}

throw ex;

}

}

首先会调用argumentResolver的supportsParameter判断是否可用,然后再执行resolveArgument方法

SpecialArgumentsResolver,自定义argumentResolver

通过上面我们可以发现,基于自定义注解实现Json的参数传递,需要实现自定的argumentResolver并注入到RequestMappingHandlerAdapter中

实现自定义Json注解

/**

* Created by zhaoqi on 2016/5/5.

*/

@Target(ElementType.PARAMETER)

@Retention(RetentionPolicy.RUNTIME)

@Documented

public @interface Json {

Class[] types() default java.lang.Object.class;

String path() default "";

}

spring配置文件增加自定义argumentResolver

注意,如果是注入的argumentResolver,会覆盖默认的argumentResolver。

如果不想覆盖默认的argumentResolver,请注入customArgumentResolvers。

// Custom arguments

if(getCustomArgumentResolvers() !=null) {

resolvers.addAll(getCustomArgumentResolvers());

}

实现SpecialArgumentsResolver

/**

* Created by zhaoqi on 2016/5/6.

*/

public class SpecialArgumentsResolver implements HandlerMethodArgumentResolver {

@Resource

DotaJsonHttpMessageConverter dotaJsonHttpMessageConverter;

@Override

public boolean supportsParameter(MethodParameter parameter) {

return parameter.hasParameterAnnotation(Json.class);

}

@Override

public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {

return this.readArguments(webRequest, parameter, parameter.getGenericParameterType());

}

private Object readArguments(NativeWebRequest webRequest, MethodParameter parameter, Type genericParameterType) {

HttpServletRequest servletRequest = webRequest.getNativeRequest(HttpServletRequest.class);

ServletServerHttpRequest inputMessage = new ServletServerHttpRequest(servletRequest);

Object arg =null;

try {

// get方式取queryString

if (servletRequest.getMethod().equals(RequestMappingHandlerAdapter.METHOD_GET)) {

// base64解码

String decodedQueryString = new String(Base64Utils.decodeFromString(servletRequest.getQueryString()));

return JsonUtil.toObject(decodedQueryString, Class.forName(genericParameterType.getTypeName()));

}

// Json注解使用dotaJsonHttpMessageConverter读取参数

arg = dotaJsonHttpMessageConverter.readInternal(Class.forName(genericParameterType.getTypeName()), inputMessage);

if (null == arg) {

throw new HttpMessageNotReadableException("Required request body is missing: " +

parameter.getMethod().toGenericString());

}

} catch (IOException | ClassNotFoundException e) {

//

}

return arg;

}

}

实际使用

@RequestMapping("/sayHi")

@ResponseBody

public ResponseVo getFeedback(@Json HelloRequest hello){

ResponseVo responseVo = new ResponseVo();

responseVo.setMsg("success");

responseVo.setData(hello.getHello());

return responseVo;

}

好处

目前前端页面调用后台接口,GET和POST的参数形式不一样。GET方式是将参数拼接在url中,而POST是可以直接传Json对象的

后台通过使用@Json注解,可以实现GET和POST参数的统一,如果需要切换请求方式,无需重新拼装参数

本例采用的为base64加密,实际可以根据情况自行使用加密方式。可以伪装请求的参数,增强安全性

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值