Spring RequestParam 的默认值等于方法调用
Spring default value of RequestParam equal to a method call
我正在尝试添加具有默认值的请求参数 - 但我希望该默认值是登录用户的名称。
我有一个方法 getUsername(),它 returns 当前用户的名称,但我无法将注释的值设置为方法调用(或 class 属性)。这是我的方法:
@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 不是必需的,如果为空则填充它 - 但这感觉不是很优雅(或 spring-ish)。还有其他方法可以实现吗?
我不确定你是否可以在注解中调用方法,但你可以在 @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()));
}
正如 fatedy 所建议的,最简单的方法是实现 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);
}
}
这需要一个简单的用户名 class:
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()));
}
我正在尝试添加具有默认值的请求参数 - 但我希望该默认值是登录用户的名称。
我有一个方法 getUsername(),它 returns 当前用户的名称,但我无法将注释的值设置为方法调用(或 class 属性)。这是我的方法:
@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 不是必需的,如果为空则填充它 - 但这感觉不是很优雅(或 spring-ish)。还有其他方法可以实现吗?
我不确定你是否可以在注解中调用方法,但你可以在 @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()));
}
正如 fatedy 所建议的,最简单的方法是实现 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);
}
}
这需要一个简单的用户名 class:
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()));
}