春季提交表单后的空字段

Posted

技术标签:

【中文标题】春季提交表单后的空字段【英文标题】:Null fields after form submit in Spring 【发布时间】:2013-08-29 09:09:57 【问题描述】:

我有一个带有 Rating 评级属性的产品。我有一个不包含评级字段的产品更新表单(updateStart 方法)(因为我不希望它是可编辑的)。

问题是当我提交表单时(使用更新方法),评分自动设置为空。 所以我尝试在 updateStart 中将 Rating 添加到表单模型中,并在 update 方法中检索它,但它也不断被重写。

我尝试在控制器中设置 @SessionAttributes("rating") 注释。这次保留了评级值,但 Spring 在数据库中创建了一个新条目,从另一个评级对象克隆,并将其附加到产品。

@Controller
@SessionAttributes("rating")
@RequestMapping("/products")
public class ProductsController 

@RequestMapping("/update_start")
public String updateStart(@RequestParam("id") Long id, Model model) throws BusinessException 
    Product product = productService.findProductById(id);

System.out.println("RATING A START "+product.getRating().getAbsoluteRating());

    List<Category> categories = productService.findAllCategories();
    model.addAttribute("categories", categories);
    model.addAttribute("product", product);
    model.addAttribute("id", id);
    model.addAttribute("rating",product.getRating());
    return "products.updateform";   


@RequestMapping(value="/update", method = RequestMethod.POST)
public String update(@ModelAttribute("rating") Rating rating, @ModelAttribute Product product, BindingResult bindingResult) throws BusinessException 

    System.out.println("RATING A UPDATE "+rating.getAbsoluteRating());

    validator.validate(product, bindingResult);

    List<Image> images = imageService.getProductImages(product.getId());

    product.setRating(rating);

    productService.updateProduct(product,images,sellerid);
    return "redirect:/products/viewsforsellers.do";
   

我能做什么?

编辑:我宁愿避免在我的表单中放置带有 ratingId 的隐藏输入字段。

【问题讨论】:

当你说你在表单中添加评分时,你是添加所有字段还是只添加id?对实体进行评级吗? @KevinBowersox 是的,Rating 是一个实体。我尝试使用以下方法将其添加到模型(而不是表单输入):model.addAttribute("rating",product.getRating()); 表格中的评分是下拉菜单? @kiduxa 正如我所说,产品更新表单(updateStart 方法)不包含评分字段(因为我不希望它可编辑)。 【参考方案1】:

在表单中包含一个隐藏输入,其中 namevalueRating 指定。该值应包括

<form>
    <input name="product.rating" value="$product.rating.id"/>
    <!-- Other fields -->
</form>

现在,当请求通过网络发送时,它应该包含由id 为产品指定的Rating

@RequestMapping(value="/update", method = RequestMethod.POST)
public String update(@ModelAttribute Product product, BindingResult bindingResult) throws BusinessException 
     //implementation
 

@ModelAttribute 应该尝试将此参数绑定到 Product 但是它不知道 Rating 是什么。这就是Converter 发挥作用的地方。 Converter 在数据绑定期间用于告诉 Spring MVC 如何将 String 类型的字段映射到 Rating 类型的字段。

public class StringToRatingConverter implements Converter<String, Rating> 


    public Rating convert(String source) 
           //Use the source String to convert to rating
           //Possibly via database call or enum conversion, pending ratings type and definition
           //Ultimately the code needs to return the appropriate object of type Rating

           return rating;  //The above implementation will create the rating object.
        
    

然后必须在dispatcher 配置文件中注册StringToRatingConverter

    <!-- Register Converters - Used for data binding-->
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="fully.qualified.path.to.StringToRatingConverter"/>
        </list> 
    </property>
</bean>

我第一次遇到这种情况,我在post on my blog 中捕获了它,您可能会有所帮助。

【讨论】:

我想避免在我的表单中放置一个隐藏字段,因为它可以使用 firebug 轻松修改。此外,如果我将 rating id 字段放入表单中,我可以使用它的值直接检索(通过数据库查询)相关的 Rating 对象,而无需使用转换器。也许我错过了什么。 我同意@KurtBourbaki,你有想过这个吗?【参考方案2】:

您应该在@SessionAttributes("rating") 注释中添加“类型”元素,以便保留属性的属性;例如

@SessionAttributes(types = Rating.class, names = "rating")

【讨论】:

以上是关于春季提交表单后的空字段的主要内容,如果未能解决你的问题,请参考以下文章

Drupal 8表单提交Ajax表单后的回调

单击提交清除文件字段而不是提交表单(IE9)

Req.Body 是 Angular 2 表单提交 + Bodyparser 上的空对象

Django Newbie - 使用多字段表单,如何消除查询集中的空字段

jQuery AJAX 将提交的表单替换为表单(好),但不会再次提交

php让页面记住表单提交后的信息方法