Home - SettingRhino/helloSpringBoot GitHub Wiki
Spring-Boot를 활용하여 CRUD메소드를 제공하는 REST API를 구현하라.
조건
- Database 이름: helloProductDB-학번이름
- Product Table 이름: productTable
- Spring Security 기능은 사용하지 않음
- Postman을 활용하여 API요청 및 응답메세지를 보일 것
- data.sql를 이용하여 미리 10개 이상의 Product생성
application.properties
server.port=9090
spring.datasource.url=jdbc:mysql://localhost:3306/helloProduct-1771155?characterEncoding=UTF-8&serverTimezone=Asia/Seoul
spring.datasource.username=root
spring.datasource.password=■■■■■■■
spring.jpa.hibernate.ddl-auto =create
spring.datasource.initialization-mode=always
management.endpoints.web.exposure.include=mappings
data.sql
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('mobilephone', '사과향이 난다.', 'apple', 'IPhoneX', '1400000', '15');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('mobilephone', '우주의 기운이 느껴진다.', 'samsung', 'galaxyS20', '1500000', '101');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('mobilephone', '매우 튼튼하다.그뿐이다', 'LG', 'ㅣ', '1350000', '13');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('labtop', '가벼운만큼 비싸다..', 'LG', 'Gram2020', '1750000', '18');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('labtop', '사과향이 나지만 매우 비싸다...', 'apple', 'MacBook', '2200000', '5');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('labtop', '우주의 기운이 느껴진다', 'samsung', 'galaxyBook', '1500000', '15');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('labtop', '전통이 우수하다', 'lenovo', 'ThinkPad', '2000000', '19');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('mobilephone', '대륙의 기상이 느껴진다', 'huawei', 'P30', '800000', '9000');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('tablet', '사과향이 난다.', 'apple', 'IPad_Pro', '1300000', '7');
INSERT INTO `helloproduct-1771155`.`producttable` (`category`, `description`, `manufacturer`, `name`, `price`, `unit_in_stock`) VALUES ('tablet', '우주의 기운이 느껴진다.', 'samsung', 'galaxyTab', '900000', '12');
### Product Model구성
public class Product{
private int id;
private String name;
private String category;
private int price;
private String manufacturer;
private int unitInStock;
private String description;
}
- API메소드 구성
-
POST
- POST http://localhost:9090/api/v1/products
- body에 데이터(JSON)를 담아 요청 서버에선 Serialization수행하여 객체로 변환 후 DB에 저장
-
GET
- GET full list of products http://localhost:9090/api/v1/products
- GET details of product with id http://localhost:9090/api/v1/products/{id}
- Fetch all products of a category http://localhost:9090/api/v1/products/category/{category}
-
PUT
- PUT http://localhost:9090/api/v1/products/{id}
- 해당 데이터 업데이트 수행
-
DELETE
- DELETE http://localhost:9090/api/v1/products/{id}
- 해당 데이터 업데이트 삭제
-
- actuator활용하여 URL Mapping정보를 캡처해라.
- http://localhost:9090/actuator/mappings 스크린샷
- Json Tree 중 mapping
- Json
{"contexts":{"application":{"mappings":{"dispatcherServlets":{"dispatcherServlet":[{"handler":"Actuator web endpoint 'mappings'","predicate":"{GET /actuator/mappings, produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}","details":{"handlerMethod":{"className":"org.springframework.boot.actuate.endpoint.web.servlet.AbstractWebMvcEndpointHandlerMapping.OperationHandler","name":"handle","descriptor":"(Ljavax/servlet/http/HttpServletRequest;Ljava/util/Map;)Ljava/lang/Object;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["GET"],"params":[],"patterns":["/actuator/mappings"],"produces":[{"mediaType":"application/vnd.spring-boot.actuator.v3+json","negated":false},{"mediaType":"application/vnd.spring-boot.actuator.v2+json","negated":false},{"mediaType":"application/json","negated":false}]}}},{"handler":"Actuator root web endpoint","predicate":"{GET /actuator, produces [application/vnd.spring-boot.actuator.v3+json || application/vnd.spring-boot.actuator.v2+json || application/json]}","details":{"handlerMethod":{"className":"org.springframework.boot.actuate.endpoint.web.servlet.WebMvcEndpointHandlerMapping.WebMvcLinksHandler","name":"links","descriptor":"(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)Ljava/util/Map;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["GET"],"params":[],"patterns":["/actuator"],"produces":[{"mediaType":"application/vnd.spring-boot.actuator.v3+json","negated":false},{"mediaType":"application/vnd.spring-boot.actuator.v2+json","negated":false},{"mediaType":"application/json","negated":false}]}}},{"handler":"kr.ac.hansung.cse.controller.HomeController#home(Model)","predicate":"{GET /}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.HomeController","name":"home","descriptor":"(Lorg/springframework/ui/Model;)Ljava/lang/String;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["GET"],"params":[],"patterns":["/"],"produces":[]}}},{"handler":"kr.ac.hansung.cse.controller.RestApiv1Controller#getProductById(int)","predicate":"{GET /api/v1/products/{id}}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.RestApiv1Controller","name":"getProductById","descriptor":"(I)Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["GET"],"params":[],"patterns":["/api/v1/products/{id}"],"produces":[]}}},{"handler":"kr.ac.hansung.cse.controller.RestApiv1Controller#postProduct(Product)","predicate":"{POST /api/v1/products}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.RestApiv1Controller","name":"postProduct","descriptor":"(Lkr/ac/hansung/cse/model/Product;)Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["POST"],"params":[],"patterns":["/api/v1/products"],"produces":[]}}},{"handler":"kr.ac.hansung.cse.controller.RestApiv1Controller#deleteCustomer(int)","predicate":"{DELETE /api/v1/products/{id}}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.RestApiv1Controller","name":"deleteCustomer","descriptor":"(I)Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["DELETE"],"params":[],"patterns":["/api/v1/products/{id}"],"produces":[]}}},{"handler":"kr.ac.hansung.cse.controller.RestApiv1Controller#updateProduct(int, Product)","predicate":"{PUT /api/v1/products/{id}}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.RestApiv1Controller","name":"updateProduct","descriptor":"(ILkr/ac/hansung/cse/model/Product;)Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["PUT"],"params":[],"patterns":["/api/v1/products/{id}"],"produces":[]}}},{"handler":"kr.ac.hansung.cse.controller.RestApiv1Controller#findByCategory(String)","predicate":"{GET /api/v1/products/category/{category}}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.RestApiv1Controller","name":"findByCategory","descriptor":"(Ljava/lang/String;)Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["GET"],"params":[],"patterns":["/api/v1/products/category/{category}"],"produces":[]}}},{"handler":"kr.ac.hansung.cse.controller.RestApiv1Controller#getAllProducts()","predicate":"{GET /api/v1/products}","details":{"handlerMethod":{"className":"kr.ac.hansung.cse.controller.RestApiv1Controller","name":"getAllProducts","descriptor":"()Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":["GET"],"params":[],"patterns":["/api/v1/products"],"produces":[]}}},{"handler":"org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#error(HttpServletRequest)","predicate":"{ /error}","details":{"handlerMethod":{"className":"org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController","name":"error","descriptor":"(Ljavax/servlet/http/HttpServletRequest;)Lorg/springframework/http/ResponseEntity;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":[],"params":[],"patterns":["/error"],"produces":[]}}},{"handler":"org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController#errorHtml(HttpServletRequest, HttpServletResponse)","predicate":"{ /error, produces [text/html]}","details":{"handlerMethod":{"className":"org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController","name":"errorHtml","descriptor":"(Ljavax/servlet/http/HttpServletRequest;Ljavax/servlet/http/HttpServletResponse;)Lorg/springframework/web/servlet/ModelAndView;"},"requestMappingConditions":{"consumes":[],"headers":[],"methods":[],"params":[],"patterns":["/error"],"produces":[{"mediaType":"text/html","negated":false}]}}},{"handler":"ResourceHttpRequestHandler [\"classpath:/META-INF/resources/webjars/\"]","predicate":"/webjars/**","details":null},{"handler":"ResourceHttpRequestHandler [\"classpath:/META-INF/resources/\", \"classpath:/resources/\", \"classpath:/static/\", \"classpath:/public/\", \"/\"]","predicate":"/**","details":null}]},"servletFilters":[{"urlPatternMappings":["/*"],"servletNameMappings":[],"name":"webMvcMetricsFilter","className":"org.springframework.boot.actuate.metrics.web.servlet.WebMvcMetricsFilter"},{"urlPatternMappings":["/*"],"servletNameMappings":[],"name":"requestContextFilter","className":"org.springframework.boot.web.servlet.filter.OrderedRequestContextFilter"},{"urlPatternMappings":["/*"],"servletNameMappings":[],"name":"Tomcat WebSocket (JSR356) Filter","className":"org.apache.tomcat.websocket.server.WsFilter"},{"urlPatternMappings":["/*"],"servletNameMappings":[],"name":"characterEncodingFilter","className":"org.springframework.boot.web.servlet.filter.OrderedCharacterEncodingFilter"},{"urlPatternMappings":["/*"],"servletNameMappings":[],"name":"formContentFilter","className":"org.springframework.boot.web.servlet.filter.OrderedFormContentFilter"}],"servlets":[{"mappings":[],"name":"default","className":"org.apache.catalina.servlets.DefaultServlet"},{"mappings":["/"],"name":"dispatcherServlet","className":"org.springframework.web.servlet.DispatcherServlet"}]},"parentId":null}}}