https://rogi221.tistory.com/157
스프링 - Part 4 - REST 방식과 Ajax를 이용하는 댓글 처리 01 (REST 방식으로 전환)
REST 방식으로 전환 @RestController REST 방식에서 가장 먼저 기억해야 하는 점은 서버에서 전송하는 것이 순수한 데이터라는 점이다. 기존 Controller에서 Model에 데이터를 담아서 JSP 등과 같은(View)로 전
rogi221.tistory.com
Ajax 댓글 처리 - 02
서비스 영역과 Controller 처리
서비스 영역과 Controller의 처리는 기존의 BoardService와 동일하게 ReplyService 인터페이스와 ReplyServiceImpl 클래스로 작성한다.
ReplyService 인터페이스
// ReplyService.java
package org.codehows.service;
import java.util.List;
import org.codehows.domain.Criteria;
import org.codehows.domain.ReplyVO;
public interface ReplyService {
public void register(ReplyVO board);
public ReplyVO get(Long bno);
public boolean modify(ReplyVO board);
public boolean remove(Long bno);
public List<ReplyVO> getList(Criteria cri, Long bno);
}
ReplyService를 구현하는 ReplyServiceImpl 클래스에는 @Service 어노테이션과 @Log4j를 적용한다.
ReplyServiceImpl 클래스
// ReplyServiceImpl.java
package org.codehows.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.codehows.domain.Criteria;
import org.codehows.domain.ReplyVO;
import org.codehows.mapper.ReplyMapper;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@Service
@Log4j
public class ReplyServiceImpl implements ReplyService {
@Setter(onMethod_ = @Autowired)
private ReplyMapper mapper;
@Override
public int register(ReplyVO vo) {
log.info("register......" + vo);
return mapper.insert(vo);
}
@Override
public ReplyVO get(Long rno) {
log.info("get......" + rno);
return mapper.read(rno);
}
@Override
public int modify(ReplyVO vo) {
log.info("modify......." + vo);
return mapper.update(vo);
}
@Override
public int remove(Long rno) {
log.info("remove........" + rno);
return mapper.delete(rno);
}
@Override
public List<ReplyVO> getList(Criteria cri, Long bno) {
log.info("get Reply List of a Board " + cri);
return mapper.getListWithPaging(cri, bno);
}
}
ReplyController의 설계
ReplyController는 앞의 예제에서 SampltController 와 유사하게 @RestController 어노테이션을 이용해서 설계하며 다음과 같은 URL을 기준으로 동작할 수 있게 작성한다.
REST 방식으로 동작하는 URL을 설계할 때는 PK를 기준으로 작성하는 것이 좋다.
PK만으로 조회, 수정, 삭제가 가능하기 때문이다.
댓글의 목록은 PK를 사용할 수 없기 떄문에 파라미터로 필요한 게시물의 번호(bno)와 페이지 번호(page) 정보들을 URL에서 표현하는 방식을 사용한다.
ReplyController는 ReplyService 타입의 객체인 ReplyServiceImpl 객체를 주입받도록 설계한다.
ReplyController의 일부
// ReplyController.java
package org.codehows.controller;
import org.codehows.service.ReplyService;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@RequestMapping("/replies/")
@RestController
@Log4j
@AllArgsConstructor
public class ReplyController {
private ReplyService service;
}
@Setter 주입을 이용하거나 위의 코드와 같이 @AllArgsConstructor를 이용해서 ReplyService 타입의 객체를 필요로 하는 생성자를 만들어서 사용한다.
등록 작업과 테스트
REST 방식으로 처리할 때 주의해야 하는 점은 브라우저나 외부에서 서버를 호출할 때 데이터의 포맷과 서버에서 보내주는 데이터의 타입을 명확히 설계해야 하는 것이다.
ReplyController 클래스
// ReplyController.java
package org.codehows.controller;
import org.codehows.domain.ReplyVO;
import org.codehows.service.ReplyService;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
@RequestMapping("/replies/")
@RestController
@Log4j
@AllArgsConstructor
public class ReplyController {
private ReplyService service;
@PostMapping(value = "/new",
consumes = "application/json",
produces = {MediaType.TEXT_PLAIN_VALUE })
public ResponseEntity<String> create(@RequestBody ReplyVO vo) {
log.info("ReplyVO: " + vo);
int insertCount = service.register(vo);
log.info("Reply INSERT COUNT: " + insertCount);
return insertCount == 1
? new ResponseEntity<>("success", HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
// 삼항 연산자 처리
}
}
create()는 @PostMapping으로 POST 방식으로만 동작하고 설계하고, consumes와 produces를 이용해서 JSON 방식의 데이터만 처리하도록 하고, 문자열을 반환하도록 설계한다. create() 의 파라미터는 @RequestBody를 적용해서 JSON 데이터를 ReplyVO 타입으로 변환하도록 지정한다.
테스트
POST 방식으로 전송 - JSON 형식으로 입력
{"bno":195, "reply":"Hello Reply","replyer":"user00"}
Send Request 클릭
성공했다면
작성된 댓글은 데이터베이스에 정상적으로 추가 되었는지 확인한다.
<sql>
select * from tbl_reply order by rno desc;
특정 게시물의 댓글 목록 확인
특정 게시물의 댓글 목록을 확인하는 작업은 아래와 같이 작성한다.
ReplyController 클래스
// ReplyController.java
... 생략 ...
@GetMapping(value = "/pages/{bno}/{page}",
produces = {
MediaType.APPLICATION_XML_VALUE,
MediaType.APPLICATION_JSON_UTF8_VALUE })
public ResponseEntity<List<ReplyVO>> getList(
@PathVariable("page") int page,
@PathVariable("bno") Long bno) {
log.info("getList.............");
Criteria cri = new Criteria(page, 10);
log.info(cri);
return new ResponseEntity<>(service.getList(cri, bno), HttpStatus.OK);
}
ReplyController의 getList()는 Criteria를 이용해서 파라미터를 수집하는데, '/{bno}/{page}'의 'page' 값은 Criteria를 생성해서 직접 처리해야한다.
댓글 삭제/조회
RestController의 댓글의 수정/삭제/조회는 위와 유사한 방식으로 JSOn이나 문자열을 반환하도록 설계한다.
ReplyController 클래스
// ReplyController.java
... 생략 ...
@GetMapping(value = "/{rno}",
produces = {
MediaType.APPLICATION_XML_VALUE,
MediaType.APPLICATION_JSON_UTF8_VALUE })
public ResponseEntity<ReplyVO> get(@PathVariable("rno") Long rno) {
log.info("get: " + rno);
return new ResponseEntity<>(service.get(rno), HttpStatus.OK);
}
@DeleteMapping(value= "/{rno}", produces = {MediaType.TEXT_PLAIN_VALUE})
public ResponseEntity<String> remove(@PathVariable("rno") Long rno) {
log.info("remove: " + rno);
return service.remove(rno) == 1
? new ResponseEntity<>("success", HttpStatus.OK)
: new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
댓글 수정
댓글 수정은 JSON 형태로 전달되는 데이터와 파라미터로 전달되는 댓글 번호(rno)를 처리하기 떄문에 아래와 같이 처리한다.
ReplyController.java
// ReplyController.java
... 생략 ...
@RequestMapping(method = {RequestMethod.PUT, RequestMethod.PATCH},
value = "/{rno}",
consumes = "application/json",
produces = {MediaType.TEXT_PLAIN_VALUE})
public ResponseEntity<String> modify(
@RequestBody ReplyVO vo,
@PathVariable("rno") Long rno) {
vo.setRno(rno);
log.info("rno : " + rno);
log.info("modify : " + vo);
return service.modify(vo) == 1?new ResponseEntity<>("success", HttpStatus.OK):new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR);
}
}
댓글 수정은 PUT 방식이나 PATCH 방식을 이용하도록 처리하고, 실제 수정되는 데이터는 JSON 포맷이므로 @RequestBody를 이용해서 처리한다. @RequestBody로 처리되는 데이터는 일반 파라미터나 @PathVariable 파라미터를 처리할 수 없기 때문에 직접 처리해주는 부분을 주의해야한다.
https://rogi221.tistory.com/160
'Spring' 카테고리의 다른 글
스프링 - Part 4 - REST 방식과 Ajax를 이용하는 댓글 처리 02 (Ajax 댓글 처리 - 04) (0) | 2023.03.30 |
---|---|
스프링 - Part 4 - REST 방식과 Ajax를 이용하는 댓글 처리 02 (Ajax 댓글 처리 - 03) (0) | 2023.03.29 |
스프링 - Part 4 - REST 방식과 Ajax를 이용하는 댓글 처리 02 (Ajax 댓글 처리 - 01) (0) | 2023.03.29 |
스프링 - Part 4 - REST 방식과 Ajax를 이용하는 댓글 처리 01 (REST 방식으로 전환) (0) | 2023.03.28 |
스프링 - Part 3 - 기본적인 웹 게시물 관리 09 (검색처리) (0) | 2023.03.28 |