728x90
반응형
SMALL

Spring MVC에서의 예외 처리 기법에 대해서 설명해주세요.

Spring MVC에서 예외 처리를 위한 여러 가지 기법이 있습니다.

1. @ExceptionHandler: 컨트롤러 클래스 내에서 발생한 예외를 처리할 메서드를 지정하는 데 사용되는 애노테이션입니다. 이 메서드는 예외 클래스를 인수로 받아 처리하며, 동일한 컨트롤러 클래스 내에서 발생한 해당 유형의 예외를 처리할 수 있습니다.

javaCopy code
@Controller
public class MyController {
    @RequestMapping("/somepage")
    public String somepage() {
        //...
        throw new CustomException("Some error occurred");
    }

    @ExceptionHandler(CustomException.class)
    public ModelAndView handleCustomException(CustomException ex) {
        ModelAndView model = new ModelAndView("error");
        model.addObject("exception", ex);
        return model;
    }
}

2. @ControllerAdvice: 전역 예외 처리를 위한 클래스에 사용되는 애노테이션입니다. 이를 사용하면 애플리케이션 전체에서 발생하는 예외를 처리하는 별도의 클래스를 정의할 수 있습니다. 이 클래스 내부에서는 @ExceptionHandler 애노테이션을 사용하여 처리할 예외 유형을 지정할 수 있습니다.

javaCopy code
@ControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(CustomException.class)
    public ModelAndView handleCustomException(CustomException ex) {
        ModelAndView model = new ModelAndView("error");
        model.addObject("exception", ex);
        return model;
    }
}

3. 예외 처리용 핸들러 메서드: 컨트롤러에서 발생한 예외를 처리하는 메서드를 지정하는 데 사용됩니다. Spring 3.2 이전 버전에서 사용되었던 예외 처리 방식으로, SimpleMappingExceptionResolver 또는 HandlerExceptionResolver 인터페이스를 구현하여 예외 처리 클래스를 정의할 수 있습니다.

javaCopy code
public class CustomExceptionResolver extends SimpleMappingExceptionResolver {
    @Override
    protected ModelAndView doResolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        if (ex instanceof CustomException) {
            // 처리할 예외 유형에 따른 처리 로직
        }
        return super.doResolveException(request, response, handler, ex);
    }
}

4. ErrorViewResolver 인터페이스 구현: Spring Boot에서 사용 가능한 예외 처리 방식으로 예외가 발생할 때 호출되며, 반환되는 ModelAndView 객체를 통해 에러 페이지를 지정할 수 있습니다.

javaCopy code
@Component
public class CustomErrorViewResolver implements ErrorViewResolver {
    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        ModelAndView modelAndView = new ModelAndView("error");
        modelAndView.addObject("status", status.value());
        modelAndView.addAllObjects(model);
        return modelAndView;
    }
}

이러한 기법들을 사용하여 Spring MVC 애플리케이션에서 발생하는 예외를 효과적으로 처리할 수 있습니다. 이렇게 처리된 예외는 사용자 친화적인 에러 메시지를 표시하거나, 로깅을 통해 개발자가 원인을 찾아 수정할 수 있는 정보를 제공하는 등의 방식으로 처리됩니다.

여기에 추가로, 예외 처리 방법을 조합하여 더욱 강력한 예외 처리 전략을 구축할 수도 있습니다. 예를 들어, @ExceptionHandler를 사용하여 컨트롤러별 예외 처리를 구현하고, @ControllerAdvice를 사용하여 전역적인 예외 처리를 수행하는 등의 방법을 사용할 수 있습니다.

예외 처리 구현 시 고려사항

  1. 예외 유형: 예외 유형에 따라 적절한 에러 메시지를 표시하거나, 처리 방식을 달리해야 할 수 있습니다. 예를 들어, 사용자 입력 오류와 시스템 오류는 다른 방식으로 처리되어야 할 수 있습니다.
  2. 에러 페이지: 예외가 발생했을 때 사용자에게 표시할 에러 페이지를 준비하고, 이를 적절한 예외 처리 메서드에서 반환해야 합니다. 에러 페이지는 사용자 친화적이고 이해하기 쉬운 메시지를 제공해야 합니다.
  3. 로깅: 예외 처리 과정에서 로깅을 통해 발생한 예외에 대한 정보를 기록할 수 있습니다. 이를 통해 개발자는 시스템 오류의 원인을 찾고, 이를 수정하는 데 도움을 받을 수 있습니다.
  4. 예외 전파: 예외를 적절한 수준에서 처리하고, 필요한 경우 상위 계층으로 전파할 수 있어야 합니다. 이를 통해 예외 처리의 책임을 명확하게 분리하고, 적절한 수준에서 처리할 수 있습니다.
728x90
반응형
LIST
728x90
반응형
SMALL

DI(Dependency Injection)에 대한 설명과 해당 기술의 장점에 대해 설명해주세요.

