gpt4 book ai didi

java - 是否可以从 JSP 向 Spring Controller 发送不止一种类型的对象?

转载 作者:行者123 更新时间:2023-11-30 03:57:16 28 4
gpt4 key购买 nike

我正在编写一个 JSP View ,一旦提交,该 View 必须将多个对象发送到 Spring @Controller。

Controller 的处理程序具有以下签名:

public ModelAndView handlerX(@ModelAttribute ModelMap model){

我在 JSP 中尝试过类似的操作:

<form method="post" action="action">
<spring:bind path="objectX.name">
<input type="text" name="${status.expression}" value="${status.value}" readonly="readonly" />
</spring:bind>

但是当调试器到达 Controller 时,模型对象不包含任何表单的值。

有人可以就如何设计表单提供一些建议吗?我认为我无法将两个不同的对象包装在命令类型对象中,因为 Controller 的处理程序仅接受 ModelMap。非常感谢!

最佳答案

您可以通过定制自己的 HandlerMethodArgumentResolver 来将从表单发送的请求参数绑定(bind)到模型参数来解决此问题。例如:

public class RequestToModelBindingArgumentResolver implements HandlerMethodArgumentResolver, Ordered {

@Override
public boolean supportsParameter(final MethodParameter parameter) {
return parameter.hasParameterAnnotation(ModelAttribute.class) &&
parameter.getParameterType() == ModelMap.class;
}

@Override
public Object resolveArgument(final MethodParameter parameter, final ModelAndViewContainer mavContainer, final NativeWebRequest webRequest, final WebDataBinderFactory binderFactory) throws Exception {

ModelMap model = mavContainer.getModel();
Map<String, String[]> requestParameters = webRequest.getParameterMap();

// Bind all request parameters to the model
for (String param : requestParameters.keySet()) {
String[] values = requestParameters.get(param);
if (values.length == 1) {
model.addAttribute(param, values[0]);
} else {
model.addAttribute(param, values);
}
}

return model;
}

@Override
public int getOrder() {
return HIGHEST_PRECEDENCE;
}
}

此类的实例可以添加到您的应用程序配置的参数解析器列表中。

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

但是有一个问题。用 @ModelAttribute 注释的参数将由 ModelAttributeMethodProcessor 解析,并且由于没有发生 HandlerMethodArgumentResolver 的排序,因此它将始终是第一个解析该值的参数。这意味着如果您添加自定义参数解析器,它将永远无法到达。这意味着我们需要找到一种方法对解析器集合进行排序(这就是解析器实现Ordered的原因)

对解析器集合进行排序的一种简单方法是将 RequestmappingHandlerAdapter 注入(inject)配置中。

@Autowired
private RequestMappingHandlerAdapter adapter;

现在我们需要一个在构造配置后调用的方法,以便我们有机会对解析器集合进行排序。

@PostConstruct
public void orderArgumentResolvers() {
List<HandlerMethodArgumentResolver> resolvers = new ArrayList<>(adapter.getArgumentResolvers());
Collections.sort(resolvers, new OrderComparator());
adapter.setArgumentResolvers(resolvers);
}

由于 adapter.getArgumentResolvers() 将返回一个不可修改的列表,因此我们需要在开始排序之前在此处跳一个小圈。排序后,RequestToModelBindingArgumentResolver 实例将位于列表顶部,并且是第一个响应 support() 调用的实例。

但是嘿!我认为更改处理程序签名要容易得多:)

关于java - 是否可以从 JSP 向 Spring Controller 发送不止一种类型的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22860616/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com