使用Springframework MVC在javascript屏幕上共享用户对象

时间:2013-02-14 12:47:40

标签: java spring servlets spring-mvc

之前我问过如何使用Webflow执行此操作,但事实证明这对我的情况不切实际。

我试图浏览3个屏幕,这些屏幕添加到对象信息,然后需要确认最后添加到数据库。 [为了保持简洁等]

第一个屏幕以用户名为例 然后下一个屏幕需要联系信息 然后第三个屏幕显示摘要并要求确认

我无法弄清楚如何通过多个屏幕传递相同的对象。我理解如何将信息从一个屏幕传递到下一个屏幕,但由于某种原因,相同的技术无法通过多个屏幕工作。

样本3页:

AddUser.jsp

<div id="form">
<h2 >Step 1</h2>
    <form action="AddUserContact" method="post">
        <table>
            <tr>
                <td>User Name:</td>
                <td><input type="text" id="username" name="username"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="Next"/></td>
            </tr>
        </table>
    </form>
</div>

AddUserContact.jsp

<div id="form">
<h2 >Step 2</h2>
    <form action="UserSummaryConfirm" method="post">
        <table>
            <tr>
                <td>${user.username}</td>
            </tr>
            <tr>
                <td>Address:</td>
                <td><input type="text" id="address" name="address"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="Next"/></td>
            </tr>
        </table>
    </form>
</div>

UserSummaryConfirm.jsp

<h2>Step 3</h2>
    <form action="home" method="post">
        <table>
            <tr>
                <td>User Name:</td>
                <td>${user.username}</td>
            </tr>
            <tr>
                <td>Address:</td>
                <td>${address}</td>
            </tr>
            <tr>
                <td><a href="home">Confirm</a></td>
            </tr>
        </table>
    </form>

我有一个控制器用于每一页[它让我更好地了解发生了什么,我稍后会简化它]

AddUserController.java

@Controller
public class AddUserController{
@RequestMapping(value = "AddUser")
    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
    User user = new User();
    ModelAndView mav = new ModelAndView("AddUser");
    user.setUserName(request.getParameter("username"));
    mav.addObject("user", user);
    return mav;
    }
}

AddUserContactController.java

@Controller
public class AddUserContactController{
@RequestMapping(value = "AddUserContact")
    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mav = new ModelAndView("AddUserContact");
        mav.addObject("user", request.getParameter("user"));
        return mav;
       }
  }

AddUserConfirm.java

@Controller
public class AddUserConfirm{
    @RequestMapping(value = "UserSummaryConfirm")
    public ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
        ModelAndView mav = new ModelAndView("UserSummaryConfirm");
        mav.addObject("user", request.getParameter("user"));
        mav.addObject("address", request.getParameter("address"));
        return mav;
    }
}

然后User类只是一个带有getter和setter的简单类。 我遇到的问题是无论我试图传递的是什么,我似乎无法弄清楚为什么同样的技术无效。

第三个屏幕上的地址显示没问题,但用户名不会显示在任何屏幕上。

使用webflow,我创建了一个UserBean,它对所有webflow屏幕都是全局的。可以轻松地从任何屏幕添加到同一对象并显示任何信息。我怎样才能达到相同的效果?

谢谢。

工作代码:

使用SessionAttributes

AddUser.jsp

<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<div id="form">
<h2 >Step 1</h2>
    <form:form action="AddUserContact" commandName="user" method="POST">
        <table>
            <tr>
                <td>User Name:</td>
                <td><form:input type="text" id="username" path="username"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="Next"/></td>
            </tr>
        </table>
    </form:form>
</div>

AssUserContact.jsp

<div id="form">
<h2 >Step 2</h2>
    <form:form action="UserSummaryConfirm" commandName="user" method="post">
        <table>
            <tr>
                <td>Address:</td>
                <td><input type="text" id="address" path="address"/></td>
            </tr>
            <tr>
                <td><input type="submit" value="Next"/></td>
            </tr>
        </table>
    </form>
</div>

UserSummaryConfirm.jsp

<h2>Step 3</h2>
    <form:form action="home" method="get">
        <table>
            <tr>
                <td>User Name:</td>
                <td><%=session.getAttribute("username")%></td>
            </tr>
            <tr>
                <td>Address:</td>
                <td><%=session.getAttribute("address")%></td>
            </tr>
            <tr>
                <td><a href="home">Confirm</a></td>
            </tr>
        </table>
    </form:form>

AddUserController.java

@Controller
@SessionAttributes({ "username", "address" })
public class AddUserController{
    User usr = new User();    

@RequestMapping(value = "AddUser")
   public String loadIndex(Model model, User user) {
    model.addAttribute("User", user);
    return "AddUser";
    }

@RequestMapping(value = "AddUserContact")
public String processUserName(Model model, User user) {
usr.setUsername(user.setUsername());
model.addAttribute("User", user);
return "AddUserContact";
}

@RequestMapping(value = "UserSummaryConfirm")
public String processUserContact(Model model, User user) {
usr.setAddress(user.getAddress());
model.addAttribute("username", usr.getUsername());
model.addAttribute("address", usr.getAddress());
return "UserSummaryConfirm";
    }

2 个答案:

答案 0 :(得分:0)

因为在第二个屏幕中你正在使用

    <tr>
        <td>${user.username}</td>
    </tr>

用户输入未绑定到任何输入,因此不会将其传递给带有表单数据的控制器 当您使用地址

    <tr>
        <td>Address:</td>
        <td><input type="text" id="address" name="address"/></td>
    </tr>  

因为它绑定到输入(因为您已分配name="address"path="name"相同)所以它的值将被发送到控制器。

如果你想在3个屏幕上传递相同的对象,那么最好使用@SessionAttribute而不是隐藏它并一次又一次地传递。


编辑:

当您正在使用会话属性时,从第二个屏幕中删除输入元素。(它绑定到用户名)。只需使用

   <td>session.getAttribute("username")%></td>

答案 1 :(得分:0)

之前我做过这样的“向导式”表格。我的解决方案使用了一个表单bean,我们将整个流程放入会话中,并且只包含每个页面中需要添加的部分。除非包含给定值的输入,否则Spring不会删除表单bean中的值。我们不使用JSR-303,如果您使用它,我认为这种方法不会起作用。我们的验证使用了BindingErrors和自定义验证代码的组合,所以我只是将代码设置为一次只验证部分,对应于刚刚提交的表单的页面。