[Java] 基於 SpringBoot 增加 @BodyParam 註解接收Http請求Body中的Json引數
阿新 • • 發佈:2020-08-27
今天我們也來自己實現一個讀取Http請求Body中的Json引數的註解。
1.添加註解
import java.lang.annotation.*; @Target({ElementType.PARAMETER}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface BodyParam { String value() default "";
// 是否必須? boolean required() default true; Class<? extends Annotation> annotation() defaultAnnotation.class; }
2.編寫註解的方法引數處理程式
import com.fasterxml.jackson.databind.ObjectMapper; import xxx.filter.BufferedServletRequestWrapper; import xxx.support.annotation.BodyParam; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; import org.springframework.web.bind.MissingServletRequestParameterException;import org.springframework.web.bind.support.WebDataBinderFactory; import org.springframework.web.context.request.NativeWebRequest; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.method.support.ModelAndViewContainer; import java.lang.reflect.Array;import java.util.List; import java.util.Map; /** * 處理 @BodyParam 註解 * @author yangyxd * @date 2020.08.18 16:03 */ @Component public class BodyParamResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter methodParameter) { return methodParameter.hasParameterAnnotation(BodyParam.class); } @Override public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception { Map json = ((BufferedServletRequestWrapper) nativeWebRequest.getNativeRequest()).getContentBody(); BodyParam p = methodParameter.getParameterAnnotation(BodyParam.class); Object v = json == null ? null : json.get(p.value().toLowerCase()); if (v == null && p.required()) throw new MissingServletRequestParameterException(p.value(), methodParameter.getParameterType().getTypeName()); // 這裡可以爭對各種型別作特殊處理,我現在只處理了 String 的部分轉換操作 if (methodParameter.getParameterType() == String.class) { if (v instanceof Map || v instanceof List || v instanceof Array) { ObjectMapper mapper = new ObjectMapper(); return mapper.writeValueAsString(v); } if (v instanceof Number) { return v.toString(); } } return v; } }
3.使用示例
@Controller @RequestMapping("/manage/xxx") @Validated public class XXXController { final XXXService service; public XXXController(XXXService service) { this.service = service; } /** * 獲取商品列表 */ @PostMapping("/list") @ResponseBody ResponseDTO<PageDataDTO<XXXItemDTO>> getList( @BodyParam(value = "from",required = false) Long from, @BodyParam(value = "to",required = false) Long to, @BodyParam(value = "name", required = false) String name, @BodyParam(value = "pagesize",required = false) Integer pageSize, @BodyParam(value = "pageindex",required = false) Integer pageIndex, @BodyParam(value = "categoryid",required = false) String categoryId, @BodyParam("deleted") Integer deleted ) throws SysException { return ResponseDTO.success(); } }