5

我有一个带有 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,并且我在 thing/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 显示主题和消息的空白值。是的,这些属性上有 getter/setter。

我有一个非常相似的控制器,它工作得很好,除了那里的 GET 映射方法的签名中没有 @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";
}
4

2 回答 2

7

问题是您只是为事物分配了一个新的引用,这在 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";
}
于 2013-09-06T06:30:39.290 回答
1

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

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. 这可以提高您和其他人的可读性。

于 2013-09-05T21:42:34.340 回答