SpringMVC使用form:options进行表单验证

时间:2013-01-20 10:49:05

标签: spring spring-mvc validation

我正在尝试在Spring中设置表单验证,因此我使用的是javax.validation注释。这很好用,它很好地得到了错误。

我的表单中有一个form:options字段,它从我的控制器中获取预先计算的值,但如果您提交了错误的数据,这些预先计算的值就会丢失。

表格如下:

<form:form method="post" action="../add" commandName="new-booking"
        modelAttribute="new-booking" class="form-vertical">
        <table>
            <tr>
                <td><form:label path="numberOfBikesBooked">Anzahl der Fahrräder</form:label><font
                    color='red'><form:errors path='numberOfBikesBooked' /></font></td>
            </tr>
            <tr>
                <td><form:select path="numberOfBikesBooked">
                        <form:options items="${possibleBikeValues}" />
                    </form:select></td>
            </tr>
            <tr>
                <td><form:label path="firstName">Vorname</form:label><font
                    color='red'><form:errors path='firstName' /></font></td>
            </tr>
            <tr>
                <td><form:input path="firstName" /></td>
            </tr>
            <tr>
                <td><form:label path="lastName">Nachname</form:label><font
                    color='red'><form:errors path='firstName' /></font></td>
            </tr>
            <tr>
                <td><form:input path="lastName" /></td>
            </tr>
            <tr>
                <td><form:label path="mailAddress">Email</form:label><font
                    color='red'><form:errors path='mailAddress' /></font></td>
            </tr>
            <tr>
                <td><form:input path="mailAddress" /></td>
            </tr>
            <tr>
                <td><input type='submit' value='Buchen!' class="btn" /></td>
            </tr>
        </table>
        <form:hidden path="Date" />
        <form:hidden path="cancelURI" />
    </form:form>

这样的控制器(add验证表格,AvailableBikes渲染表格):

@RequestMapping(value = "/add", method = RequestMethod.POST)
public String addPerson(@ModelAttribute("new-booking") @Valid Booking booking,
        BindingResult result, Map<String, Object> model) {

    if(result.hasErrors()){
        return "booking";
    }

    logger.info(String.format("Adding a Booking with the following data: Name: %s %s Email: %s Date: %s", booking.getFirstName(), booking.getLastName(), booking.getMailAddress(), booking.getDate()));

    bookingService.addBooking(booking);

    model.put("booking", booking);

    return "success";
}

@RequestMapping(value = "/AvailableBikes", method = RequestMethod.POST)
public String getAvailableBikes(@ModelAttribute("date") StringDate parDate,
        Map<String, Object> model) {

    // Parse Date
    DateFormat dateFormat = new SimpleDateFormat("dd-MM-yy");
    Date inDate = Calendar.getInstance().getTime();
    try {
        inDate = dateFormat.parse(parDate.getDate());
    } catch (ParseException e) {
        logger.severe(e.getMessage());
        e.printStackTrace();
    }

    logger.info(String.format("Listing the available Bookings for the %s", inDate));

    int availableBookings = bookingService.getAvailableBookings(inDate);
    model.put("NumAvailableBikes", Integer.toString(availableBookings));

    // TODO: Fix this with the AvailableBikesRange
    List<Integer> allPossibleBikeValues = new ArrayList<Integer>();
    for (int i = 1; i <= 30; i++) {
        allPossibleBikeValues.add(i);
    }
    model.put("possibleBikeValues", allPossibleBikeValues);

    // Get ready for new booking
    Booking booking = new Booking();
    booking.setDate(inDate);
    // TODO: How to handle the Cancel?
    booking.setCancelURI("xyz");
    model.put("new-booking", booking);

    return "booking";
}

这是模型(我认为这不重要):

@Entity 公共课预订{

@Id
@GeneratedValue
private Integer id;

@Column(name = "date", nullable = false)
@NotNull
private Date date;

@Column(name = "numberOfBikesBooked", nullable = false)
@Min(1)
@Max(100)
private int numberOfBikesBooked;

@Column(name = "mailAddress", nullable = false)
@Email
private String mailAddress;

@Column(name = "firstName", nullable = false)
@NotBlank
@Size(min=3, max=100)
private String firstName;

@Column(name = "lastName", nullable = false)
@NotBlank
@Size(min=3, max=100)
private String lastName;

@Column(name = "cancelURI", nullable = true)
private String cancelURI;

1 个答案:

答案 0 :(得分:1)

firstName的问题是你有两个form:input :)第二个必须是mailAddress

预先计算值的问题很简单:当您返回视图名称字符串时,控制器不会被调用。这种情况的模型是空的。有几种解决方案:您可以提取预先计算方法并在需要的地方调用它。或者(我更喜欢这种方式)您可以设置interceptors来填充网址模型:

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/context-relative-url.html" />
        <bean class="a.b.c.DropDownPopulator" />
    </mvc:interceptor>
</mvc:interceptors>

和populator:

public class DropDownPopulator extends HandlerInterceptorAdapter {

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        Map<String, String> result = new LinkedHashMap<String, String>(/*map for dropdown*/);

        modelAndView.addObject("values", result);
    }
}