Web开发中参数处理的两种方式

1、Body 参数

  可以使用 @RequestBody 或 @RequestParam,也可以不使用任何注解。

  @RequestBody 主要用来接收前端传递给后端的 json 格式的数据的(请求体中的数据的)。

  它只有一个属性-required,表示参数是否必须要传,默认为 true。此时前端请求体Body参数不能为空,否则就会报错:Required request body is missing。比如后端是单个POJO或者Map,前端必须传值为 {},后端是集合或者数组时,前端必须传值 [],只有当设置为 false时,前端的body参数才允许为空(可以不传任何值)。

  GET 方式无请求体,所以 @RequestBody 接收数据时,前端必须是 POST 方式进行提交,然后给页面的数据默认也是 json

  同一个方法中,@RequestBody 与 @RequestParam() 可以同时使用,前者最多只能有一个,后者可以有多个,

  @RequestBody 接收的是请求体里面的数据,@RequestParam 接收的是 key-value 里面的参数。

  以上是常用的请求体传参方式:

@RequestMapping("/addConfig")
public Object addConfig(HttpServletRequest request,
                            @RequestBody GlobalConfigVo globalConfigVo){
      
 }
@RequestMapping(value = "/friend/submitBound")
public WebMessage submitBound(UserInfo userInfo,
                                  @RequestParam(value = "masterId")String masterId) {
        
}
@RequestMapping(value = "/get/unlock/drama")
public WebMessage getUnlockDrama(UserInfo userInfo,String dramaId,int count){
        
}

2、Header 参数

  身份验证信息等一般放在 header 中,对于 header 中的参数,如何像 @RequestBody 这样很方便的映射成对象呢?

  可以通过实现 HandlerMethodArgumentResolver 来解决。

step1:在MVC拦截器中将 header 中的信息处理成需要的 userInfo 通过 request.setAttribute() 放入 request 属性中。

@Slf4j
@Component
public class CommonHeaderInterceptor implements HandlerInterceptor {

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {
        try {
            String URI = StringUtils.substringAfter(request.getRequestURI(), ShuaConstants.REQUEST_PATH);
            String sign = request.getHeader("sign");
            String deviceId = request.getHeader("deviceId");
            String brand = request.getHeader("brand");
            String gps = request.getHeader("gps");
            String bs = request.getHeader("bs");
            String appVersion = request.getHeader("appVersion");
            String os = request.getHeader("os");
            String channel = request.getHeader("channel");
            String romVersion = request.getHeader("romVersion");
            String osVersion = request.getHeader("osVersion");
            String accessKey = request.getHeader("accessKey");
            String pkgId = request.getHeader("pkgId");
            String oaid = request.getHeader("oaid");

            CommonHeaderDTO commonHeaderDTO = new CommonHeaderDTO();
            commonHeaderDTO.setDeviceId(deviceId);
            commonHeaderDTO.setBrand(brand);
            commonHeaderDTO.setGps(gps);
            commonHeaderDTO.setBs(bs);
            commonHeaderDTO.setAppVersion(appVersion);
            commonHeaderDTO.setOs(os);
            commonHeaderDTO.setChannel(channel);
            commonHeaderDTO.setRomVersion(romVersion);
            commonHeaderDTO.setOsVersion(osVersion);
            commonHeaderDTO.setAccessKey(accessKey);
            commonHeaderDTO.setPkgId(pkgId);
            commonHeaderDTO.setAppId(String.valueOf(ShuaConstants.APP_ID));

            UserInfo userInfo = userService.findById(commonHeaderDTO, userId);

            userInfo.setOaid(oaid);
            userInfo.setChannel(channel);
            userInfo.setAppVersion(appVersion);
            userInfo.setTargetApi(targetApi);
            userInfo.setIp(IpUtils.getIpAddress(request));
            userInfo.setOs(os.equals("android") ? 0 : 1);
            userInfo.setMac(mac);
            userInfo.setAndroidId(androidId);
            userInfo.setUa(ua);
            userInfo.setIp(IpUtils.getIpAddress(request));
            userInfo.setModel(model);
            userInfo.setCaid(caid);
            //将user信息放入request属性中
            request.setAttribute(ShuaConstants.USER_INFO, userInfo);

            return true;
        }catch (Exception e){
            
        }
        return false;
    }


    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object o, ModelAndView modelAndView) throws Exception {

    }

step2:实现 HandlerMethodArgumentResolver。

public class UserInfoMethodArgumentResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return UserInfo.class.isAssignableFrom(methodParameter.getParameterType());
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        return nativeWebRequest.getAttribute(ShuaConstants.USER_INFO, RequestAttributes.SCOPE_REQUEST);
    }
}

step3:使用

@RequestMapping(value = "/version/check")
 public WebMessage checkVersionUpdate(UserInfo userInfo){
        return WebMessage.build(userService.checkVersionUpdate(userInfo.getUserId(), OsEnum.IOS.code() == userInfo.getOs(),userInfo.getPkgId(),userInfo.getAppVersion()));
    }

  HandlerMethodArgumentResolver 是处理器方法参数解析器。

  首先什么是Handler?说白了就是 Spring MVC中真正用于处理业务逻辑的类,也就是常说的、标注了@Controller注解的Controller类;Controller类中使用@RequestMapping(或GetMapping等变种注解)标注的方法称为处理器方法;处理器方法的参数指的就是该方法的参数。
  处理器方法参数解析器HandlerMethodArgumentResolver用于自动向处理器方法参数注入值(自动赋值),它有两个方法:

  supportsParameter() 方法用于判断处理器方法是否支持要映射的参数,如上:我们要映射的是 UserInfo,所以只判断方法是否支持该参数。

  resolveArgument() 方法我们将 拦截器中放入 request 属性中的 userInfo 取出即可。

 

posted @ 2024-04-22 22:43  jingyi_up  阅读(7)  评论(0编辑  收藏  举报