1. 程式人生 > 實用技巧 >[Java] 基於 SpringBoot 增加 @BodyParam 註解接收Http請求Body中的Json引數

[Java] 基於 SpringBoot 增加 @BodyParam 註解接收Http請求Body中的Json引數

今天我們也來自己實現一個讀取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() default
Annotation.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();
    }
    
}