Cześć, mam mały problem z poprawnym przekazywaniem atrybutów między kontrolerem a widokiem jsp. Chcę wyświetlić użytkownikowi formularz do wypełnienia, a po wpisaniu błędnych danych ma on wrócić do tego samego widoku i wskazać niepoprawne dane. Mam do tego dwie metody GET i POST przekazujące sobie obiekt Product. Obiekt Product jest atrybutem formularza więc nie ma problemu z przekazywaniem go między widokami. Problem pojawia się gdy wczytam z bazy listę producentów oraz kategorii, ponieważ nie potrafię przekazać ich jako atrybuty razem z formularzem (albo źle je odbieram - raczej to pierwsze ;] ). Poniżej wrzucam dwie metody z kontrolera i fragment widoku.
Controller
@RequestMapping(value="/add",method=RequestMethod.GET)
public String getAddNewProductForm(Model model) {
Product newProduct=new Product();
model.addAttribute("newProduct",newProduct);
model.addAttribute("categories",categoryService.getAllCategories());
model.addAttribute("manufacturers",categoryService.getAllManufacturers());
return "addProduct";
}
@RequestMapping(value="/add",method=RequestMethod.POST)
public String processAddNewProductForm(@ModelAttribute("newProduct") @Valid Product productToBeAdded, /***@ModelAttribute("categories") List<Category> categories <--TO NIE DZIAŁA. DLACZEGO?*/
BindingResult result,HttpServletRequest request) {
if(result.hasErrors()) {
return "addProduct";
}
String[] suppressedFields=result.getSuppressedFields();
if(suppressedFields.length>0) {
throw new RuntimeException("Próba wiązania niedozwolonych pól: "+StringUtils.arrayToCommaDelimitedString(suppressedFields));
}
MultipartFile productImage = productToBeAdded.getProductImage();
if (productImage!=null && !productImage.isEmpty()) {
productToBeAdded.setProductImage(productImage);
}
productService.addProduct(productToBeAdded);
return "redirect:/products";
}
addProduct.jsp
.
.
.
<section class="container">
<form:form modelAttribute="newProduct" class="form-horizontal"
enctype="multipart/form-data">
<form:errors path="*" cssClass="alert alert-danger" element="div" />
<fieldset>
<div class="form-group">
<label class="control-label col-lg-2 col-lg-2" for="productId"><spring:message
code="addProduct.form.name.label" /></label>
<div class="col-lg-10">
<form:input id="name" path="name" type="text"
class="form:input-large" />
<form:errors path="name" cssClass="text-danger" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2 col-lg-2" for="productId">Cena</label>
<div class="col-lg-10">
<form:input id="unitPrice" path="unitPrice" type="text"
class="form:input-large" />
<form:errors path="unitPrice" cssClass="text-danger" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2 col-lg-2" for="productId">Marka</label>
<div class="col-lg-10">
<select id="manufacturers" name="manufacturers" style="max-height: 100px;">
<c:forEach items="${manufacturers}" var="manufacturer">
<option value="${manufacturer.id}">${manufacturer.name}</option>
</c:forEach>
</select>
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2 col-lg-2" for="productId">Kategoria</label>
<div class="col-lg-10">
<select id="categories" name="categories" style="max-height: 100px;">
<c:forEach items="${categories}" var="category">
<option value="${category.id}">${category.name}</option>
</c:forEach>
</select>
<form:errors path="category" cssClass="text-danger" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2 col-lg-2" for="productId">Liczba
sztuk w magazynie</label>
<div class="col-lg-10">
<form:input id="unitsInStock" path="unitsInStock" type="text"
class="form:input-large" />
<form:errors path="unitsInStock" cssClass="text-danger" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2" for="description">Opis</label>
<div class="col-lg-10">
<form:textarea id="description" path="description" rows="2" />
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2" for="condition">Stan</label>
<div class="col-lg-10">
<form:radiobutton path="condition" value="new" checked="checked"/>
Nowy
<form:radiobutton path="condition" value="used" />
Używany
</div>
</div>
<div class="form-group">
<label class="control-label col-lg-2" for="productImage"> <spring:message
code="addProdcut.form.productImage.label" />
</label>
<div class="col-lg-10">
<form:input id="productImage" path="productImage" type="file"
class="form:input-large" />
<form:errors path="productImage" cssClass="text-danger" />
</div>
</div>
<div class="form-group">
<div class="col-lg-offset-2 col-lg-10">
<input type="submit" id="btnAdd" class="btn btn-primary"
value="Dodaj" />
</div>
</div>
</fieldset>
</form:form>
</section>
Gdzie w widoku przechować atrybuty categories i manufacturers aby odebrałą je metoda POST i przesłała ponownie razem z komunikatami o błędach do widoku?
Przed przesłaniem formularza