当前位置: 首页 > 知识库问答 >
问题:

从JSP向Spring控制器发送一种以上类型的对象是可能的?

公冶元青
2023-03-14

我正在编写一个JSP视图,一旦提交,就必须将多个对象发送给Spring@Controller。

控制器的处理程序具有以下签名:

public ModelAndView handlerX(@ModelAttribute ModelMap model){
<form method="post" action="action">
<spring:bind path="objectX.name">
    <input type="text" name="${status.expression}" value="${status.value}" readonly="readonly" />
</spring:bind> 

但是当调试器到达控制器时,model对象不包含窗体的任何值。

有谁能给出一些如何设计表格的建议吗?我认为我不能将两个不同的对象包装在一个命令类型对象中,因为控制器的处理程序只接受一个模型映射。非常感谢!

共有1个答案

华浩壤
2023-03-14

您可以通过剪裁自己的HandlerMethodArgumentResolver来将从表单发送的请求参数绑定到模型参数来解决这个问题。例如:

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进行排序,它将始终是第一个html" target="_blank">解析该值的参数。这意味着,如果您添加自定义参数解析器,它将永远无法到达。这意味着我们需要找到对解析器集合进行排序的方法(这就是解析器实现ordered)。

排序冲突解决程序集合的一个简单方法是将RequestMappingHandlerAdapter注入到配置中。

@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()调用的实例。

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

 类似资料:
  • 我试图通过AJAX向Spring控制器发送JSON对象,但收到错误415: 下面是我的javascript调用- 这里是我的依赖项杰克逊相关的依赖项在我的POM- 讽刺的是,当我试着穿Spring靴的时候,它就起作用了。

  • 我正在使用spring控制器返回一个简单的列表对象。我已经用@ResponseBody注释了正确的方法,但它仍然不能从ArrayList转换。我还添加了jackson-mapper-asl jar。 我的控制器代码是 rest-servlet.xml 原木 我到底错过了什么?

  • 我在将对象列表从Thymeleaf保存到控制器时遇到了一个大问题。thymeleaf中的对象列表由Jquery生成。但我不知道如何将数据传输到控制器,对象列表不知道大小。因为用户可以随时添加它。请帮助我将thymeleaf中的列表对象发送给控制器。 我创建了一个具有1个属性的新类:ArrayList loaiDoans;“LoaiDoan”是我想要保存的对象。使用该类是将列表“loaidon”从t

  • 我有窗体和相应的控制器,对象列表被传递给它们。 实体类: 控制器: 形式: 我假设表单中的百里叶th:each循环变量不能是th:object=${ent2}(因为如果我这样做,select form返回null)。而th:value="${ent2.name}返回字符串值。所以我不得不将@RequestParam(th:value)发送给“save”方法。但是在这种情况下,我必须对数据库进行额外

  • 我的视图中有一个向控制器发送对象的表单,但问题是,如果我发送的对象超过256个,就会出现异常: 所以我在想为什么会有这样的限制,于是我找到了这个话题:https://stackoverflow.com/a/24699008/4173394 但它似乎对我不起作用(可能是我的一个坏习惯)。 下面是我的结构:我的视图名为createUpdate.vm,并像这样发布我的表单: 我在FollowerFile