반응형

개발 공부를 하게 되면서 가장 당황스러운 게 용어와 개념입니다.

java로 개발을 시작하게 되면 생소한 개념들이 아주 많이 있습니다.

DAO, DTO, Repository, Entity 와 같은 개념들, MVC 패턴에 관련된 내용들에 대해서 알아보겠습니다.

mvc

기본적인 구조는 클라이언트에서 데이터를 요청하면

Controller -> Service -> Repository -> Entity -> DB

DB -> Repository -> Service -> Controller -> Browser(클라이언트)

이런 식으로 뿌려주게 됩니다.

 

DTO(데이터 전송 개체)

 - DTO(데이터 전송 개체) 패턴이 일반적으로 애플리케이션의 여러 부분 간의 데이터 전송을 단순화하는 데 사용됩니다.

 

다양한 세부정보가 포함된 User 클래스가 있다고 가정해 보면


public class User {
    private String username;
    private String email;
    private int age;

    // Constructors, getters, setters...
}

 

이제 컨트롤러에서 서비스와 같이 다양한 레이어나 모듈 간에 사용자 데이터를 전송하려고 합니다.

전체 User 개체를 전달하는 대신 DTO를 만들 수 있습니다.

 

public class UserDTO {
    private String username;
    private String email;

    // Constructors, getters, setters...

    // Additional fields or logic specific to the transfer can be added.
}

 

UserDTO를 이용하면 필요한 데이터만 전송할 수 있어 정보의 과다 노출을 방지하고 보안을 강화할 수 있습니다. 이 접근 방식은 서비스 간 데이터 전송 최적화가 중요한 마이크로서비스 아키텍처에 특히 유용합니다

 

Controller

Java의 MVC(Model-View-Controller) 아키텍처에서 컨트롤러는 사용자 입력을 처리하고 그에 따라 모델(데이터)과 뷰(사용자 인터페이스)를 업데이트하는 역할을 담당하는 중요한 구성 요소입니다. 이는 사용자와 애플리케이션 논리 사이의 중개자 역할을 합니다.

컨트롤러의 역할을 간략하게 설명하면 다음과 같습니다.

  1. 사용자 입력 처리: 컨트롤러는 일반적으로 뷰(UI) 또는 외부 이벤트와의 상호 작용을 통해 사용자 입력을 받습니다.
  2. 모델 업데이트: 입력을 처리하고 모델(데이터 또는 비즈니스 로직)과 상호 작용하며 그에 따라 모델 상태를 업데이트합니다.
  3. 뷰 업데이트: 모델을 수정한 후 컨트롤러는 변경 사항을 반영하도록 뷰를 업데이트하여 사용자 인터페이스가 기본 데이터와 동기화된 상태를 유지하도록 합니다.
  4. 애플리케이션 흐름 유지: 컨트롤러는 다양한 사용자 작업에 응답하는 방법을 결정하고 모델과 뷰 간의 상호 작용을 조정하여 애플리케이션의 흐름을 관리합니다.

Java에서 Spring MVC와 같은 프레임워크는 MVC 패턴의 강력한 구현을 제공합니다. 여기서 컨트롤러는 사용자 상호 작용, 데이터 조작 및 UI 업데이트의 전체 프로세스를 관리하는 데 중심적인 역할을 합니다

 

Java Spring MVC 애플리케이션에서 컨트롤러는 사용자 요청을 처리하고 적절한 응답을 반환하는 역할을 담당합니다. 다음은 Spring MVC 컨트롤러의 간단한 예입니다.

기본 Spring MVC 프로젝트가 설정되어 있다고 가정하면 컨트롤러의 예는 다음과 같습니다.

 

import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;

@Controller
public class HelloController {

    @GetMapping("/hello")
    public String hello(Model model) {
        // Add data to the model
        model.addAttribute("message", "Hello, Spring MVC!");

        // Return the view name (HTML page to render)
        return "hello";
    }
}

 

  • @Controller 주석은 이 클래스를 컨트롤러로 선언합니다.
  • @GetMapping("/hello") 주석은 "/hello" 엔드포인트에서 GET 요청을 처리하도록 메서드를 매핑합니다.
  • 'Model' 매개변수는 뷰에 표시할 데이터를 추가하는 데 사용됩니다.

