Post on 03-Aug-2020
ธระยทธ ทองเครอ
Spring MVC
Spring MVCSpring MVC คอ Framework ทใชในการสรางเวบแอปพลเคชน โดยมการแยกสวน
ระหวางชน model และชน view เพอให UI programmers และ back end developers สามารถท างานไปพรอม ๆ กนได
Model Layer คอ สวนทประมวลผล business logic View Layer คอ สวนท render หนา interface โดยใชเทคโนโลยการแสดงผลตางๆ
เชน JSP, Facelets, FreeMarker หรอ ThymeleafController ใชรบ input จากผใชและสงไปประมวลท Repository แลวเกบผลลพธไว
ท model object เพอล าเลยงไปยงสวน View Layerการน า Spring Boot มาใชรวมกบ Spring MVC จะชวยลดการ Config เพราะม
บางสวนทท างานแบบอตโนมต ท าใหลดเวลาในการพฒนาลงได
2
บางสวน Spring สรางใหแลว บางสวนตอง implement เพม
การประมวลผลค ารองใน Spring MVC
3
1. DispatcherServlet รบ request2. DispatcherServlet สง path ไปยง HandlerMapping เพอเลอก Controller ทมอย3. DispatcherServlet น า Controller ทเลอกแลวสงไปยง HandlerAdapter4. HandlerAdapter เรยกเมธอดทนกพฒนาไดสรางไวในคลาส Controller ซงอาจจะมการประมวลทางธรกจ หรอเขาถงฐานขอมลโดยตรง หรอผาน Service
5. Controller เกบผลลพธการประมวลผลลงใน Model และระบชอ View สงกลบไปยง HandlerAdapter6. DispatcherServlet เรยก ViewResolver เพอเลอก View ตามทนกพฒนาก าหนด7. DispatcherServlet น าหนา view ทนกพฒนาสรางไว Render เปนผลลพธ8. สง response กลบไปยงผใช
สรางโดยนกพฒนา
Spring สรางใหแลว
โครงสรางโปรเจคส าหรบ Spring MVC
4
โฟลเดอรส าหรบเกบคลาสจาวา
1. สรางโฟลเดอรเกบไฟล css, js, html, รปภาพ
2. สรางโฟลเดอรเกบไฟล jsp
<dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-jasper</artifactId><scope>provided</scope>
</dependency>
เพม Lib ส าหรบแปลภาษา JSP
5
ไฟล application.properties
6
spring.mvc.view.prefix=/jsp/spring.mvc.view.suffix=.jsp
ระบโฟลเดอรทเกบไฟล jsp
ก าหนดใหอางถงไฟล jsp ไดโดยไมตองลงทายดวย .jsp
โครงสรางของคลาส Controller
7
@Controller@RequestMapping("/ชอ path ของ controller")public class XxxxxController {
@GetMapping("/ชอ path เขาถงเมธอด")public String ชอเมธอดใดๆดได([ตวแปรรบคา parameter], Model model) {
// เรยกเมธอดตางๆ จาก DAO/Repository หรอประมวลผล Business Logic
// เกบ object ตางๆ ลงใน model ทตองการให Template Engine น าไปแสดงผลmodel.addAttribute("ชอขอมลทจะสงไปยง view", ตวแปรทจะสงไปยง view);model.addAttribute("...", ...);
return "ชอ jsp ทใช render สวน view โดยไมตองใสนามสกล";หรอใช "redirect:/ชอ path ทจะสงตอ";
}}
ระบ path หลกของ Controller (สามารถละได)
ระบ annotation เพอก าหนดใหคลาสนเปน Controller (คลาสทสามารถรบ request และสง response ได)
เมธอด return คาเปน String
ตวแปร model ส าหรบบรรจขอมลเพอใชแสดงผลในหนา jsp
ตวอยางคลาส Controllerimport org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class FirstController {
@GetMapping("/")
public String welcome(Model model) {
model.addAttribute("message", "Civilized Land");
return "/home";
}
}
8
ก าหนด Path ทใชเขาถงเมธอดนแบบ GET
ก าหนดชอไฟล jsp ทจะสงไปแสดงผล
สราง attribute ชอ message ใหเกบสตรง "Civilized Land"
ตวอยาง JSP (home.jsp)
9
<%@ page language="java" contentType="text/html; charset=utf-8"
pageEncoding="utf-8" %>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>Welcome to ${message}</h1>
<img src="green.jpg" width="600">
</body>
</html>
ดงคา attribute ชอ message จากController ออกมาแสดงผล
การก าหนดรปแบบการเขาถง Controller @RequestMapping ใชก าหนด path ในการรบ request ทกชนด เชน
@RequestMapping("/addcustomer") หรอ@RequestMapping(value="/addcustomer", method=RequestMethod.POST)
@GetMapping ใชก าหนด path ทรบ request แบบ GET เชน@GetMapping("/listProduct")
@PostMapping ใชก าหนด path ทรบ request แบบ POST เชน@PostMapping("/checkLogin")
@PutMapping ใชก าหนด path ทรบ request แบบ Put มกใชใน Web API @PutMapping("/updateUser")
@DeleteMapping ใชก าหนด path ทรบ request แบบ Delete มกใชใน Web API @DeleteMapping("/deleteUser")
10
การรบขอมลของ Controller รบผาน URL Parameter ใช @RequestParam ก ากบ
http://localhost:8080/search?name=jim&age=20
รบผาน Path ใช @PathVariable ก ากบhttp://localhost:8080/customer/10/jim
11
@GetMapping("/search")String add(@RequestParam("name") String name, @RequestParam("age") Integer age, Model model) {
System.out.println("name=" + name);System.out.println("age=" + age);return "/home";
}
@GetMapping("/customer/{id}/{cname}")String check(@PathVariable("id") String cid, @PathVariable("cname") String name, Model model) {
System.out.println("id=" + cid);System.out.println("cname=" + name);return "/home";
}
การรบขอมลเกบลง JavaBeans
12
@Controllerpublic class TestController {
@GetMapping("/computeArea")public String computeArea(@ModelAttribute Triangle t, Model model) {
float area = (float)0.5 * t.getBase() * t.getHeight();model.addAttribute("area", area);return "triangle-area";
}}
triangle-area.jsp
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><html><head><meta charset="utf-8"></head><body><b>พนทสามเหลยม คอ ${area}</b></body></html>
JavaBeanspublic class Triangle {
private float base;private float height;public float getBase() {
return base;}public void setBase(float base) {
this.base = base;}public float getHeight() {
return height;}public void setHeight(float height) {
this.height = height;}
}
ก าหนดชอใน URL Parameter ทมชอเดยวกบตวแปรใน JavaBean
ใช @ModelAttribute และก ำหนดตวแปร JavaBeans ทตองกำรใชเกบขอมลจำก URL
ขอมลจำก URL จะถกเกบลงตวแปร t ทประกำศไว
กจกรรมจงสรางเวบส าหรบบวกเลขดวย Spring MVC โดยสง request ใหกบ Controller 2 คา
ไดแก a และ b หลงจากนนใหสวน Controller บวกคา และสงไปแสดงผลยงไฟล JSP
13
สงคาทาง URL
กจกรรมจงสรางเวบไซตส าหรบ Sign In เขาสระบบดวย Spring MVC ก าหนดให username
เปน “bobby” และ password เปน “1234” เปนขอมลทเขาสระบบได โดยสงผลการตรวจสอบไปแสดงผลทไฟล JSP
14
กรณ user และ password ถกตอง
กรณ user และ password ไมถกตอง
ระบบจดการขอมลลกคา
15
หนาแสดงรายการลกคาแบบฟอรมเพมขอมล
แบบฟอรมแกไขขอมล
หนาแสดงขอมลลกคาตามรหส
Repository Class (หรอ DAO)
16
@Repositorypublic class CustomerRepository {
@PersistenceContextprivate EntityManager entityManager; // ใชเรยกเมธอดจดการฐานขอมล ทสรางมาใหแลว
public List<Customer> findAll() {Query query = entityManager.createQuery("from Customer"); // สรางค าสง SELECT ขอมลจากตาราง customerreturn query.getResultList(); // ดงรายการผลลพธจากการ Query สงกลบ
}
public Customer findById(Integer id) {return entityManager.find(Customer.class, id); // คนหา Customer ตาม id
}
@Transactionalpublic Customer save(Customer customer) {
entityManager.persist(customer); // insert กรณไมมคา id ใน object หรอ update กรณมคา id ใน object return customer;
}
@Transactionalpublic void delete(Integer id) {
Customer customer = entityManager.find(Customer.class, id); // คนหาตาม id ทตองการลบentityManager.remove(customer); // เรมลบจรง
}}
Controller
17
@Controllerpublic class CustomerController {
// สราง object Repository ส าหรบเรยกใชในคลาส@Autowiredprivate CustomerRepository customerRepository;
@GetMapping("/customers") // ใชแสดงขอมลลกคาท งหมดpublic String getCustomerList(Model model) {
List<Customer> customerList = customerRepository.findAll();model.addAttribute("customerList", customerList);return "/list";
}
@GetMapping("/customer/{id}") // ใชแสดงลกคา 1 คน ตามรหสpublic String getCustomer(@PathVariable Integer id, Model model) {
Customer customer = customerRepository.findById(id);model.addAttribute("customer", customer);return "/detail";
}
@PostMapping("/customer/create") // ใชเพมขอมลลกคาpublic String create(@ModelAttribute Customer customer,
Model model) { customerRepository.save(customer);return "redirect:/customers";
}
// ใชโหลดขอมลลกคา 1 คน ตามรหส แลวสงไปแสดงในฟอรม@GetMapping("/customer/editform/{id}")public String load(@PathVariable Integer id, Model model) {
Customer customer = customerRepository.findById(id);model.addAttribute("customer", customer);return "/edit-form";// สงไปแสดงผลในฟอรมแกไข
}
@PostMapping("/customer/edit") // ใชแกไขขอมลลกคาpublic String update(@ModelAttribute Customer editCustomer, Model model) {
Customer oldCustomer = customerRepository.findById(editCustomer.getId());oldCustomer.setFirstName(editCustomer.getFirstName());oldCustomer.setLastName(editCustomer.getLastName());customerRepository.save(oldCustomer);return "redirect:/customers";// สงไปยง path แสดงขอมลลกคาท งหมด
}
@GetMapping("/customer/delete/{id}") // ใชลบขอมลลกคาตามรหสpublic String delete(@PathVariable Integer id) {
customerRepository.delete(id);return "redirect:/customers";// สงไปยง path แสดงขอมลลกคาท งหมด
}}
หนาแสดงรายการลกคา
18
Model: CustomerRepository
View: list.jsp
Controller: CustomerController
public List<Customer> findAll() {// สราง Query ดงขอมลท งหมดจากตาราง customerQuery query = entityManager.createQuery("from Customer"); // ดงรายการผลลพธจากการ Query สงกลบreturn query.getResultList();
}
@GetMapping("/customers")public String getCustomerList(Model model) {
// เรยกเมธอดจาก RepositortyList<Customer> customerList = customerRepository.findAll();model.addAttribute("customerList", customerList);return "/list";
}
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>…<h2>ขอมลลกคา</h2><table border="1">
<tr><th>รหส</th><th>ชอ</th><th>นามสกล</th><th></th></tr><c:forEach items="${customerList}" var="customer"><tr>
<td>${customer.id}</td><td><a href="/customer/${customer.id}">${customer.firstName}</a></td><td>${customer.lastName}</td><td>
<a href="/customer/editform/${customer.id}">แกไข</a><a href="/customer/delete/${customer.id}">ลบ</a>
</td></tr></c:forEach>
</table>
หนาแสดงขอมลลกคาตามรหส
19
Model: CustomerRepository
View: detail.jsp
Controller: CustomerController
public Customer findById(Integer id) {// คนหา Customer ตาม idreturn entityManager.find(Customer.class, id);
}
@GetMapping("/customer/{id}")public String getCustomer(@PathVariable Integer id, Model model) {
// ดงขอมลลกคา 1 คน ตามรหสCustomer customer = customerRepository.findById(id);model.addAttribute("customer", customer);return "/detail";
}
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html><html><head><meta charset="utf-8"></head><body>
<h2>ขอมลลกคาหมายเลข ${customer.id}</h2>ชอ: ${customer.firstName}<br>นามสกล: ${customer.lastName}
</body></html>
หนาเพมขอมล
20
Model: CustomerRepository
View: customer-form.html
Controller: CustomerController
@Transactionalpublic Customer save(Customer customer) {
// insert กรณไมมคา id ใน object หรอ update กรณมคา id ใน object entityManager.persist(customer); return customer;
}
@PostMapping("/customer/create")public String create(@ModelAttribute Customer customer, Model model) {
customerRepository.save(customer);return "redirect:/customers";
}
<!DOCTYPE html><html><head><meta charset="utf-8"></head><body>
<form action="/customer/create" method="post">ชอ: <input type="text" name="firstName"><br>สกล: <input type="text" name="lastName"><br>
<input type="submit" value="เพม"></form>
</body></html>
หนาแกไขขอมล
21
Model: CustomerRepository
View: edit-form.jsp
Controller: CustomerController
public Customer findById(Integer id) {// คนหา Customer ตาม idreturn entityManager.find(Customer.class, id);
}
@Transactionalpublic Customer save(Customer customer) {
// insert กรณไมมคา id ใน object หรอ update กรณมคา id ใน object entityManager.persist(customer); return customer;
}
@GetMapping("/customer/editform/{id}")public String load(@PathVariable Integer id, Model model) {
// ดงขอมลลกคา 1 คน ตามรหสCustomer customer = customerRepository.findById(id);model.addAttribute("customer", customer);return "/edit-form";// สงไปแสดงผลในฟอรมแกไข
}
@PostMapping("/customer/edit") public String update(@ModelAttribute Customer editCustomer, Model model) {
// แกไขขอมลลกคาCustomer oldCustomer = customerRepository.findById(editCustomer.getId());oldCustomer.setFirstName(editCustomer.getFirstName());oldCustomer.setLastName(editCustomer.getLastName());customerRepository.save(oldCustomer);return "redirect:/customers";// สงไปยงหนาแสดงรายการลกคา
}
<form action="/customer/edit" method="post"><input type="hidden" name="id"
value="${customer.id}">ชอ: <input type="text" name="firstName"
value="${customer.firstName}"><br>สกล: <input type="text" name="lastName"
value="${customer.lastName}"><br><input type="submit" value="แกไข">
</form>
การลบขอมล
22
Model: CustomerRepository
View: list.jsp
Controller: CustomerController
@Transactionalpublic void delete(Integer id) {
// คนหาตาม id ทตองการลบCustomer customer = entityManager.find(Customer.class, id); entityManager.remove(customer); // เร มลบจรง
}
@GetMapping("/customer/delete/{id}") public String delete(@PathVariable Integer id) {
customerRepository.delete(id);
// สงไปยง path แสดงขอมลลกคาท งหมดreturn "redirect:/customers";
}
<h2>ขอมลลกคา</h2><table border="1">
<tr><th>รหส</th><th>ชอ</th><th>นามสกล</th><th></th></tr><c:forEach items="${customerList}" var="customer"><tr>
<td>${customer.id}</td><td><a href="/customer/${customer.id}">${customer.firstName}</a></td><td>${customer.lastName}</td><td>
<a href="/customer/editform/${customer.id}">แกไข</a><a href="/customer/delete/${customer.id}">ลบ</a>
</td></tr></c:forEach>
</table>
กจกรรม จงสรางเวบแสดงความคดเหนโดยใช Spring Framework ซงหนาเวบมเพยงหนาเดยว ทแสดงความคดเหนทงหมดของ
ผใช แสดงชอผแสดงความเหน วนทแสดงความเหน และจ านวนผทกด Love ใหกบความคดเหนนน ผใชสามารถคลกทลงก Love เพอเพมจ านวนความชอบได และสามารถเพมความคดเหนใหมไดในแบบฟอรมสวนทายของหนาเวบ โดยจะตองใสชอผแสดงความคดเหนดวย (ใช Entity และ Repository จากบททผานมา)
23
Controller(ForumController)
View(main.jsp)
Model(ForumRepository) Database
(forumdb)Client
HTTP Request
JavaBeans(Forum)
Browser
Server
กจกรรมสรางเวบแอปพลเคชนส าหรบจดการขอมลงานทตองท าในแตละวน การ
ท างานหลกแสดงดง usecase diagram โดยใช Spring Framework
24
ตวอยางหนาจอ
Usecase Diagram