서비스영역과 Controller처리
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
서비스영역과 Controller 처리는
기존의 BoardService와 동일하게
ReplyService 인터페이스와 ReplyServiceimpl 클래스를 작성.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | package org.zerock.service; import java.util.List; import org.zerock.domain.Criteria; import org.zerock.domain.ReplyVO; public interface ReplyService { public int register (ReplyVO vo); public ReplyVO get (Long rno); public int modify(ReplyVO vo); public int remove (Long rno); public List<ReplyVO> getList(Criteria cri , Long bno); } | cs |
ReplyService를 구현하는 ReplyServiceImpl 클래스에는 @Service 어노테이션과 @Log4j를 적용한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | package org.zerock.service; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.zerock.domain.Criteria; import org.zerock.domain.ReplyVO; import org.zerock.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 "+ bno); return mapper.getListWithPaging(cri, bno); } } | cs |
ReplyServiceImpl은 ReplyMapper에 의존적인관계이기 때문에 위의 코드와 같이 @Setter를 이용해서 처리하거나
스프링 4.3의 생성자와 자동주입을 이용해서 아래와 같이 처리할 수 있습니다.
@Service
@Log4j
@ALLArgsConstructor
public class ReplyServiceImpl implements ReplyService{
private ReplyMapper mapper ;
....생략...
}
ReplyController의 설계
ReplyController 는 SampleController와 유사하게 @RestController 어노테이션을 이용해서 설계하며 다음과 같은 URL을 기준으로 동작할 수 있게 작성합니다.
작업 |
URL |
HTTP전송방식 |
등록 |
/replies/new |
POST |
조회 |
/replies/:rno |
GET |
삭제 |
/replies/:rno |
DELETE |
수정 |
/replies/:rno |
PUT or PATCH |
페이지 |
/replies/pages/:bno/:page |
GET |
REST 방식으로 동작하는 URL을 설계할 때는 PK를 기준으로 작성하는 것이 좋다
PK만으로 조회 , 수정 , 삭제가 가능하기 때문
댓글의 목록은 PK를 사용할수없기때문에 파라미터로 필요한 게시물의 번호(bno)와 페이지 번호(page)정보를 URL에 표현하는 방식을 사용
ReplyController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package org.zerock.controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.zerock.service.ReplyService; import lombok.AllArgsConstructor; import lombok.extern.log4j.Log4j; @RequestMapping("/replies/") @RestController @Log4j @AllArgsConstructor public class ReplyController { private ReplyService service; } | cs |
@Setter 주입을 이용하거나 위의 코드와 같이 @AllArgsContstructor 를 이용해서 ReplyService 타입ㅇ의 객체를 필요로 하는 생성자를 만들어서 사용
등록 작업과 테스트
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package org.zerock.controller; 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 org.zerock.domain.ReplyVO; import org.zerock.service.ReplyService; 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); //삼항연산자 처리 } } | cs |
create()는 @PostMapping으로 POST 방식으로만 동작하도록 설계하고 , consumes 와 produces를 이용해서 JSON 방식의 데이터만 처리하도혹 하고, 문자열을 반환 하도록 설계합니다 .
create() 의 파라미터는 @RequestBody를 적용해서 JSON데이터를 ReplyVO 타입으로 변환하도록 지정
create()는 내부적으로 ReplyServiceImpl을 호출해서 register()를 호출하고, 댓글이 추가된 숫자를 확인해서 브라우저에서 200 OK 혹은 500 Internal Server Error 를 반환하도록 합니다 .
테스틀르 위해서 프로젝트를 '/' 경로로 실행하고 , 크롬 확장 프로그램등을 이용해서 테스트한다.
테스트 시에는 POST 방식으로 전송하고 , 'Content-Type'은 'application/json'으로 지정해야한다.
실제 전송되는 데이터는 존재하는 게시물 번호 (bno)와 댓글 내용(reply) , 댓글 작성자(replyer)를 JSON 문법에 맞게 작성하도록 주의 합니다 . 게시물의 번호는 기존에 존재하는 번호이어야 하므로 주의가 필요
{"bno":314575, "reply" : "hello reply" ,"replyer":"user00"} |
오류발생
check whether you have multiple ContextLoader* definitions in your web.xml!
자바 설정과 xml설정이 중복으로 되어있어서 나오는 문제
자바설정을 없애주어야한다.
테스트시
HTTP Status 415 - request entity is in a format not supported
테스트 댓글이외에 값이 json형식으로 데이터 베이스에 정상적으로 추가되었는지 확인가능하다.