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

Spring Web MVC、@ModelAttribute和@RequestParam一起

卫景明
2023-03-14

我有一个控制器,它的GET方法是这样写的:

@Controller
public class ThingController {

     @RequestMapping( value = "/Thing.html", method = RequestMethod.GET )
    public String editThing(@RequestParam( "thingId" ) String thingId, @ModelAttribute ThingBean thing, BindingResult result) {
        thing = <some service call using thingId>
        logger.debug("The thing to edit is {}", thingBean);
        return "thing/edit";
    }
}

bean是正确的(getter和setter),服务调用返回带有thingId的正确ThingBean,并且显示了我在edit.jsp的JSP页面。

JSP是:

<html>
<body>
    <h1 id="title" class="title">Edit Thing</h1>

<form:form id="thing" modelAttribute="thing">
    <form:input path="subject" id="subject" tabindex="1" />
    <form:textarea path="message" />

</form:form>

</body>
</html>

但是,JSP 显示主题和消息的空白值。是的,这些属性上有吸气剂/二传手。

我有一个非常相似的控制器,工作得很好,除了GET - mapped方法的签名中没有@RequestParam。

我在Spring WebMVC文档中没有看到任何地方说我不能这样做——为什么它不能工作?为什么更新后的ModelAttribute对象没有被绑定到JSP表单中?

编辑:

这个控制器和GET调用的相同模式已经在许多不同的地方工作过——用@ModelAttribute注释的变量由方法填充,然后可供JSP页面显示。为什么通过添加@RequestParam注释,它就停止了?

@RequestMapping( value = "/Things.html", method = RequestMethod.GET )
public String getThings(@ModelAttribute ThingForm thingForm, BindingResult result) {

    try {
        // need to get list of Things
        List<Thing> Things = <service call that gets list of Things>;
        thingForm.setThings(Things);
        logger.debug("Things are {}", Things);

    }
    catch (ResourceNotFoundException e) {
        return "error";
    }

    logger.debug("Thing list loading - end");

    // Go to jsp
    return "thing/list";
}

共有2个答案

东方化
2023-03-14

您忘记指定Model At的名称,请使用以下更正:

public String editThing(@RequestParam( "thingId" ) String thingId, 
@ModelAttribute("thing") ThingBean thing, BindingResult result) {
....
}

如果上述方法无效,请使用以下方法:

public String editThing(@RequestParam( "thingId" ) String thingId, 
    @ModelAttribute("thing") ThingBean thing, BindingResult result, Model model) {
            ....
    thing = <some service call using thingId>
    logger.debug("The thing to edit is {}", thingBean);
    model.addAttribute("thing",thing);
    return "thing/edit";
}

如果可能的话,我建议对组件使用更好的命名约定,例如,thingModel而不是thing。这有助于提高您和其他人的可读性。

孔深
2023-03-14

问题是,你只是给东西分配了一个新的引用,这在Java中是行不通的。你必须把它放在模型中,否则你的视图不会知道它。

@RequestMapping( value = "/Thing.html", method = RequestMethod.GET )
public String editThing(@RequestParam( "thingId" ) String thingId, @ModelAttribute ThingBean thing, BindingResult result) {
    thing = <some service call using thingId> // This is only assigning a new reference not updating 
    logger.debug("The thing to edit is {}", thingBean);
    return "thing/edit";
}

所以与其这样做

@RequestMapping( value = "/Thing.html", method = RequestMethod.GET )
public String editThing(@RequestParam( "thingId" ) String thingId, @ModelAttribute ThingBean thing, BindingResult result, Model model) {
    thing = <some service call using thingId>
    model.addAttribute("thing", thing);
    logger.debug("The thing to edit is {}", thingBean);
    return "thing/edit";
}

这让我想知道为什么你在这种方法中甚至有一个模型属性?它基本上是无用的。

而不是上述我会做这样的事情

@ModelAttribute("thing")
public Thing prepareModel(@RequestParam("thingId") String thingId) {
    return thingSergice.findById(thingId);
}

现在,这个方法将在每个请求处理方法之前被调用。在这种情况下,你可以简单地引用它,而不是每次都要查找它。(从您的代码来看,您的方法中的Thingbean模型属性是非常无用的,我会将其重写为以下内容)

@RequestMapping( value = "/Thing.html", method = RequestMethod.GET )
public String editThing() {
    return "thing/edit";
}
 类似资料:
  • 问题内容: 方法上的参数指示应从模型中检索参数。如果模型中不存在该参数,则应首先实例化该参数,然后将其添加到模型中。一旦出现在模型中,则应从名称匹配的所有请求参数中填充参数的字段。WebDataBinder类将请求参数名称(包括查询字符串参数和表单字段)匹配,以按名称对属性字段进行建模。 将请求参数绑定到控制器中的方法参数。 我知道与不是同一件事,不是互斥的,不会扮演相同的角色,并且可以同时使用,

  • {“时间戳”:1553613278534,“状态”:400,“错误”:“错误请求”,“消息”:“必需的字符串参数'param2'不存在”,“路径”:“/MyURL/42”} 我希望PUT的工作就像POST一样,但它似乎不是。 不幸的是,我不能将参数作为QueryParam发送,因此我应该维护相同的请求调用,因为我正在重构一个完全以这种方式工作的现有endpoint。

  • 我尝试使用和通过Postman发送JSON和多个文件,但它不起作用。有可能在API中同时使用这两个注释吗?

  • 问题内容: 我有这个枚举: 我想用作rest请求的参数: 当我发送这些请求时,它工作正常 但是当我发送: /events?sort=somethingElse 我在控制台中收到500条响应和以下消息: 有没有一种方法可以防止spring抛出这些异常并将enum设置为null? 编辑 Strelok接受的答案有效。但是,我决定处理MethodArgumentTypeMismatchException

  • 我对的枚举有问题。在方法中有两个枚举:和。是内置的Spring枚举,它完美地从String转换为Enum: 但是当我打电话的时候 我阅读并测试了: 带枚举的Spring的@RequestParam Spring Boot能够接受枚举作为请求参数 枚举作为Spring Boot Rest中的请求参数 如何在RequestParm中将多个值转换为枚举? @RequestParam defaultval

  • 如果我错了请纠正我。两者都可以用于数据绑定。 谢谢!!