src/main/resources/templates 디렉터리에 간단한 HTML 파일(예: hello.html)을 만듭니다.

 

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Hello Page</title>
</head>
<body>
    <h1 th:text="${message}"></h1>
</body>
</html>

 

이 Thymeleaf 템플릿은 컨트롤러의 메시지를 표시합니다.

프로젝트(일반적으로 application.properties 파일)에서 Thymeleaf를 구성하는 것을 잊지 말아야 합니다.

 


spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html

 

이제 http://localhost:8080/hello에 액세스하면 컨트롤러 메서드가 호출되고 "Hello, Spring MVC!" 메시지가 표시됩니다.

 

Service

- Java MVC(Service)에서 "Service"는 비즈니스 로직을 처리하고 데이터를 조작하는 레이어를 의미합니다. Service 레이어는 Controller와 Repository (데이터 액세스 레이어) 간의 중간 매개체 역할을 합니다. 주로 다음과 같은 목적으로 사용됩니다:

  1. 비즈니스 로직 분리: 비즈니스 로직은 Service 레이어에서 처리되며, 이를 통해 Controller는 요청을 수신하고 결과를 반환하는 역할에 집중할 수 있습니다.
  2. 재사용성 및 모듈화: 비즈니스 로직이 Service에 캡슐화되면 여러 Controller에서 동일한 로직을 재사용할 수 있으며, 변경이 필요한 경우 Service 레이어만 수정하면 됩니다.

간단한 예시를 통해 설명하겠습니다. 다음은 사용자 관리를 다루는 예시입니다.

 

@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User getUserById(Long userId) {
        return userRepository.findById(userId).orElse(null);
    }

    public User createUser(User user) {
        // 비즈니스 로직 처리
        return userRepository.save(user);
    }

    public void deleteUser(Long userId) {
        // 비즈니스 로직 처리
        userRepository.deleteById(userId);
    }
}

 

위 코드에서 UserService는 사용자와 관련된 비즈니스 로직을 다루는 Service입니다. Controller에서는 사용자 요청을 받고, 해당 요청에 대한 처리를 UserService에 위임합니다.

 

Repository

- Java MVC(Model-View-Controller)의 맥락에서 저장소는 종종 Spring Data와 연결됩니다. Spring Data는 데이터 액세스 계층을 구현하는 데 필요한 상용구 코드를 크게 줄이는 저장소 추상화를 제공합니다.

Spring Data에서 저장소는 일반적으로 특정 데이터 모델과 상호 작용하기 위한 방법을 정의하는 데이터 액세스 인터페이스를 나타냅니다. 필수는 아니지만 @Repository 주석은 일반적으로 클래스가 저장소 역할을 함을 나타내는 데 사용됩니다.

다음은 Spring Data JPA를 사용하는 간단한 예입니다.

 

import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long> {
    // Custom queries or methods can be declared here
    User findByUsername(String username);
}

 

이 예에서 UserRepository User 엔터티에 대한 표준 CRUD 작업을 제공하는 Spring Data 인터페이스인 JpaRepository를 확장합니다. 사용자 정의 쿼리 또는 메서드는 인터페이스에서 선언될 수 있으며 Spring Data는 자동으로 구현을 생성합니다.

 

Entity

Java MVC(Model-View-Controller)의 맥락에서 엔티티는 종종 데이터베이스 테이블과 관련된 영구 데이터 개체를 나타냅니다. JPA(Java Persistence API) 및 Spring Data JPA와 같은 프레임워크에서 엔티티는 저장할 데이터의 구조를 정의하는 주석이 달린 Java 클래스입니다.

다음은 JPA 엔티티의 간단한 예입니다.

 

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Customer {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String firstName;
    private String lastName;

    // Getters and setters
}

 

이 예에서 Customer 클래스에는 @Entity 주석이 추가되어 JPA 엔터티임을 나타냅니다. @Id 주석은 기본 키를 지정하고 @GeneratedValue는 고유 ID 생성 전략을 지정합니다.

엔터티는 종종 데이터베이스의 테이블을 나타내며 JPA는 Java 개체와 데이터베이스 테이블 간의 매핑을 관리합니다.

 

