【问题标题】:Can Spring use a simple String as form command object?Spring 可以使用简单的字符串作为表单命令对象吗?
【发布时间】:2013-01-25 21:30:38
【问题描述】:

我希望在实际上只有一个可绑定值的表单上使用 Spring 强大的绑定工具(错误/验证/标签库/等)。我没有使用包含单个字符串属性(“名称”)的对象,而是尝试使用基本字符串作为命令对象,但我不确定如何(或是否)让它与相同的顶级。这是一个使用带有嵌套字符串的对象 (MyObject) 的示例 - 这很好用。我想只使用一个字符串,但是当我将 MyObject 更改为 String 时,为该字符串输入的任何内容都不会反映在下一页中。我做错了什么?

@Controller 
@SessionAttributes("command")
public class TestController {

private static final String[] WIZARD_PAGES = new String[] {
    "enterValue",
    "confirmValue"
};  

@RequestMapping(value = "doStuff.action", method = RequestMethod.GET)
public String formBackingObject(HttpServletRequest request, HttpServletResponse response, final ModelMap modelMap) {
    MyObject entry = new MyObject();
    modelMap.put("command", entry);
    return WIZARD_PAGES[0];
}

@RequestMapping(value = "doStuff.action", method = RequestMethod.POST)
public String onSubmit(HttpServletRequest request, HttpServletResponse response, final ModelMap modelMap,
        final @ModelAttribute("command") MyObject entry,
        final Errors errors, SessionStatus status,
        @RequestParam(value = "_page") Integer currentPage,
        @RequestParam(value = "_finish", required=false) Object finish,
        @RequestParam(value = "_cancel", required=false) Object cancel) {

    // submitting
    if (finish != null) {       
                    // do submit stuff here
        status.setComplete();
        return "redirect:/home.action";
    }

    // cancelling
    if (cancel != null) {
        status.setComplete();
        return "redirect:/home.action";                     
    }       

    // moving to next page
    int targetPage = WebUtils.getTargetPage(request, "_target", currentPage);
    if (targetPage >= currentPage) {    
        // validate current page here
        switch(currentPage) {
        case 0: // TODO: call validation
            if (!errors.hasErrors()) {
               // do some stuff to prepare the next page
            }
            break;                                      
        }
    }

    if (errors.hasErrors())
        return WIZARD_PAGES[currentPage];
    return WIZARD_PAGES[targetPage];
}

然后输入Value.jsp:

<form:form commandName="command">
    <form:input path="name"/>
            <input type="submit" name="_target1" value="<spring:message code="COMMON.NEXT"/>" />
    <input type="hidden" name="_page" value="0" />
 </form:form>

和confirmValue.jsp:

<form:form commandName="command">
${name}
    <input type="submit" name="_finish" value="<spring:message code="COMMON.SUBMIT"/>" />
   <input type="hidden" name="_page" value="1" />
</form:form>

【问题讨论】:

    标签: java spring binding command-objects


    【解决方案1】:

    字符串是不可变的。当你使用 MyObject 时,Spring 改变的是对象对 String 的引用,而不是 String 本身。

    【讨论】:

    • 我怀疑它与 String 的不变性有关,但为什么 Spring 不能像对对象属性一样更改对 String 的引用?我想如果结论是无法完成,那么为什么不重要。
    • 查看@Hung Tran 的回答,这正是正在发生的事情。
    【解决方案2】:

    我猜你的情况可能是由两件事引起的:

    1) 字符串是不可变对象。这意味着每当您分配一个新的字符串时,都会返回一个新的参考值

    2) 方法参数按值传递。因为String是引用类型,那么对象引用的引用值不能改变

    例如

    public static void change(String text) { // (1) pass by value
       text = "Hello Word"; // (2) immutable
    }
    
    public static void main(String[] args) {
      String str = "Hello";
      change(str);
      System.out.println(str); // Output: Hello
    }
    

    当我们将一个String对象引用包裹在另一个对象中时,那么传递给change方法的对象引用就是myObject不再是String引用了。这就是为什么使用 myObject 可以改变 String 对象引用的引用值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 2015-08-11
      • 1970-01-01
      • 2023-03-13
      • 2015-10-08
      • 1970-01-01
      相关资源
      最近更新 更多