의존성 주입은 객체가 다른 객체에 의존하는 경우, 의존하는 객체를 외부에서 생성하여 주입하는 기술입니다. 이를 통해 여러 가지 장점을 얻을 수 있습니다.

의존성 주입이란?

DI는 런타임 시점에 객체 간의 의존 관계를 결정하고, 객체를 동적으로 생성하고 연결하는 데 사용됩니다. 이 접근 방식은 코드의 유연성과 확장성을 향상시키며, 테스트 용이성을 증가시킵니다.

의존성 주입(Dependency Injection, DI)은 객체 지향 프로그래밍에서 객체 간 의존 관계를 외부에서 설정하고 관리하는 기법으로, 클래스 간의 결합도를 낮추고 유연한 구조를 구축할 수 있습니다. 이 기법의 핵심 원칙은 객체가 직접 의존하는 다른 객체를 생성하지 않고, 외부에서 생성된 객체를 주입받아 사용하는 것입니다. 이를 통해 각 객체는 다른 객체와의 관계를 명확히 알지 못하며 인터페이스에만 의존하게 되어, 클래스 간의 결합도를 줄이고 캡슐화와 모듈화를 향상시킬 수 있습니다.

의존성 주입을 구현하는 주요 방법은 다음과 같습니다.

1. 생성자 주입: 객체를 생성할 때 생성자를 통해 의존성을 주입하는 방법입니다. 생성자에 필요한 의존 객체를 인자로 전달하며, 객체가 생성되면서 의존성이 설정됩니다.

javaCopy code
public class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public BurgerChef(BurgerRecipe burgerRecipe) {
        this.burgerRecipe = burgerRecipe;
    }
}

2. 세터 주입: 객체의 세터 메소드를 사용해 의존성을 주입하는 방법입니다. 세터 메소드를 호출하여 필요한 의존 객체를 설정합니다.

javaCopy code
public class BurgerChef {
    private BurgerRecipe burgerRecipe;

    public void setBurgerRecipe(BurgerRecipe burgerRecipe) {
        this.burgerRecipe = burgerRecipe;
    }
}

3. 인터페이스 주입: 인터페이스를 사용하여 의존성을 주입하는 방법입니다. 객체가 인터페이스를 구현하고, 외부에서 주입할 의존 객체를 설정할 수 있는 메소드를 정의합니다.

의존성 주입은 객체 지향 프로그래밍의 핵심 원칙에 부합하며, 많은 프레임워크와 라이브러리에서 활용되고 있습니다. 예를 들어, Java의 대표적인 프레임워크인 Spring에서는 DI를 기반으로 하는 IoC(Inversion of Control) 컨테이너를 제공하여 개발자들이 쉽게 의존성 관리를 할 수 있도록 돕고 있습니다.

DI의 장점

  1. 의존성이 줄어든다. - 의존성 주입을 사용하면 클래스 간의 결합도가 낮아져 변화에 더 유연하게 대응할 수 있습니다. 의존 대상이 변하더라도 구현 자체를 수정할 일이 줄어들게 됩니다.
  2. 재사용성이 높은 코드가 된다. - 의존성 주입을 통해 클래스를 분리하면, 기능이 재사용 가능한 단위로 구분되어 다른 클래스에서도 활용할 수 있습니다.
  3. 테스트하기 좋은 코드가 된다. - 의존성 주입을 사용하면 클래스 간의 의존성이 줄어들어 테스트하기 쉬운 코드가 됩니다. 의존 객체를 쉽게 변경하거나 모의 객체로 대체할 수 있어 테스트에 용이합니다.
  4. 가독성이 높아진다. - 클래스의 기능을 분리함으로써 가독성이 향상됩니다. 기능이 명확하게 구분되어 코드를 이해하기 쉬워집니다.

요약

DI(의존관계 주입)는 객체가 의존하는 또 다른 객체를 외부에서 선언하고 이를 주입받아 사용하는 것입니다. 이를 구현함으로써 얻을 수 있는 장점들을 알아봤습니다. 이러한 기술은 자바와 관련된 서적이나 스프링에 처음 입문할 때 자주 접하게 되는 개념입니다.

 

728x90
반응형
LIST
728x90
반응형
SMALL

REST API란 무엇인가요?

웹 기반 서비스에서 클라이언트와 서버 간의 통신을 쉽게하기 위해 사용되며, HTTP 프로토콜을 기반으로 자원(Resource)에 접근할 수 있는 인터페이스를 제공합니다.

 

프로젝트에 REST API를 사용한 이유가 무엇인가요? 

