티스토리 뷰

SpringBoot+Thymeleaf

업무로직 만들기

joyHong 2020. 2. 10. 00:45

이전 포스팅에서는 RestController를 생성하여 뷰 페이지 없이 요청과 응답을 하는 것을 살펴보았다.

이번에는 그 연장선에서 뷰 페이지 없이 RestController를 이용하여 업무로직까지 간략히 만들어 보려고 한다.

먼저 프로젝트에 repository 와 service 패키지를 생성한다.

이 예제에서는 데이터베이스를 활용하고 있지 않기 때문에

레파지토리 구현 클래스에 임시로 사용할 데이터 값을 생성하는 코드를 추가할 것이다.

레파지토리 인터페이스는 VO 클래스를 통해 데이터를 다루는 역할(CRUD)을 할 것이다. 

만약 데이터베이스를 연동하게 되면 레파지토리 인터페이스에서 처리를 하도록 변경하면 된다.

이 부분은 나중에 다시 이야기를 할 예정이다.

서비스 패키지에는 서비스 인터페이스와 그것의 구현 클래스를 생성하여 실제적인 업무로직을 처리하도록 구현한다.

생성이 되어야 하는 클래스와 인터페이스 구조는 아래와 같다.

생성해야 하는 프로젝트 구조

먼저 레파지토리 부분을 작성하는게 개인적으로는 코드 진행 상 편리한 것 같다.

그리고 인터페이스와 그 구현체를 생성할 때는 어느 쪽을 먼저하던지 개인이 편리한 방법을 선택하면 되지 않을까 생각한다.

만약 인터페이스 구현 클래스를 먼저 생성하였으면 이클립스에서 제공하는 단축키로 refactor > Extract Interface 를 하면 되고

인터페이스를 먼저 생성하였으면 인터페이스 구현 클래스를 생성시 오류 안내에 따라 구현할 것들을 추가하면 되기 때문이다.

어찌됐든 위에서 잠깐 언급한 바와 같이 이 예제에서는 데이터베이스를 사용하지 않기 때문에

이를 대신할 코드를 삽입하겠다. 이는 컨트롤러가 빈에 등록될 때 초기값으로 임의의 데이터를 생성하여 넣도록 하는 것이다. 따라서 코드를 수정하거나 컨테이너를 재시작하면 이전의 내용이 사라지고 초기값으로 변경되니 유의하기를 바란다.

코드는 아래와 같다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@PostConstruct
    public void init() {
        // TODO Auto-generated method stub
        Logger.getLogger("com.joyhong.repository.BookRepositoryImpl").log(Level.INFO, "Test for repository data");
        bookMap = new HashMap<Long, Book>();
        for(int i=0; i<10; i++) {
            id++;
            Book book = new Book();
            book.setSeq(id);
            book.setTitle("책 제목 " + id);
            book.setCreator("책 저자 " + id);
            book.setPublisher("출판사 " + id);
            book.setPublishedYear(2010);
            
            bookMap.put(id, book);
        }
    }
 

여기서 중요한 부분은 @PostConstruct 어노테이션인데 이것은 DI 이후에 실행되어져야 할 메소드에 사용하는 어노테이션이다. 

데이터에 대한 CRUD를 할 수 있도록 생성하는 repository는 BookRepository와 BookRepositoryImpl 두개의 클래스를 작성한다.

 

BookRepository.java

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
package com.joyhong.repository;
 
 
 
public interface BookRepository {
    
    /**
     * 책 정보를 저장
     * @param book
     */
    void createBook(Book book);
    
    /**
     * 책정보를 읽기
     * @param seq
     * @return
     */
    Book getBook(Long seq);
    
    /**
     * 모든 책 정보를 읽기
     * @return
     */
    HashMap<Long, Book> getBookAll();
    
    /**
     * 책 정보를 업데이트
     * @param book
     * @return
     */
    Long updateBook(Book book);
    
    /**
     * 책 정보를 삭제
     * @param book
     */
    void deleteBook(Long seq);
 
    /**
     * 마지막 책번호를 반환
     * @return
     */
    Long getLastID();
}
 
 

 

BookRepositoryImpl.java

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
64
65
66
67
68
69
70
71
package com.joyhong.repository;
 
 
import javax.annotation.PostConstruct;
 
import org.springframework.stereotype.Repository;
 
 
 
@Repository
public class BookRepositoryImpl implements BookRepository{
 
    private HashMap<Long, Book> bookMap;
    private Long id = 0L;
    
    @PostConstruct
    public void init() {
        // TODO Auto-generated method stub
        Logger.getLogger("com.joyhong.repository.BookRepositoryImpl").log(Level.INFO, "Test for repository data");
        bookMap = new HashMap<Long, Book>();
        for(int i=0; i<10; i++) {
            id++;
            Book book = new Book();
            book.setSeq(id);
            book.setTitle("책 제목 " + id);
            book.setCreator("책 저자 " + id);
            book.setPublisher("출판사 " + id);
            book.setPublishedYear(2010);
            
            bookMap.put(id, book);
        }
    }
    
