1

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 public class Booking {

@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;
4

1 に答える 1

1

の問題は、firstName2 つあることですform:input:) 2 つ目は でなければなりませんmailAddress

事前計算された値の問題は単純です。ビュー名の文字列を返すときに、コントローラーが呼び出されません。この場合のモデルは空です。いくつかの解決策があります。事前計算をメソッドに抽出し、必要な場所で呼び出すことができます。または(私はこの方法を好みます)、インターセプターを設定して、URL のモデルを設定できます。

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

そしてポピュレータ:

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);
    }
}
于 2013-01-20T10:54:53.177 に答える