프로젝트에서 REST API를 사용하는 주요 이유는 다음과 같습니다.
1. 표준화된 인터페이스: REST API는 표준화된 인터페이스를 제공하므로, 개발자들이 쉽게 익힐 수 있고 다양한 플랫폼에서 사용할 수 있습니다.
2. 유지 보수성: REST API의 구성 요소들이 독립적으로 작동하므로, 한 쪽의 변경이 다른 쪽에 영향을 주지 않아 유지 보수가 쉽습니다.
3. 확장성: 클라이언트와 서버가 독립적으로 확장될 수 있어, 시스템의 확장성이 향상됩니다.
4. 간결성과 가독성: REST API는 자원에 대한 명확한 URI와 표준 HTTP 메서드를 사용하여 코드의 간결성과 가독성이 높습니다.

 

제 프로젝트에서 사용한 REST API는 아래와 같습니다.
  1. Ticket.java: 티켓 도메인 모델을 정의한 클래스입니다. 티켓과 관련된 속성과 메서드를 포함하고 있습니다.
  2. TicketRepository.java: 티켓 데이터에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행하는 인터페이스입니다. 이를 통해 데이터베이스와의 상호 작용이 가능합니다.
  3. TicketService.java: 티켓과 관련된 비즈니스 로직을 처리하는 서비스 클래스입니다. TicketRepository를 사용하여 데이터베이스와 상호 작용하고, 티켓 생성, 조회, 수정, 삭제 등의 기능을 제공합니다.
  4. TicketController.java: 클라이언트의 요청을 처리하는 컨트롤러 클래스입니다. 이 클래스에서 REST API를 정의하며, HTTP 메서드와 URI를 사용하여 각 엔드포인트를 구성합니다.
  • 티켓 생성: POST /tickets
  • 티켓 조회 (전체): GET /tickets
  • 티켓 조회 (특정 ID): GET /tickets/{id}
  • 티켓 수정: PUT /tickets/{id}
  • 티켓 삭제: DELETE /tickets/{id}

REST API 특징

가장 큰 특징은 각 요청이 어떤 동작이나 정보를 위한 것인지를 그 요청의 모습 자체로 추론이 가능하다는 것입니다.

 

REST API의 설계 규칙

1. URI는 명사를 사용(리소스명은 동사가 아닌 명사를 사용해야 합니다.)
         - 예) 다음과 같은 동사는 안됨!
               - /updateUser
              - /deleteUser
2.  슬래시( / )로 계층 관계를 표현합니다.
3. URI 마지막 문자로 슬래시 ( / )를 포함하지 않습니다.
4. 밑줄( _ )을 사용하지 않고, 하이픈( - )을 사용합니다.
5. URI는 소문자로만 구성합니다.
6. HTTP 응답 상태 코드를 사용합니다.클라이언트는 해당 요청에 대한 실패, 처리 완료, 잘못된 요청 등에 대한 피드백을 받아야 합니다.
7. 파일확장자는 URI에 포함하지 않습니다. 

 

REST API와 RESTful API의 차이

RESTful API :
REST의 설계 규칙을 잘 지켜서 설계된 API를 RESTful한 API 라고 합니다.
즉, REST의 원리를 잘 따르는 시스템을 RESTful이란 용어로 지칭됩니다.

 

프로젝트에 REST API를 사용한 이유가 무엇인가요?

먼저, REST API를 사용하면 URI, HTTP Method를 통해 구현되어 있기 때문에 자원의 상태를 직관적으로 알 수 있습니다.
또한, 클라이언트와 서버를 명확하게 분리할 수 있기 때문에 적용하게 되었습니다.
각 엔드포인트는 클라이언트로부터 요청을 받아, TicketService를 통해 비즈니스 로직을 처리하고, 응답을 반환합니다. 이렇게 구성된 REST API를 통해 클라이언트는 티켓 관련 작업을 손쉽게 수행할 수 있습니다.

 

REST API 말고 다른 비교할만한 것을 알고 있나요?

GraphQL: 이 프로젝트에서는 GraphQL을 사용하여 티켓 관련 데이터를 처리할 수 있습니다. GraphQL을 사용하면 클라이언트가 필요한 데이터만 요청할 수 있으며, 여러 종류의 리소스를 한 번의 요청으로 가져올 수 있습니다. GraphQL을 적용하려면 기존의 REST 엔드포인트 대신 GraphQL 스키마와 리졸버를 정의해야 합니다.

gRPC: 이 프로젝트에서는 gRPC를 사용하여 티켓 관련 기능을 구현할 수 있습니다. gRPC는 낮은 지연 시간과 높은 처리량을 제공하며, 스트리밍 및 양방향 통신을 지원합니다. gRPC를 적용하려면 기존의 REST 엔드포인트 대신 Protocol Buffers를 사용하여 서비스와 메시지를 정의하고, 클라이언트와 서버 간의 통신을 구현해야 합니다.

REST API와는 다른 접근 방식을 제공하며, 이를 통해 프로젝트의 특성과 요구 사항에 따라 적합한 솔루션을 선택할 수 있습니다.

728x90
반응형
LIST

+ Recent posts