    @Override
    public void createBook(Book book) {
        book.setSeq(++id);
        bookMap.put(id, book);
    }
    
    @Override
    public Book getBook(Long seq) {
        return bookMap.get(seq);
    }
 
    @Override
    public HashMap<Long, Book> getBookAll() {
        return bookMap;
    }
 
    @Override
    public Long updateBook(Book book) {
        Long id = book.getSeq();
        bookMap.put(id, book);
        return id;
    }
 
    @Override
    public void deleteBook(Long seq) {
        bookMap.remove(seq);
    }
 
    @Override
    public Long getLastID() {
        return id;
    }
}
 
 

repository 부분을 생성하고 다음으로는 service 부분을 생성한다.

서비스도 마찬가지로 BookService 인터페이스와 그 구현체인 BookServiceImpl  클래스 두개를 생성한다.

여기서 생성하는 BookService 인터페이스는 컨트롤러에서 사용이 되어진다.

 

BookService.java

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
package com.joyhong.service;
 
 
 
public interface BookService {
 
    /**
     * 책 정보를 입력
     * @param book
     */
    void createBook(Book book);
    
    /**
     * 책번호로 책 정보를 반환
     * @param seq
     * @return
     */
    Book readBook(Long seq);
    
    /**
     * 모든 책 정보를 반환
     * @return
     */
    HashMap<Long, Book> readBookAll();
    
    /**
     * 책정보를 업데이트
     * @param book
     * @return
     */
    Long updateBook(Book book);
    
    /**
     * 책 정보를 삭제
     * @param book
     */
    void deleteBook(Long seq);
}
 
 

 

BookServiceImpl.java

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 com.joyhong.service;
 
 
import org.springframework.stereotype.Service;
 
import com.joyhong.repository.BookRepository;
 
@Service
public class BookServiceImpl implements BookService {
 
    @Autowired
    private BookRepository bookRepo;
    
    @Override
    public void createBook(Book book) {
        bookRepo.createBook(book);
    }
    
    @Override
    public Book readBook(Long seq) {
        return bookRepo.getBook(seq);
    }
 
    @Override
    public HashMap<Long, Book> readBookAll() {
        return bookRepo.getBookAll();
    }
 
    @Override
    public Long updateBook(Book book) {
        return bookRepo.updateBook(book);
    }
 
    @Override
    public void deleteBook(Long seq) {
        bookRepo.deleteBook(seq);
    }
}
 
 

 

그럼 이제 마지막으로 컨트롤러 작성해야 한다.

컨트롤러에서는 사용자가 요청하는 URL에 맞는 기능을 처리할 업무로직과 연결시켜 주는 역할을 하게 된다.

여기에서는 새롭게 BookController 를 생성한다.

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
package com.joyhong.controller.book;
 
 
 
import com.joyhong.service.BookService;
 
@RestController
public class BookController {
 
    @Autowired
    private BookService bookService;
    
    @RequestMapping(value = "/book/info", method = RequestMethod.GET)
    public Book info(Long id) {
        return bookService.readBook(id);
    }
    
    @RequestMapping(value = "/book/all", method = RequestMethod.GET)
    public HashMap<Long, Book> all() {
        return bookService.readBookAll();
    }
    
    @RequestMapping(value = "/book/create", method = RequestMethod.GET)
    public void create() {
        bookService.createBook(new Book());
    }
    
    @RequestMapping(value = "/book/update", method = RequestMethod.GET)
    public Long update(Book book) {
        return bookService.updateBook(book);
    }
    
    @RequestMapping(value = "/book/delete", method = RequestMethod.GET)
    public void delete(Long id) {
        bookService.deleteBook(id);
    }
    
}
 
 
 
 

여기까지 모든 코드를 다 작성하였다. 모든 코드마다 어노테이션이 중요하다. 

만약 에러가 발생하는 상황이 발생하면 오타 혹은 어노테이션 유무를 잘 확인해야 할 것이다.

 

그럼 잘 구동되는지 확인해보기 위해 

http://localhost:8080/home/book/all

를 확인하면 자바 컬렉션이 JSON으로 자동으로 변경되어 나오는 것을 볼 수 있다.

다음으로는 http://localhost:8080/home/book/info?id=2 를 통해 2번 책 하나에 대한 정보를 확인해 볼 수 있다.

마지막으로 http://localhost:8080/home/book/delete?id=2 를 통해 2번 책 정보를 삭제할 수 도 있다.

 

 

최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/11   »
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
글 보관함