MVC 패턴

  1. Model (모델):
    • 역할: 데이터와 비즈니스 로직을 다룸.
    • 예시: 주문 시스템에서 주문 정보를 표현하는 클래스.
  2. View (뷰):
    • 역할: 사용자에게 정보를 보여주는 부분.
    • 예시: 주문 시스템에서 주문 정보를 화면에 표시하는 웹 페이지.
  3. Controller (컨트롤러):
    • 역할: 사용자 입력을 처리하고 모델과 뷰를 연결.
    • 예시: 주문 시스템에서 주문 생성 요청을 받아 모델에 전달하고, 그 결과를 뷰에 반영.
  4. 도메인 객체:
    • 역할: 실제 비즈니스 도메인을 표현하고 해당 도메인의 규칙을 적용.
    • 예시: 주문 시스템에서 상품, 고객, 주문 등의 도메인 객체.

 

Java MVC 패턴에서 주로 사용되는 어노테이션은 다음과 같습니다:

  1. @Controller:
    • 설명: 해당 클래스를 컨트롤러로 지정합니다.
    • 예시: @Controller 어노테이션이 붙은 클래스는 사용자의 입력을 처리하고 비즈니스 로직을 수행합니다.
  2. @RequestMapping:
    • 설명: 메서드 또는 클래스에 어떤 요청이나 URL과 매핑되는지 지정합니다.
    • 예시: @RequestMapping("/users")는 "/users" 경로로 들어오는 요청을 처리하는 메서드를 지정합니다.
  3. @ModelAttribute:
    • 설명: 메서드 매개변수에 사용되며, 해당 메서드가 리턴하는 데이터를 모델에 추가합니다.
    • 예시: @ModelAttribute("user")는 "user"라는 이름으로 모델에 데이터를 추가합니다.
  4. @ResponseBody:
    • 설명: 메서드가 직접 HTTP 응답의 본문을 작성하도록 지정합니다.
    • 예시: @ResponseBody 어노테이션이 붙은 메서드는 데이터를 직접 응답 본문에 씁니다.
  5. @PathVariable:
    • 설명: URL 패턴에서 값을 추출하여 메서드 매개변수에 전달합니다.
    • 예시: @RequestMapping("/users/{id}")와 @PathVariable("id")를 사용하여 경로에서 사용자 ID를 추출합니다.
  6. @RequestParam:
    • 설명: 요청 매개변수를 메서드 매개변수에 바인딩합니다.
    • 예시: @RequestParam("name") String name은 "name" 매개변수를 받아와서 name 변수에 할당합니다.

 

MVC패턴과 gRPC 연결 방법 예시

의존성 추가:

  • build.gradle 또는 pom.xml에 gRPC 관련 의존성을 추가합니다.
  • 예시 (Gradle):

implementation 'io.grpc:grpc-netty:1.43.0'
implementation 'io.grpc:grpc-protobuf:1.43.0'
implementation 'io.grpc:grpc-stub:1.43.0'

 

gRPC 서비스 정의:

  • gRPC 서비스를 정의하고 프로토콜 버퍼를 사용하여 통신 메시지를 정의합니다.
  • 예시:

syntax = "proto3";

service MyService {
  rpc MyMethod (MyRequest) returns (MyResponse);
}

message MyRequest {
  // 필요한 필드 정의
}

message MyResponse {
  // 필요한 필드 정의
}

 

Controller에 gRPC 클라이언트 통합:

  • Spring MVC 컨트롤러에서 gRPC 클라이언트를 주입하고, 필요한 메서드를 호출합니다.
  • 예시:


@Autowired
private MyServiceGrpc.MyServiceBlockingStub myService;

@RequestMapping("/my-endpoint")
public ResponseEntity<String> myEndpoint() {
    MyResponse response = myService.myMethod(MyRequest.newBuilder().build());
    // gRPC 응답을 처리하고 적절한 응답을 반환
    return ResponseEntity.ok(response.getResult());
}

 

서버 구현:

  • gRPC 서버를 구현하고 필요한 비즈니스 로직을 처리합니다.
  • 예시:

public class MyServiceImpl extends MyServiceGrpc.MyServiceImplBase {
  @Override
  public void myMethod(MyRequest request, StreamObserver<MyResponse> responseObserver) {
    // 비즈니스 로직 처리
    MyResponse response = MyResponse.newBuilder().setResult("Hello, gRPC!").build();
    responseObserver.onNext(response);
    responseObserver.onCompleted();
  }
}
반응형
복사했습니다!