1

我有以下 Spring MVC 3.2.4 方法:

@RequestMapping(value = "/products/{product}", method = RequestMethod.POST)
public String update(Product product, @Valid @ModelAttribute("productForm") ProductForm productForm, BindingResult bindingResult, Model model) {
    if (bindingResult.hasErrors()) {
        return "products/view";
    }
    mapper.map(productForm, product);
    productService.saveProduct(product);
    return "redirect:/products/{product}";
}

成功后,它应该将用户重定向回产品的详细信息。问题是我没有重定向到页面“/products/1”,而是重定向到页面“/products/Product [code=1234567890, name=Nejaky]”。看起来占位符 {product} 被替换为 product.toString() 而不是来自 URL 的原始 ID。我正在使用内置的 Spring Data 转换器:

<mvc:annotation-driven conversion-service="conversionService">
    <mvc:argument-resolvers>
        <bean class="org.springframework.data.web.PageableHandlerMethodArgumentResolver" />
    </mvc:argument-resolvers>
</mvc:annotation-driven>

<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean" />

<bean class="org.springframework.data.repository.support.DomainClassConverter">
    <constructor-arg ref="conversionService" />
</bean>

我应该怎么做才能使其正常工作并将我重定向回“/products/1”而不执行“redirect:/product”+product.getId() 之类的操作?

4

2 回答 2

1

我们的故事从RedirectView源代码开始,在方法中replaceUriTemplateVariables

protected StringBuilder replaceUriTemplateVariables(
        String targetUrl, Map<String, Object> model, Map<String, String> currentUriVariables, String encodingScheme)
        throws UnsupportedEncodingException {

    StringBuilder result = new StringBuilder();
    Matcher m = URI_TEMPLATE_VARIABLE_PATTERN.matcher(targetUrl);
    int endLastMatch = 0;
    while (m.find()) {
        String name = m.group(1);
        Object value = model.containsKey(name) ? model.remove(name) : currentUriVariables.get(name);
        Assert.notNull(value, "Model has no value for '" + name + "'");
        result.append(targetUrl.substring(endLastMatch, m.start()));
        result.append(UriUtils.encodePathSegment(value.toString(), encodingScheme));
        endLastMatch = m.end();
    }
    result.append(targetUrl.substring(endLastMatch, targetUrl.length()));
    return result;
}

正如您所预测的,该方法使用value.toString()where valueis your productobject in the Model. 这里不涉及转换系统等其他组件。您的选择如下:

利用

"redirect:/product" + product.getId()

添加一个名为的模型属性"productId"并在您的视图名称中使用它

model.addAttribute("productId", product.getId());
"redirect:/product/{productId}"

或者使用 uri 变量。我还没有关于这些的信息。

于 2013-10-09T19:40:41.277 回答
0

好的,终于找到原因了。我不得不用@PathVariable 注释产品参数。想知道没有它它也能工作。

于 2013-10-10T08:53:56.973 回答