Spring MVC – 10 – Form Handling | @ModelAttribute
Merhaba Arkadaslar.
Bu bolumde Spring MVC ile basit bir form uygulamasi yapacagiz. Sonraki bolumlerde ,Validation , Error Message gibi konularla ilgili ornegimizi gelistirecegiz. Buradaki ornegimiz en temel sekilde olacaktir.
Simdiye kadar olan orneklerimizde hep Controller’dan data ekledik. Yani ;
model.addAttribute(message,"Welcome")
ve bu ekledigimiz data’ya JSTL yardimiyla JSP sayfamizdan ulastik ;
${message}
Peki data’yi view’de eklemek istersek. Bu durumda Controller’dan nasil bu veriye ulasabiliriz.
Yani disaridan HTML forma girilen verilere Controller uzerinden nasil erisim saglariz ?
Iste bu noktada Spring bizim icin bir cozum saglamaktadir.
@ModelAttribute
Spring tag library , HTML <form> ve <input> taglarina benzer sekilde ozel taglara sahiptir.
Spring tag library kullanabilmek icin @taglib directive’ini JSP sayfamiza eklememiz gereklidir.
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
Burada ornegimiz icerisinde kullanacagimiz Spring tag library ;
- <form:form>
- <form:input>
- <form:textarea>
- <form:select>
- <form:option>
- <form:radiobutton>
- <form:radiobuttons>
productAdd.jsp
Onceki ornegimizde hatirlayacagimiz gibi JSP sayfamizda Bootstrap kullanmistik. Burada onemli olan kisimlari paylasiyorum. Oncelikle @taglib directive tanimlarini yapalim.
Sonrasinda <form:form> tagini kullaniyoruz burada dikkat etmemiz gereken nokta ; modelAttribute attribute’u olacaktir.
Bununla birlikte modelAttribute yerine bazi orneklerde commandName attribute’unun kullanildigini gorebiliriz. Bu attribute’ler ayni isi yapmaktadir.
org.springframework.web.servlet.tags.form.FormTag
public void setModelAttribute(String modelAttribute) { this.modelAttribute = modelAttribute; } protected String getModelAttribute() { return this.modelAttribute; } public void setCommandName(String commandName) { this.modelAttribute = commandName; } protected String getCommandName() { return this.modelAttribute; }
Daha sonrasinda yukarida listeledigimiz Spring tag’larini kullaniyoruz. Bu taglarin HTML olarak karsiliklari text , text area , radiobutton vs olacaktir.
Bu taglarda dikkat edecegimiz nokta path attribute’u olacaktir. Spring tag library HTML elemenleri ile form-backing bean modelini bind edecektir.
Bu ornegimizde modelimiz Product sinifimiz olacaktir , bu sinifta yer alan property/instance variable’lari path attribute’te kullaniyoruz. Boylece Spring bizim icin bind islemini gerceklestirecektir.
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %> <form:form modelAttribute="newProduct" class="form-horizontal" method="post"> ... <form:input id="productId" path="productId" type="text" class="form:input-large"/> ... <form:input id="name" path="name" type="text" class="form:input-large"/> ... <form:input id="unitPrice" path="unitPrice" type="text" class="form:input-large"/> ... <form:textarea id="description" path="description" rows = "2"/> ... <form:select id="manufacturer" path="manufacturer" type="text" class="form:input-large"> <form:option value="Apple">Apple</form:option> <form:option value="Google">Google</form:option> <form:option value="Samsung">Samsung</form:option> </form:select> ... ... <form:select id="category" path="category" type="text" class="form:input-large"> <form:option value="Laptop">Laptop</form:option> <form:option value="Tablet">Tablet</form:option> <form:option value="Smart Phone">Smart Phone</form:option> </form:select> .. <form:input id="unitsInStock" path="unitsInStock" type="text" class="form:input-large"/> ... <form:radiobutton path="condition" value="New" />New <form:radiobutton path="condition" value="Old" />Old <form:radiobutton path="condition" value="Refurbished" />Refurbished ... <input type="submit" id="btnAdd" class="btn btn-primary" value ="Add"/> ... </form:form>
Simdi de Controller tarafini yapalim. Dusundugumuzde , oncelikle HTTP GET istegi ile form sayfamiza istekte bulunmayiz daha sonrasinda HTTP POST ile submit islemini gerceklestirmemiz gerekir.
ProductManagementController.java
Kodu inceleyecek olursak onceki ornegimizde @PathVariable , @RequestParam annotation’larini kullanmistik , burada da benzer sekilde @ModelAttribute annotation’ini kullaniyoruz. Dikkat edecek olursak attribute olarak JSP sayfamizda kullandigimiz “newProduct” degerini kullaniyoruz.
Dikkat edecek olursak getNewProductForm metodumuzda RequestMethod.GET degerini kullandik. Boylece /add URL’i icin HTTP GET istekleri bu metot icin karsilanacaktir.
Geriye addProduct.jsp sayfasini donuyoruz ve @ModelAttribute annotation ile form-backing bean bilgisini veriyoruz.
Ikinci metodumuz da HTTP POST istegini karsilayacaktir , yani formu submit ettigimizde bu metot istegi karsilayacaktir.
Daha sonrasinda /products url adresine redirect islemi yapiyoruz. Boylece istek tekrar karsilanacak ve tum urunlerin listesi getirilecektir. Tabi ekledigimiz urun de gelecektir.
package _09.form.handling.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import _09.form.handling.domain.Product; import _09.form.handling.service.ProductService; @Controller @RequestMapping("/products/management") public class ProductManagementController { @Autowired private ProductService productService; @RequestMapping(value = "/add", method = RequestMethod.GET) // http://localhost:8080/injavawetrust.springmvc/products/management/add public String getNewProductForm(@ModelAttribute("newProduct") Product newProduct) { return "09.form.handling.view/productAdd"; } @RequestMapping(value = "/add", method = RequestMethod.POST) public String processAddNewProductForm(@ModelAttribute("newProduct") Product productToBeAdded) { productService.addProduct(productToBeAdded); return "redirect:/products"; } }
Controller , form-backing beanden verileri cekebilir @ModelAttribute annotation’ini kullaniriz. Form-backing bean ya da form bean , form datalarini store etmek icin kullanilir.
http://localhost:8080/injavawetrust.springmvc/products/management/add
Ilgili URL adresine gidip formu dolduralim , submit ettigimizde basariyla ekleme islemi gerceklesecektir.
Reference Data
JSP dosyamizi inceleyecek olursak icerisinde hard-coded olarak kullandik ya da radiobuttonlari benzer sekilde hard-coded olarak yazdik.
Peki bu alanlar dinamik olarak gelecekse ozaman ne yapmamiz gerekir ? Iste bunun icin yine @ModelAttribute annotation’indan yararlanacagiz.
Kodumuzu inceleyecek olursak metotlarin basinda @ModelAttribute annotation’ini kullandik.
Bu metotlar istek karsilanmadan once calisacaktir. Boylece form sayfamiz acildiginda eklemis oldugumuz bu degerleri gorebiliriz. Tabi bunun icin JSP sayfamizda da degisiklik yapmamiz gereklidir.
// referenceData @ModelAttribute("manufacturerList") public List<String> prepareManufacturerList() { return Arrays.asList("Apple", "Google", "Samsung"); } // referenceData @ModelAttribute("categoryList") public List<String> prepareCategoryList() { return Arrays.asList("Laptop", "Tablet", "SmartPhone"); } // referenceData @ModelAttribute("conditionMap") public Map<String, String> prepareConditionMap() { Map<String, String> conditions = new HashMap<String, String>(); conditions.put("new", "New"); conditions.put("old", "Old"); conditions.put("refurbished", "Refurbished"); return conditions; } //
JSP sayfamizda hardcoded olarak ekledigimiz kisimlari yorum satiri haline getirdim , ilgili Spring tag’lari su sekilde olacaktir. Dikkat edecek olursak burada <form:select> ve <form:radiobuttons> taglari icin items attribute’unu ekledik ve ilgili model attributuler ile bind etmesini sagladik. Bir diger nokta olarak <form:radiobutton> degil <form:radibuttons> tagini kullaniyoruz.
<form:select id="manufacturer" path="category" type="text" class="form:input-large" items="${manufacturerList}"/> ... <form:select id="category" path="manufacturer" type="text" class="form:input-large" items="${categoryList}"/> ... <form:radiobuttons path="condition" items="${conditionMap}"/>
Initialize Model
Bir diger nokta olarak formdaki alanlari initialize edebiliriz ya da diledigimiz option’ini secili olarak gelmesini isteyebiliriz. Bunun icin HTTP GET istegini karsiladigimiz metotta set metotlarini kullanmamiz yeterli olacaktir.
@RequestMapping(value = "/add", method = RequestMethod.GET) // http://localhost:8080/injavawetrust.springmvc/products/management/add public String getNewProductForm(@ModelAttribute("newProduct") Product newProduct) { newProduct.setDescription("default description"); newProduct.setCondition("new"); newProduct.setCategory("Tablet"); newProduct.setManufacturer("Samsung"); return "09.form.handling.view/productAdd"; }
Ornegimizi tekrar calistiralim ;
Ornek bir urun ekleyelim ;
Github kaynak kodlar / source folder
Injavawetrust-springmvc-tutorial
Yazimi burada sonlandiriyorum.
Herkese Bol Javali Gunler dilerim.
Be an oracle man , import java.*;
Levent Erguder
OCP, Java SE 6 Programmer
OCE, Java EE 6 Web Component Developer
Leave a Reply