You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Spring 1.2升级至5.3:表单控制器Bean配置适配问题咨询

解决Spring 1.2到5.3升级中FormController配置的替换问题

Hey,我太懂你现在升级Spring版本的头疼了——那些在1.2里用得顺风顺水的sessionFormcommandName属性,到5.3里直接报“不可写”错误,这是因为Spring MVC在3.x之后就彻底废弃了传统的FormController体系,转向了注解驱动的控制器模型,老属性自然就不被支持了。

下面给你一套完整的替换方案,完全覆盖你原来Bean配置的所有功能,同时贴合Spring 5.3的最佳实践:

一、核心思路:从XML配置的FormController迁移到注解式控制器

原来的PriceIncreaseFormController继承了Spring老版本的FormController类,现在我们要改成用@Controller注解标注的类,通过注解实现原来的所有配置项。

1. 新的控制器代码(Java类)

替换你原有的web.PriceIncreaseFormController,代码如下:

package web;

import bus.PriceIncrease;
import bus.ProductManager;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.SessionAttributes;

@Controller
@SessionAttributes("priceIncrease") // 替代原来的sessionForm=true,将表单对象存入session
public class PriceIncreaseFormController {

    // 构造器注入(Spring 4.3+推荐方式,无需@Autowired)
    private final ProductManager productManager;
    private final PriceIncreaseValidator priceIncreaseValidator;

    public PriceIncreaseFormController(ProductManager productManager, PriceIncreaseValidator priceIncreaseValidator) {
        this.productManager = productManager;
        this.priceIncreaseValidator = priceIncreaseValidator;
    }

    // 替代原来的commandName和commandClass:创建表单绑定的模型对象
    @ModelAttribute("priceIncrease")
    public PriceIncrease createPriceIncreaseModel() {
        return new PriceIncrease();
    }

    // 处理表单展示请求(对应原来的formView)
    @GetMapping("/priceincrease")
    public String showPriceIncreaseForm() {
        return "priceincrease";
    }

    // 处理表单提交请求(对应原来的successView和验证逻辑)
    @PostMapping("/priceincrease")
    public String processPriceIncreaseSubmit(
            @ModelAttribute("priceIncrease") PriceIncrease priceIncrease,
            BindingResult bindingResult,
            Model model) {
        
        // 调用自定义验证器(对应原来的validator属性)
        priceIncreaseValidator.validate(priceIncrease, bindingResult);

        if (bindingResult.hasErrors()) {
            // 验证失败,返回表单页面
            return "priceincrease";
        }

        // 执行业务逻辑:调用productManager处理价格上涨(和原来的逻辑一致)
        productManager.increasePrices(priceIncrease.getPercentage());

        // 成功后从session移除表单对象,避免后续请求残留
        model.addAttribute("priceIncrease", null);
        // 用redirect避免重复提交(比直接返回视图更规范)
        return "redirect:/hello.htm";
    }
}

2. 调整Spring XML配置

原来的priceIncreaseForm Bean可以完全删除,换成以下配置支持注解驱动:

<!-- 启用Spring MVC注解驱动(必须项) -->
<mvc:annotation-driven/>

<!-- 扫描控制器所在的包,让Spring自动识别@Controller注解的类 -->
<context:component-scan base-package="web"/>

<!-- 视图解析器:保留你原来的配置即可,这里给个示例 -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/WEB-INF/views/"/> <!-- 根据你的实际视图路径调整 -->
    <property name="suffix" value=".jsp"/> <!-- 根据你的视图类型调整,比如.jsp或.html -->
</bean>

<!-- 保留原来的验证器和业务Bean配置,这些不需要改 -->
<bean id="priceIncreaseValidator" class="bus.PriceIncreaseValidator"/>
<bean id="prodMan" class="bus.ProductManager">
    <!-- 原来的属性配置(比如数据源等)继续保留 -->
</bean>

二、关键配置项的对应关系

给你梳理老配置和新注解/代码的对应逻辑,方便理解:

  • sessionForm=true@SessionAttributes("priceIncrease"):将指定名称的模型对象存入session,实现跨请求保留表单数据的功能
  • commandName="priceIncrease" + commandClass="bus.PriceIncrease"@ModelAttribute("priceIncrease")方法:创建并命名表单绑定的实体对象,和原来的参数绑定逻辑一致
  • validator → 直接注入PriceIncreaseValidator并在提交方法中调用:验证逻辑和原来完全兼容
  • formView="priceincrease"@GetMapping方法返回"priceincrease":处理GET请求,返回表单视图
  • successView="hello.htm"return "redirect:/hello.htm":处理提交成功后的跳转,用redirect避免用户刷新页面导致重复提交
  • productManager依赖 → 构造器注入:Spring 5推荐的依赖注入方式,比原来的XML属性注入更安全

三、额外注意事项

  1. Java版本要求:Spring 5.3最低要求Java 8,确保你的项目已经升级到Java 8或以上版本
  2. 验证器兼容:如果你的PriceIncreaseValidator实现了org.springframework.validation.Validator接口,直接注入即可使用,不需要修改
  3. 请求路径:确保你的表单提交的路径和@PostMapping的路径一致(这里是/priceincrease

内容的提问来源于stack exchange,提问作者user3067524

火山引擎 最新活动