【问题标题】:Spring default value of RequestParam equal to a method callRequestParam 的 Spring 默认值等于一个方法调用
【发布时间】:2016-03-21 16:52:37
【问题描述】:

我正在尝试添加具有默认值的请求参数 - 但是我希望该默认值是登录用户的名称。

我有一个 getUsername() 方法,它返回当前用户的名称,但我无法将注释的值设置为方法调用(或类属性)。这是我的方法:

@RequestMapping(method = RequestMethod.GET)
public @ResponseBody ResponseEntity<WebUser> getUser(
        @RequestParam(value = "username", defaultValue = getUsername()) String username) {
    return ResponseEntity.ok(service.getUser(getUsername(), username.toLowerCase()));
}

我可以使 RequestParam 不需要并在 null 时填充它 - 但这感觉不是很优雅(或弹簧式)。有没有其他方法可以做到这一点?

【问题讨论】:

标签: java spring spring-mvc annotations http-request-parameters


【解决方案1】:

正如fateddy 所建议的,最简单的方法是实现一个HandlerMethodArgumentResolver。

public class UsernameHandlerMethodArgumentResolver implements HandlerMethodArgumentResolver {
    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(Username.class);
    }
    @Override
    public Object resolveArgument(MethodParameter methodParameter,
                                  ModelAndViewContainer modelAndViewContainer,
                                  NativeWebRequest nativeWebRequest,
                                  WebDataBinderFactory webDataBinderFactory) throws Exception {
        String username = nativeWebRequest.getParameter("username");
        if (username == null && nativeWebRequest.getUserPrincipal() != null) {
            username = nativeWebRequest.getUserPrincipal().getName();
        }
        return new Username(username);
    }
}

这需要一个简单的用户名类:

public class Username {
    private String username;
    public Username(String username) {
        this.username = username;
    }
    public String getValue() {
        return this.username;
    }
}

还有注释

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface UserRequest {}

为了得到正确配置,这需要对 WebMvcConfigurerAdapter 进行非常小的更改:

@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
    argumentResolvers.add(new UsernameHandlerMethodArgumentResolver());
}

就是这样。很好走。现在我们可以简单地将参数放入控制器端点:

@RequestMapping(method = RequestMethod.GET)
public @ResponseBody ResponseEntity<WebUser> getUser(@UserRequest Username username) {
    return ResponseEntity.ok(service.getUser(username, username.toLowerCase()));
}

【讨论】:

    【解决方案2】:

    我不确定你是否可以在注解中调用方法,但你可以在@RequestMapping调用执行之前通过类似下面的方式获取用户名值。

    我认为这可以使用@ModelAttribute 来实现。

    @ModelAttribute("username")
    public String getUserName() {
        String name = "XYZ";
        return name;
    }
    

    并且在您的@RequestMapping 中执行如下操作。

    @RequestMapping(method = RequestMethod.GET)
    public @ResponseBody ResponseEntity<WebUser> getUser(
            @ModelAttribute("username") String username) {
        return ResponseEntity.ok(service.getUser(username, username.toLowerCase()));
    }
    

    Further reading

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-03
      • 1970-01-01
      • 2016-12-13
      • 1970-01-01
      • 2020-09-03
      相关资源
      最近更新 更多