Spring_FrameWork

서비스영역과 Controller처리

tmxhsk99 2018. 12. 6. 14:47

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


서비스영역과  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 타입ㅇ의 객체를 필요로 하는 생성자를 만들어서 사용 

등록 작업과 테스트 

REST  방식으로 처리할 대 주의해야 하는 점은 브라우저나 외ㅏ부에서 서버를 호출할때 데이터의 포맷과 서버에서 보내주는 데이터의 타입을 명확히 설계해야 하는 것이다 .
예를 들어 댓글등록은  JSON 타입으로 댓글을 전송하고 
서버에서 댓글의 처리 결과가 정상적으로 되었는지 문자열로 결과를 알려주도록한다.


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

reply controller에서 content type 을 application/json으로 지정안하면 오류가 뜬다


전송에 성공한 모습 


테스트 댓글이외에 값이 json형식으로 데이터 베이스에 정상적으로 추가되었는지 확인가능하다.