【问题标题】:Spring Boot: Maunally bind an object from a webRequest using HandlerMethodArgumentResolverSpring Boot:使用 HandlerMethodArgumentResolver 手动绑定来自 webRequest 的对象
【发布时间】:2020-02-10 22:35:33
【问题描述】:

我需要在它到达控制器之前构建一个对象,我发现这样做的一种方法是使用HandlerMethodArgumentResolver

基本上,我有一个映射到请求参数的 pojo,但我想在它到达控制器之前在该 pojo 中设置一些其他字段。

POJO:UserParams.java

@AllArgsConstructor
public class UserParams {
    private String firstName;
    private String lastName;
    private String sessionId;
}

假设我的请求是 localhost:8080/user?firstName=John&lastName=Doe

因此,在我的解析器中,我想使用上述请求中的请求参数绑定 UserParams 对象并填充 sessionId 字段并返回具有附加值的绑定对象。

@Component
public class UserParamsResolver implements HandlerMethodArgumentResolver {

    @Override
    public boolean supportsParameter(final MethodParameter parameter) {
        return parameter.getParameterType().isAssignableFrom(UserParams.class);
    }

    @Override
    public Object resolveArgument(final MethodParameter parameter,
                                  final ModelAndViewContainer mavContainer,
                                  final NativeWebRequest webRequest,
                                  final WebDataBinderFactory binderFactory) {
        WebDataBinder binder = new WebDataBinder(BeanUtils.instantiateClass(parameter.getParameterType()));
        ServletRequestParameterPropertyValues values = new ServletRequestParameterPropertyValues(((ServletWebRequest) webRequest).getRequest());
        binder.bind(values);
        BindingResult result = binder.getBindingResult();

        // UserParams userParams = how to get this object? 
        // userParams.setSessionId(userParams.getLastName + Math.random())
        return userParams;
}

因此,当请求最终到达控制器时,我的 userParams 中包含 sessionId。

我尝试查看很多地方(programcreek.com 有很多 WebDataBinder 的示例),并尝试了解 Spring 在访问 Controller 之前如何使用请求参数绑定对象,但我没有运气。

【问题讨论】:

    标签: java spring spring-boot spring-mvc


    【解决方案1】:

    一种解决方案是使用 spring AOP 来处理所有以UserParams 为参数的@Controller 方法。然后你必须访问WebRequest才能获得sessionId,这有点棘手;您必须创建一个@Bean @Scope("request")(例如,将其命名为WebRequestAccessor),其中包含@Autowired 类型的WebRequest 字段。将 WebRequestAccessor bean 自动装配到您的 @Aspect 中,以便使用其 WebRequest 字段,然后您可以访问 sessionId。在UserParams 参数上设置sessionId,然后让建议的方法继续工作。

    看看here,了解如何编写和使用@Aspect。

    更新

    您可以使用JSESSIONID 代替HttpSession.getId()。只需用 @CookieValue("JSESSIONID") 注释 private String sessionId

    更新 2

    我很确定你应该使用ServletModelAttributeMethodProcessor(或ModelAttributeMethodProcessor)而不是HandlerMethodArgumentResolver

    【讨论】:

    • 难道不能让它在HandlerMethodArgumentResolver中工作吗?我在解析器中需要它的原因是因为我想让它更通用,所以将来我可以使用相同的解析器类绑定 UserParams、OwnerParams、BuyerParams 等。
    • 我不知道,但你可以让所有这些类实现一个接口(例如SessionIdProvider,为sessionId 设置setter/getter),然后基于该接口创建@Aspect
    猜你喜欢
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    • 2018-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多