บทที่ 5 MVC (Model-View-Controller) - Spring MVC.pdf · 2020-04-07 ·...

Post on 03-Aug-2020

1 views 0 download

Transcript of บทที่ 5 MVC (Model-View-Controller) - Spring MVC.pdf · 2020-04-07 ·...

ธระยทธ ทองเครอ

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