我正在尝试在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;
答案 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);
}
}