본문 바로가기

SPRING/SPRING BOOT V3.0.6 REFERENCE

[Spring Boot Reference V3.0.6] Spring Boot Web

반응형

Spring Boot는 웹 애플리케이션 개발에 적합합니다. 포함된 Tomcat, Jetty, Undertow 또는 Netty를 사용하여 독립형 HTTP 서버를 만들 수 있습니다. 대부분의 웹 애플리케이션은 spring-boot-starter-web모듈을 사용하여 신속하게 시작하고 실행합니다. 모듈을 사용하여 반응형 웹 애플리케이션을 빌드하도록 선택할 수도 있습니다 spring-boot-starter-webflux.

아직 Spring Boot 웹 애플리케이션을 개발하지 않은 경우 "Hello World!" 시작하기 섹션 의 예 .

1. 서블릿 웹 애플리케이션

서블릿 기반 웹 애플리케이션을 구축하려는 경우 Spring MVC 또는 Jersey에 대한 Spring Boot의 자동 구성을 활용할 수 있습니다.

1.1. "스프링 웹 MVC 프레임워크"

Spring Web MVC 프레임워크 ("Spring MVC"라고도 함)는 풍부한 "모델 뷰 컨트롤러" 웹 프레임워크입니다. @ControllerSpring MVC를 사용하면 들어오는 HTTP 요청을 처리하기 위해 특별한 빈 을 만들 수 있습니다 @RestController. 컨트롤러의 메서드는 @RequestMapping주석을 사용하여 HTTP에 매핑됩니다.

다음 코드는 @RestControllerJSON 데이터를 제공하는 일반적인 코드를 보여줍니다.

@RestController
@RequestMapping("/users")
public class MyRestController {

    private final UserRepository userRepository;

    private final CustomerRepository customerRepository;

    public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
        this.userRepository = userRepository;
        this.customerRepository = customerRepository;
    }

    @GetMapping("/{userId}")
    public User getUser(@PathVariable Long userId) {
        return this.userRepository.findById(userId).get();
    }

    @GetMapping("/{userId}/customers")
    public List<Customer> getUserCustomers(@PathVariable Long userId) {
        return this.userRepository.findById(userId).map(this.customerRepository::findByUser).get();
    }

    @DeleteMapping("/{userId}")
    public void deleteUser(@PathVariable Long userId) {
        this.userRepository.deleteById(userId);
    }

}
 

기능 변형인 "WebMvc.fn"은 다음 예와 같이 라우팅 구성을 요청의 실제 처리와 분리합니다.

@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {

    private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);

    @Bean
    public RouterFunction<ServerResponse> routerFunction(MyUserHandler userHandler) {
        return route()
                .GET("/{user}", ACCEPT_JSON, userHandler::getUser)
                .GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
                .DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
                .build();
    }

}
 
@Component
public class MyUserHandler {

    public ServerResponse getUser(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }

    public ServerResponse getUserCustomers(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }

    public ServerResponse deleteUser(ServerRequest request) {
        ...
        return ServerResponse.ok().build();
    }

}
 

Spring MVC는 핵심 Spring Framework의 일부이며 자세한 정보는 참조 문서 에서 확인할 수 있습니다 . spring.io/guides 에서 사용할 수 있는 Spring MVC를 다루는 여러 가이드도 있습니다 .

  RouterFunction라우터의 정의를 모듈화하기 위해 원하는 만큼 빈을 정의할 수 있습니다 . 우선순위를 적용해야 하는 경우 콩을 주문할 수 있습니다.

1.1.1. Spring MVC 자동 구성

Spring Boot는 대부분의 애플리케이션에서 잘 작동하는 Spring MVC에 대한 자동 구성을 제공합니다.

자동 구성은 Spring의 기본값 위에 다음 기능을 추가합니다.

이러한 Spring Boot MVC 사용자 지정을 유지하고 더 많은 MVC 사용자 지정 (인터셉터, 포맷터, 뷰 컨트롤러 및 기타 기능 @Configuration) WebMvcConfigurer을 만들고 싶다면 @EnableWebMvc.

RequestMappingHandlerMapping, RequestMappingHandlerAdapter또는 의 사용자 지정 인스턴스를 제공 ExceptionHandlerExceptionResolver하고 Spring Boot MVC 사용자 지정을 계속 유지하려는 경우 유형의 bean을 선언 WebMvcRegistrations하고 해당 구성 요소의 사용자 지정 인스턴스를 제공하는 데 사용할 수 있습니다.

Spring MVC를 완전히 제어하려면 @Configuration로 주석을 추가하거나 의 Javadoc에 설명된 대로 주석을 @EnableWebMvc추가 할 수 있습니다 .@ConfigurationDelegatingWebMvcConfiguration@EnableWebMvc

 
Spring MVC는 또는 파일 ConversionService에서 값을 변환하는 데 사용되는 것과 다른 것을 사용합니다 .  ,  변환기를 사용할 수 없으며 that  주석이 무시됩니다.application.propertiesapplication.yamlPeriodDurationDataSize@DurationUnit@DataSizeUnit
Spring MVC에서 사용하는 것을 커스터마이즈하고 싶다면 빈에 메서드 ConversionService를 제공하면 된다 . 이 메서드에서 원하는 변환기를 등록하거나 에서 사용할 수 있는 정적 메서드에 위임할 수 있습니다 .WebMvcConfigureraddFormattersApplicationConversionService

1.1.2. HttpMessage 변환기

Spring MVC는 HttpMessageConverter인터페이스를 사용하여 HTTP 요청 및 응답을 변환합니다. 합리적인 기본값이 기본적으로 포함되어 있습니다. 예를 들어 개체는 JSON(Jackson 라이브러리 사용) 또는 XML(사용 가능한 경우 Jackson XML 확장 사용 또는 Jackson XML 확장을 사용할 수 없는 경우 JAXB 사용)로 자동 변환될 수 있습니다. 기본적으로 문자열은 UTF-8.

HttpMessageConverters변환기를 추가하거나 사용자 지정해야 하는 경우 다음 목록과 같이 Spring Boot의 클래스를 사용할 수 있습니다 .

@Configuration(proxyBeanMethods = false)
public class MyHttpMessageConvertersConfiguration {

    @Bean
    public HttpMessageConverters customConverters() {
        HttpMessageConverter<?> additional = new AdditionalHttpMessageConverter();
        HttpMessageConverter<?> another = new AnotherHttpMessageConverter();
        return new HttpMessageConverters(additional, another);
    }

}
 

HttpMessageConverter컨텍스트에 있는 모든 Bean이 변환기 목록에 추가됩니다. 동일한 방식으로 기본 변환기를 재정의할 수도 있습니다.

1.1.3. 메시지 코드 리졸버

Spring MVC에는 바인딩 오류에서 오류 메시지를 렌더링하기 위한 오류 코드를 생성하는 전략이 있습니다 MessageCodesResolver. 또는 spring.mvc.message-codes-resolver-format속성 을 설정하면 Spring Boot가 하나를 생성합니다( 의 열거 참조 ).PREFIX_ERROR_CODEPOSTFIX_ERROR_CODEDefaultMessageCodesResolver.Format

1.1.4. 정적 콘텐츠

기본적으로 Spring Boot는 클래스 경로의 /static(또는 /public또는 /resources또는 /META-INF/resources) 디렉토리 또는 ServletContext. Spring MVC에서 사용하므로 자신의 메서드를 추가 하고 재정의하여 ResourceHttpRequestHandler해당 동작을 수정할 수 있습니다 .WebMvcConfigureraddResourceHandlers

독립 실행형 웹 애플리케이션에서는 컨테이너의 기본 서블릿이 활성화되지 않습니다. 속성을 사용하여 활성화할 수 있습니다 server.servlet.register-default-servlet.

ServletContext기본 서블릿은 대체 역할을 하여 Spring이 처리하지 않기로 결정한 경우 루트에서 콘텐츠를 제공합니다 . Spring은 항상 DispatcherServlet.

기본적으로 리소스는 에 매핑되지만 /**속성을 사용하여 조정할 수 있습니다 spring.mvc.static-path-pattern. 예를 들어 /resources/**다음과 같이 모든 리소스를 재배치할 수 있습니다.

spring.mvc.static-path-pattern=/resources/**
 

속성을 사용하여 정적 리소스 위치를 사용자 지정할 수도 있습니다 spring.web.resources.static-locations(기본값을 디렉터리 위치 목록으로 바꿈). 루트 서블릿 컨텍스트 경로도 "/"자동으로 위치로 추가됩니다.

앞에서 언급한 "표준" 정적 리소스 위치 외에도 Webjars 콘텐츠 에 대한 특별한 경우가 있습니다 . 기본적으로 경로가 있는 리소스는 /webjars/**Webjars 형식으로 패키징된 경우 jar 파일에서 제공됩니다. 경로는 spring.mvc.webjars-path-pattern속성으로 사용자 정의할 수 있습니다.

  src/main/webapp애플리케이션이 jar로 패키징된 경우 디렉토리를 사용하지 마십시오 . 이 디렉토리는 공통 표준이지만 war 패키징에서만 작동하며 jar 를 생성하는 경우 대부분의 빌드 도구에서 자동으로 무시됩니다.

Spring Boot는 또한 Spring MVC에서 제공하는 고급 리소스 처리 기능을 지원하여 캐시 버스팅 정적 리소스와 같은 사용 사례를 허용하거나 Webjars에 대해 버전에 구애받지 않는 URL을 사용할 수 있습니다.

Webjars에 대해 버전에 구애받지 않는 URL을 사용하려면 webjars-locator-core종속성을 추가하십시오. 그런 다음 Webjar를 선언하십시오. 예를 들어 jQuery를 사용하여 Webjar 버전  "/webjars/jquery/jquery.min.js"결과를 추가합니다."/webjars/jquery/x.y.z/jquery.min.js"x.y.z

  JBoss를 사용하는 webjars-locator-jboss-vfs경우 webjars-locator-core. 그렇지 않으면 모든 Webjar가 404.

캐시 무효화를 사용하기 위해 다음 구성은 <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>URL에 와 같은 콘텐츠 해시를 효과적으로 추가하여 모든 정적 리소스에 대한 캐시 무효화 솔루션을 구성합니다.

spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
 
  ResourceUrlEncodingFilter리소스에 대한 링크는 Thymeleaf 및 FreeMarker용으로 자동 구성된 덕분에 런타임 시 템플릿에 다시 작성됩니다 . JSP를 사용할 때 이 필터를 수동으로 선언해야 합니다. 다른 템플릿 엔진은 현재 자동으로 지원되지 않지만 사용자 지정 템플릿 매크로/도우미 및 ResourceUrlProvider.

예를 들어 JavaScript 모듈 로더를 사용하여 리소스를 동적으로 로드할 때 파일 이름을 바꾸는 것은 옵션이 아닙니다. 그렇기 때문에 다른 전략도 지원되고 결합될 수 있습니다. "고정" 전략은 다음 예와 같이 파일 이름을 변경하지 않고 URL에 정적 버전 문자열을 추가합니다.

spring.web.resources.chain.strategy.content.enabled=true
spring.web.resources.chain.strategy.content.paths=/**
spring.web.resources.chain.strategy.fixed.enabled=true
spring.web.resources.chain.strategy.fixed.paths=/js/lib/
spring.web.resources.chain.strategy.fixed.version=v12
 

이 구성에서 아래에 있는 JavaScript 모듈은 "/js/lib/"고정된 버전 관리 전략( "/v12/js/lib/mymodule.js")을 사용하는 반면 다른 리소스는 여전히 콘텐츠를 사용합니다( <link href="/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css"/>).

지원되는 추가 옵션은 를 참조하십시오 WebProperties.Resources.

 
이 기능은 전용 블로그 게시물 과 Spring Framework의 참조 문서 에 자세히 설명되어 있습니다 .

1.1.5. 환영 페이지

Spring Boot는 정적 및 템플릿 시작 페이지를 모두 지원합니다. index.html먼저 구성된 정적 콘텐츠 위치에서 파일을 찾습니다 . 템플릿 이 없으면 템플릿을 찾습니다 index. 둘 중 하나가 발견되면 자동으로 애플리케이션의 시작 페이지로 사용됩니다.

1.1.6. 맞춤 파비콘

다른 정적 리소스와 마찬가지로 Spring Boot는 favicon.ico구성된 정적 콘텐츠 위치에서 a를 확인합니다. 해당 파일이 있으면 자동으로 애플리케이션의 파비콘으로 사용됩니다.

1.1.7. 경로 일치 및 콘텐츠 협상

Spring MVC는 요청 경로를 보고 애플리케이션에 정의된 매핑(예: @GetMapping컨트롤러 메서드의 주석)과 일치시켜 수신되는 HTTP 요청을 핸들러에 매핑할 수 있습니다.

Spring Boot는 기본적으로 접미사 패턴 일치를 비활성화하도록 선택합니다. 즉, 다음과 같은 요청은 매핑 "GET /projects/spring-boot.json"과 일치하지 않습니다 @GetMapping("/projects/spring-boot"). 이는 Spring MVC 애플리케이션의 모범 사례 로 간주됩니다 . 이 기능은 과거에 적절한 "수락" 요청 헤더를 보내지 않은 HTTP 클라이언트에 주로 유용했습니다. 올바른 콘텐츠 유형을 클라이언트에 보내야 했습니다. 요즘에는 콘텐츠 협상이 훨씬 더 안정적입니다.

적절한 "수락" 요청 헤더를 지속적으로 보내지 않는 HTTP 클라이언트를 처리하는 다른 방법이 있습니다. "GET /projects/spring-boot?format=json"접미사 일치를 사용하는 대신 쿼리 매개변수를 사용하여 다음과 같은 요청이 다음에 매핑되도록 할 수 있습니다 @GetMapping("/projects/spring-boot").

spring.mvc.contentnegotiation.favor-parameter=true
 

또는 다른 매개변수 이름을 사용하려는 경우:

spring.mvc.contentnegotiation.favor-parameter=true
spring.mvc.contentnegotiation.parameter-name=myparam
 

대부분의 표준 미디어 유형은 기본적으로 지원되지만 새 미디어 유형을 정의할 수도 있습니다.

spring.mvc.contentnegotiation.media-types.markdown=text/markdown
 

Spring Framework 5.3에서 Spring MVC는 컨트롤러 핸들러에 대한 요청 경로를 일치시키기 위한 여러 구현 전략을 지원합니다. 이전에는 전략만 지원했지만 AntPathMatcher이제는 PathPatternParser. 이제 Spring Boot는 새 전략을 선택하고 옵트인하는 구성 속성을 제공합니다.

spring.mvc.pathmatch.matching-strategy=path-pattern-parser
 

이 새로운 구현을 고려해야 하는 이유에 대한 자세한 내용은 전용 블로그 게시물 을 참조하십시오 .

  PathPatternParser최적화된 구현이지만 일부 경로 패턴 변형 의 사용을 제한합니다 . DispatcherServlet서블릿 접두사( ) 를 사용하여 접미사 패턴 일치 또는 매핑과 호환되지 않습니다 spring.mvc.servlet.path.

기본적으로 Spring MVC는 요청에 대한 핸들러를 찾을 수 없는 경우 404 Not Found 오류 응답을 보냅니다. 대신 throw 하려면 NoHandlerFoundExceptionconfigprop:spring.mvc.throw-exception-if-no-handler-found를 로 설정합니다 true. 기본적으로 정적 콘텐츠 제공은 매핑되어 있으므로 /**모든 요청에 ​​대한 처리기를 제공합니다.  NoHandlerFoundException발생하려면 정적 콘텐츠 제공을 완전히 비활성화 하는  spring.mvc.static-path-pattern의 보다 구체적인 값으로 설정해야 합니다./resources/**spring.web.resources.add-mappingsfalse

1.1.8. 구성 가능한WebBindingInitializer

Spring MVC는 a를 사용하여 특정 요청에 대해 WebBindingInitializera를 초기화합니다 . WebDataBinder직접 생성하면 ConfigurableWebBindingInitializer @BeanSpring Boot는 이를 사용하도록 Spring MVC를 자동으로 구성합니다.

1.1.9. 템플릿 엔진

REST 웹 서비스뿐만 아니라 Spring MVC를 사용하여 동적 HTML 콘텐츠를 제공할 수도 있습니다. Spring MVC는 Thymeleaf, FreeMarker 및 JSP를 포함한 다양한 템플릿 기술을 지원합니다. 또한 다른 많은 템플릿 엔진에는 자체 Spring MVC 통합이 포함되어 있습니다.

Spring Boot에는 다음 템플릿 엔진에 대한 자동 구성 지원이 포함되어 있습니다.

  가능하면 JSP를 피해야 합니다. 포함된 서블릿 컨테이너와 함께 사용할 때 몇 가지 알려진 제한 사항이 있습니다 .

이러한 템플릿 엔진 중 하나를 기본 구성으로 사용하면 템플릿이 에서 자동으로 선택됩니다 src/main/resources/templates.

  애플리케이션을 실행하는 방법에 따라 IDE에서 클래스 경로를 다르게 주문할 수 있습니다. 기본 메서드에서 IDE에서 애플리케이션을 실행하면 Maven 또는 Gradle을 사용하거나 패키지된 jar에서 애플리케이션을 실행할 때와 순서가 다릅니다. 이로 인해 Spring Boot가 예상 템플릿을 찾지 못할 수 있습니다. 이 문제가 있는 경우 IDE에서 클래스 경로를 재정렬하여 모듈의 클래스와 리소스를 먼저 배치할 수 있습니다.

1.1.10. 오류 처리

기본적으로 Spring Boot는 /error모든 오류를 합리적으로 처리하는 매핑을 제공하며 서블릿 컨테이너에 "글로벌" 오류 페이지로 등록됩니다. 머신 클라이언트의 경우 오류 세부 정보, HTTP 상태 및 예외 메시지가 포함된 JSON 응답을 생성합니다. 브라우저 클라이언트의 경우 동일한 데이터를 HTML 형식으로 렌더링하는 "whitelabel" 오류 보기가 있습니다(사용자 정의하려면 로 View확인되는 를 추가하십시오 error).

server.error기본 오류 처리 동작을 사용자 지정하려는 경우 설정할 수 있는 여러 속성이 있습니다 . 부록의 "서버 속성" 섹션을 참조하십시오 .

기본 동작을 완전히 대체하려면 해당 유형의 Bean 정의를 구현 및 등록하거나 기존 메커니즘을 사용하지만 내용을 대체하는 ErrorController유형의 Bean을 추가 할 수 있습니다 .ErrorAttributes

   BasicErrorController사용자 지정의 기본 클래스로 사용할 수 있습니다 ErrorController. 이는 새 콘텐츠 유형에 대한 처리기를 추가하려는 경우에 특히 유용합니다(기본값은 text/html구체적으로 처리하고 다른 모든 것에 대한 폴백을 제공하는 것임). 그렇게 하려면 확장하고 속성이 있는 BasicErrorControllera를 사용하여 공용 메소드를 추가하고 새 유형의 빈을 작성하십시오. @RequestMappingproduces

Spring Framework 6.0부터는 RFC 7807 문제 세부 정보가 지원됩니다. Spring MVC는 application/problem+json다음과 같은 미디어 유형으로 사용자 정의 오류 메시지를 생성할 수 있습니다.

{
  "type": "https://example.org/problems/unknown-project",
  "title": "Unknown project",
  "status": 404,
  "detail": "No project found for id 'spring-unknown'",
  "instance": "/projects/spring-unknown"
}
 

spring.mvc.problemdetails.enabled이 지원은 로 설정하여 활성화할 수 있습니다 true.

@ControllerAdvice다음 예제와 같이 특정 컨트롤러 및/또는 예외 유형에 대해 반환할 JSON 문서를 사용자 지정하기 위해 주석 이 달린 클래스를 정의할 수도 있습니다 .

@ControllerAdvice(basePackageClasses = SomeController.class)
public class MyControllerAdvice extends ResponseEntityExceptionHandler {

    @ResponseBody
    @ExceptionHandler(MyException.class)
    public ResponseEntity<?> handleControllerException(HttpServletRequest request, Throwable ex) {
        HttpStatus status = getStatus(request);
        return new ResponseEntity<>(new MyErrorBody(status.value(), ex.getMessage()), status);
    }

    private HttpStatus getStatus(HttpServletRequest request) {
        Integer code = (Integer) request.getAttribute(RequestDispatcher.ERROR_STATUS_CODE);
        HttpStatus status = HttpStatus.resolve(code);
        return (status != null) ? status : HttpStatus.INTERNAL_SERVER_ERROR;
    }

}
 

앞의 예에서 와 MyException동일한 패키지에 정의된 컨트롤러에 의해 가 발생 하면 POJO SomeController의 JSON 표현이 MyErrorBody표현 대신 사용됩니다 ErrorAttributes.

경우에 따라 컨트롤러 수준에서 처리되는 오류가 메트릭 인프라 에 의해 기록되지 않습니다 . 애플리케이션은 처리된 예외를 요청 속성으로 설정하여 이러한 예외가 요청 메트릭과 함께 기록되도록 할 수 있습니다.

@Controller
public class MyController {

    @ExceptionHandler(CustomException.class)
    String handleCustomException(HttpServletRequest request, CustomException ex) {
        request.setAttribute(ErrorAttributes.ERROR_ATTRIBUTE, ex);
        return "errorView";
    }

}
 
사용자 지정 오류 페이지

주어진 상태 코드에 대한 사용자 정의 HTML 오류 페이지를 표시하려는 경우 디렉토리에 파일을 추가할 수 있습니다 /error. 오류 페이지는 정적 HTML(즉, 정적 리소스 디렉터리 아래에 추가됨)이거나 템플릿을 사용하여 작성될 수 있습니다. 파일 이름은 정확한 상태 코드 또는 시리즈 마스크여야 합니다.

예를 들어 404정적 HTML 파일에 매핑하려면 디렉토리 구조가 다음과 같습니다.

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>

FreeMarker 템플릿을 사용하여 모든 오류를 매핑하려면 5xx디렉터리 구조는 다음과 같습니다.

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.ftlh
             +- <other templates>

ErrorViewResolver보다 복잡한 매핑의 경우 다음 예제와 같이 인터페이스를 구현하는 Bean을 추가할 수도 있습니다 .

public class MyErrorViewResolver implements ErrorViewResolver {

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
        // Use the request or status to optionally return a ModelAndView
        if (status == HttpStatus.INSUFFICIENT_STORAGE) {
            // We could add custom model values here
            new ModelAndView("myview");
        }
        return null;
    }

}
 

메소드  . @ExceptionHandler_ @ControllerAdvice그런 ErrorController다음 처리되지 않은 예외를 선택합니다.

Spring MVC 외부의 오류 페이지 매핑

Spring MVC를 사용하지 않는 애플리케이션의 경우 인터페이스 ErrorPageRegistrar를 사용하여 ErrorPages. 이 추상화는 기본 임베디드 서블릿 컨테이너와 직접 작동하며 Spring MVC가 없는 경우에도 작동합니다 DispatcherServlet.

@Configuration(proxyBeanMethods = false)
public class MyErrorPagesConfiguration {

    @Bean
    public ErrorPageRegistrar errorPageRegistrar() {
        return this::registerErrorPages;
    }

    private void registerErrorPages(ErrorPageRegistry registry) {
        registry.addErrorPages(new ErrorPage(HttpStatus.BAD_REQUEST, "/400"));
    }

}
 
  ErrorPagea에 의해 처리되는 경로로 an을 등록하는 경우 Filter(Jersey 및 Wicket과 같은 일부 비 Spring 웹 프레임워크에서 일반적임) 다음 예제와 같이 Filter명시적으로 디스패처로 등록해야 합니다 .ERROR
@Configuration(proxyBeanMethods = false)
public class MyFilterConfiguration {

    @Bean
    public FilterRegistrationBean<MyFilter> myFilter() {
        FilterRegistrationBean<MyFilter> registration = new FilterRegistrationBean<>(new MyFilter());
        // ...
        registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
        return registration;
    }

}
 

기본값에는 디스패처 유형이 FilterRegistrationBean포함되지 않습니다 ERROR.

WAR 배포에서 오류 처리

서블릿 컨테이너에 배포될 때 Spring Boot는 오류 페이지 필터를 사용하여 오류 상태가 있는 요청을 적절한 오류 페이지로 전달합니다. 이는 서블릿 사양이 오류 페이지 등록을 위한 API를 제공하지 않기 때문에 필요합니다. war 파일을 배포하는 컨테이너와 애플리케이션에서 사용하는 기술에 따라 몇 가지 추가 구성이 필요할 수 있습니다.

오류 페이지 필터는 응답이 아직 커밋되지 않은 경우에만 올바른 오류 페이지로 요청을 전달할 수 있습니다. 기본적으로 WebSphere Application Server 8.0 이상은 서블릿의 서비스 메소드가 성공적으로 완료되면 응답을 커미트합니다. com.ibm.ws.webcontainer.invokeFlushAfterService로 설정하여 이 동작을 비활성화해야 합니다 false.

1.1.11. CORS 지원

CORS( Cross-Origin Resource Sharing )는 대부분의 브라우저 에서 구현되는 W3C 사양 으로, IFRAME 또는 JSONP와 같이 덜 안전하고 덜 강력한 접근 방식을 사용하는 대신 어떤 종류의 교차 도메인 요청이 승인되는지 유연한 방식으로 지정할 수 있습니다.

버전 4.2부터 Spring MVC는 CORS를 지원합니다 . Spring Boot 애플리케이션에서 주석 과 함께 컨트롤러 메서드 CORS 구성을 사용하면 @CrossOrigin특정 구성이 필요하지 않습니다. 전역 CORS 구성은 다음 예제와 같이 WebMvcConfigurer사용자 지정 메서드로 빈을 등록하여 정의할 수 있습니다 .addCorsMappings(CorsRegistry)

@Configuration(proxyBeanMethods = false)
public class MyCorsConfiguration {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {

            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/api/**");
            }

        };
    }

}
 

1.2. JAX-RS 및 저지

REST 끝점에 대한 JAX-RS 프로그래밍 모델을 선호하는 경우 Spring MVC 대신 사용 가능한 구현 중 하나를 사용할 수 있습니다. Jersey  Apache CXF는 기본적으로 매우 잘 작동합니다. CXF를 사용하려면 응용 프로그램 컨텍스트에서 Servlet또는를 Filter로 등록해야 합니다 . @BeanJersey에는 일부 기본 Spring 지원 기능이 있으므로 스타터와 함께 Spring Boot에서 자동 구성 지원도 제공합니다.

Jersey를 시작하려면 를 spring-boot-starter-jersey종속성으로 포함하고 다음 예와 같이 모든 엔드포인트를 등록하는 @Bean유형 중 하나가 필요합니다.ResourceConfig

@Component
public class MyJerseyConfig extends ResourceConfig {

    public MyJerseyConfig() {
        register(MyEndpoint.class);
    }

}
 
  실행 가능한 아카이브 스캔에 대한 Jersey의 지원은 다소 제한적입니다. 예를 들어 완전히 실행 가능한 jar 파일 에 있거나 WEB-INF/classes실행 가능한 war 파일을 실행할 때 패키지에서 엔드포인트를 검색할 수 없습니다 . 이러한 제한을 피하기 위해서는 packages메소드를 사용하지 않아야 하며 register앞의 예제와 같이 메소드를 사용하여 엔드포인트를 개별적으로 등록해야 합니다.

고급 사용자 지정을 위해 ResourceConfigCustomizer.

등록된 모든 끝점은 다음 예와 같이 @ComponentsHTTP 리소스 주석(및 기타)과 함께 있어야 합니다.@GET

@Component
@Path("/hello")
public class MyEndpoint {

    @GET
    public String message() {
        return "Hello";
    }

}
 

 EndpointSpring 이므로 @Component수명 주기는 Spring에서 관리하며 @Autowired주석을 사용하여 종속성을 주입하고 @Value주석을 사용하여 외부 구성을 주입할 수 있습니다. 기본적으로 Jersey 서블릿은 에 등록되고 매핑됩니다 /*. @ApplicationPath에 추가하여 매핑을 변경할 수 있습니다 ResourceConfig.

기본적으로 Jersey는 이라는 @Bean유형의 서블릿으로 설정됩니다 . 기본적으로 서블릿은 느리게 초기화되지만 를 설정하여 해당 동작을 사용자 정의할 수 있습니다 . 동일한 이름으로 자신의 빈을 생성하여 해당 빈을 비활성화하거나 재정의할 수 있습니다. 설정을 통해 서블릿 대신 필터를 사용할 수도 있습니다 (이 경우 대체 또는 재정의는 ). 필터에는 가 있으며 로 설정할 수 있습니다 . Jersey를 필터로 사용하는 경우 Jersey에서 가로채지 못하는 모든 요청을 처리할 서블릿이 있어야 합니다. 응용 프로그램에 이러한 서블릿이 포함되어 있지 않은 경우 다음으로 설정하여 기본 서블릿을 활성화할 수 있습니다.ServletRegistrationBeanjerseyServletRegistrationspring.jersey.servlet.load-on-startupspring.jersey.type=filter@BeanjerseyFilterRegistration@Orderspring.jersey.filter.orderserver.servlet.register-default-servlettrue. spring.jersey.init.*속성 맵을 지정하는 데 사용하여 서블릿 및 필터 등록에 초기화 매개변수를 지정할 수 있습니다 .

1.3. 임베디드 서블릿 컨테이너 지원

서블릿 애플리케이션의 경우 Spring Boot에는 임베디드 Tomcat , Jetty  Undertow 서버에 대한 지원이 포함됩니다. 대부분의 개발자는 적절한 "스타터"를 사용하여 완전히 구성된 인스턴스를 얻습니다. 기본적으로 임베디드 서버는 포트에서 HTTP 요청을 수신합니다 8080.

1.3.1. 서블릿, 필터 및 리스너

HttpSessionListener포함된 서블릿 컨테이너를 사용하는 경우 Spring 빈을 사용하거나 서블릿 구성 요소를 스캔하여 서블릿 사양에서 서블릿, 필터 및 모든 리스너(예: )를 등록할 수 있습니다 .

서블릿, 필터 및 리스너를 Spring Bean으로 등록

Spring bean인 모든 Servlet, Filter또는 서블릿 인스턴스는 포함된 컨테이너에 등록됩니다. *Listener이는 구성 중에 값을 참조하려는 경우에 특히 편리할 수 있습니다 application.properties.

기본적으로 컨텍스트에 단일 서블릿만 포함되어 있으면 에 매핑됩니다 /. 여러 서블릿 빈의 경우 빈 이름이 경로 접두사로 사용됩니다. 필터는 에 매핑됩니다 /*.

규칙 기반 매핑이 충분히 유연하지 않은 경우 완전한 제어를 위해 ServletRegistrationBean, FilterRegistrationBean및 ServletListenerRegistrationBean클래스를 사용할 수 있습니다.

일반적으로 필터 빈을 순서 없이 두는 것이 안전합니다. 특정 주문이 필요한 경우 에 주석을 달거나 Filter구현 @Order하도록 해야 합니다 Ordered. Filterbean 메서드에 로 주석을 달아 a의 순서를 구성할 수 없습니다 @Order. Filter추가 @Order또는 구현 으로 클래스를 변경할 수 없는 경우 에 대한 를 정의 하고 메서드를 사용하여 등록 빈의 순서를 설정 Ordered해야 합니다 . 애플리케이션의 문자 인코딩 구성에 위배될 수 있으므로 에서 요청 본문을 읽는 필터를 구성하지 마십시오 . 서블릿 필터가 요청을 래핑하는 경우 보다 작거나 같은 순서로 구성해야 합니다 .FilterRegistrationBeanFiltersetOrder(int)Ordered.HIGHEST_PRECEDENCEOrderedFilter.REQUEST_WRAPPER_FILTER_MAX_ORDER

  Filter애플리케이션에서 모든 항목의 순서를 보려면 web 로깅 그룹 ( logging.level.web=debug)에 대한 디버그 수준 로깅을 활성화합니다. 순서 및 URL 패턴을 포함하여 등록된 필터의 세부 정보는 시작 시 기록됩니다.
  FilterBean은 애플리케이션 수명 주기 초기에 초기화되므로 Bean을 등록할 때 주의하십시오 . Filter다른 bean과 상호 작용하는 a를 등록해야 하는 경우 a를 DelegatingFilterProxyRegistrationBean대신 사용하는 것이 좋습니다.

1.3.2. 서블릿 컨텍스트 초기화

jakarta.servlet.ServletContainerInitializer임베디드 서블릿 컨테이너는 인터페이스 또는 Spring의 인터페이스를 직접 실행하지 않습니다 org.springframework.web.WebApplicationInitializer. 이는 전쟁 중에 실행되도록 설계된 타사 라이브러리가 Spring Boot 애플리케이션을 손상시킬 수 있는 위험을 줄이기 위한 의도적인 설계 결정입니다.

Spring Boot 애플리케이션에서 서블릿 컨텍스트 초기화를 수행해야 하는 경우 인터페이스를 구현하는 Bean을 등록해야 합니다 org.springframework.boot.web.servlet.ServletContextInitializer. 단일 onStartup방법은 에 대한 액세스를 제공하며 ServletContext필요한 경우 기존 에 대한 어댑터로 쉽게 사용할 수 있습니다 WebApplicationInitializer.

서블릿, 필터 및 리스너 검색

내장된 컨테이너를 사용할 때 , , 로 주석이 달린 클래스의 자동 등록은 를 @WebServlet사용 하여 활성화할 수 @WebFilter있습니다 .@WebListener@ServletComponentScan

  @ServletComponentScan컨테이너의 기본 제공 검색 메커니즘이 대신 사용되는 독립 실행형 컨테이너에는 영향을 미치지 않습니다.

1.3.3. ServletWebServerApplicationContext

내부적으로 Spring Boot는 ApplicationContext임베디드 서블릿 컨테이너 지원을 위해 다른 유형을 사용합니다.  단일 빈을 검색하여 자체적으로 부트스트랩하는 ServletWebServerApplicationContext특별한 유형입니다 . 일반적으로 , 또는 는 자동 구성되었습니다.WebApplicationContextServletWebServerFactoryTomcatServletWebServerFactoryJettyServletWebServerFactoryUndertowServletWebServerFactory

  일반적으로 이러한 구현 클래스를 알 필요는 없습니다. 대부분의 응용 프로그램은 자동 구성되며 사용자를 대신하여 적절 ApplicationContext하고 생성됩니다.ServletWebServerFactory

포함된 컨테이너 설정에서 ServletContext애플리케이션 컨텍스트 초기화 중에 발생하는 서버 시작의 일부로 설정됩니다. 이 빈으로 인해 에서 를 ApplicationContext안정적으로 초기화할 수 없습니다 ServletContext. 이 문제를 해결하는 한 가지 방법은 ApplicationContext빈의 종속성으로 주입하고 ServletContext필요할 때만 액세스하는 것입니다. 또 다른 방법은 서버가 시작된 후 콜백을 사용하는 것입니다. ApplicationListener이는 다음과 같이 which 를 수신하는 an 을 사용하여 수행할 수 있습니다 ApplicationStartedEvent.

public class MyDemoBean implements ApplicationListener<ApplicationStartedEvent> {

    private ServletContext servletContext;

    @Override
    public void onApplicationEvent(ApplicationStartedEvent event) {
        ApplicationContext applicationContext = event.getApplicationContext();
        this.servletContext = ((WebApplicationContext) applicationContext).getServletContext();
    }

}
 

1.3.4. 포함된 서블릿 컨테이너 사용자 지정

일반적인 서블릿 컨테이너 설정은 Spring 속성을 사용하여 구성할 수 있습니다 Environment. application.properties일반적으로 또는 파일 에서 속성을 정의합니다 application.yaml.

일반적인 서버 설정은 다음과 같습니다.

  • 네트워크 설정: 들어오는 HTTP 요청에 대한 수신 포트( server.port), 바인드할 인터페이스 주소 server.address등.
  • 세션 설정: 세션 지속 여부( server.servlet.session.persistent), 세션 시간 초과( server.servlet.session.timeout), 세션 데이터 위치( server.servlet.session.store-dir) 및 세션 쿠키 구성( server.servlet.session.cookie.*).
  • 오류 관리: 오류 페이지 위치( server.error.path) 등.
  • SSL
  • HTTP 압축

Spring Boot는 공통 설정을 노출하기 위해 가능한 한 많이 시도하지만 이것이 항상 가능한 것은 아닙니다. 이러한 경우 전용 네임스페이스는 서버별 사용자 지정을 제공합니다( server.tomcat및 참조 server.undertow). 예를 들어 내장된 서블릿 컨테이너의 특정 기능으로 액세스 로그를 구성할 수 있습니다.

  ServerProperties전체 목록은 클래스를 참조하십시오 .
SameSite 쿠키

쿠키 SameSite속성은 교차 사이트 요청에서 쿠키가 제출되는지 여부와 방법을 제어하기 위해 웹 브라우저에서 사용할 수 있습니다. 이 속성은 속성이 없을 때 사용되는 기본값을 변경하기 시작한 최신 웹 브라우저와 특히 관련이 있습니다.

세션 쿠키의 속성을 변경하려는 경우 속성을 SameSite사용할 수 있습니다 server.servlet.session.cookie.same-site. 이 속성은 자동 구성된 Tomcat, Jetty 및 Undertow 서버에서 지원됩니다. 또한 Spring Session 서블릿 기반 Bean을 구성하는 데 사용됩니다 SessionRepository.

예를 들어 세션 쿠키에 SameSite의 속성을 지정하려는 경우 또는 파일 None에 다음을 추가할 수 있습니다 .application.propertiesapplication.yaml

server.servlet.session.cookie.same-site=none
 

SameSite에 추가된 다른 쿠키의 속성을 HttpServletResponse변경 하려면 CookieSameSiteSupplier.  CookieSameSiteSupplier전달되고 값 또는 를 Cookie반환할 수 있습니다 .SameSitenull

특정 쿠키를 빠르게 일치시키는 데 사용할 수 있는 여러 편의 팩토리 및 필터 방법이 있습니다. 예를 들어, 다음 bean을 추가하면 정규 표현식과 일치하는 이름을 가진 모든 쿠키에 대해 SameSiteof를 자동으로 적용합니다 .Laxmyapp.*

@Configuration(proxyBeanMethods = false)
public class MySameSiteConfiguration {

    @Bean
    public CookieSameSiteSupplier applicationCookieSameSiteSupplier() {
        return CookieSameSiteSupplier.ofLax().whenHasNameMatching("myapp.*");
    }

}
 
프로그래밍 방식의 사용자 정의

포함된 서블릿 컨테이너를 프로그래밍 방식으로 구성해야 하는 경우 인터페이스를 구현하는 Spring Bean을 등록할 수 있습니다 WebServerFactoryCustomizer. 다양한 사용자 정의 setter 메소드를 포함하는 WebServerFactoryCustomizer에 대한 액세스를 제공합니다 . ConfigurableServletWebServerFactory다음 예에서는 포트를 프로그래밍 방식으로 설정하는 방법을 보여줍니다.

@Component
public class MyWebServerFactoryCustomizer implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory> {

    @Override
    public void customize(ConfigurableServletWebServerFactory server) {
        server.setPort(9000);
    }

}
 

TomcatServletWebServerFactory, JettyServletWebServerFactory그리고 각각 Tomcat, Jetty 및 Undertow에 대한 추가 사용자 지정 setter 메서드가 있는 UndertowServletWebServerFactory전용 변형입니다 ConfigurableServletWebServerFactory. 다음 예에서는 TomcatServletWebServerFactoryTomcat 관련 구성 옵션에 대한 액세스를 제공하는 사용자 정의 방법을 보여줍니다.

@Component
public class MyTomcatWebServerFactoryCustomizer implements WebServerFactoryCustomizer<TomcatServletWebServerFactory> {

    @Override
    public void customize(TomcatServletWebServerFactory server) {
        server.addConnectorCustomizers((connector) -> connector.setAsyncTimeout(Duration.ofSeconds(20).toMillis()));
    }

}
 
ConfigurableServletWebServerFactory 직접 사용자 지정

에서 확장해야 하는 고급 사용 사례의 경우 ServletWebServerFactory이러한 유형의 빈을 직접 노출할 수 있습니다.

많은 구성 옵션에 대해 Setter가 제공됩니다. 좀 더 이국적인 작업을 수행해야 하는 경우를 대비하여 몇 가지 보호된 메서드 "후크"도 제공됩니다. 자세한 내용은 소스 코드 설명서를 참조하십시오 .

  자동 구성된 사용자 지정자는 여전히 사용자 지정 공장에 적용되므로 해당 옵션을 신중하게 사용하십시오.

1.3.5. JSP 제한 사항

포함된 서블릿 컨테이너를 사용하는(및 실행 가능한 아카이브로 패키징된) Spring Boot 애플리케이션을 실행할 때 JSP 지원에 몇 가지 제한 사항이 있습니다.

  • War 패키징을 사용하는 경우 Jetty 및 Tomcat과 함께 작동해야 합니다. 실행 가능한 전쟁은 로 시작할 때 작동하며 java -jar모든 표준 컨테이너에 배포할 수도 있습니다. 실행 가능한 jar를 사용할 때는 JSP가 지원되지 않습니다.
  • Undertow는 JSP를 지원하지 않습니다.
  • 사용자 정의 페이지를 생성해도 오류 처리를error.jsp 위한 기본 보기가 무시되지 않습니다 . 대신 사용자 지정 오류 페이지를 사용해야 합니다.

2. 반응형 웹 애플리케이션

Spring Boot는 Spring Webflux에 대한 자동 구성을 제공하여 반응형 웹 애플리케이션 개발을 단순화합니다.

2.1. "스프링 웹플럭스 프레임워크"

Spring WebFlux는 Spring Framework 5.0에 도입된 새로운 반응형 웹 프레임워크입니다. Spring MVC와 달리 서블릿 API가 필요하지 않고 완전히 비동기식이며 비 차단이며 Reactor 프로젝트를 통해 Reactive Streams 사양을 구현합니다 .

Spring WebFlux는 기능적 및 주석 기반의 두 가지 형태로 제공됩니다. 주석 기반 모델은 다음 예제와 같이 Spring MVC 모델에 매우 가깝습니다.

@RestController
@RequestMapping("/users")
public class MyRestController {

    private final UserRepository userRepository;

    private final CustomerRepository customerRepository;

    public MyRestController(UserRepository userRepository, CustomerRepository customerRepository) {
        this.userRepository = userRepository;
        this.customerRepository = customerRepository;
    }

    @GetMapping("/{userId}")
    public Mono<User> getUser(@PathVariable Long userId) {
        return this.userRepository.findById(userId);
    }

    @GetMapping("/{userId}/customers")
    public Flux<Customer> getUserCustomers(@PathVariable Long userId) {
        return this.userRepository.findById(userId).flatMapMany(this.customerRepository::findByUser);
    }

    @DeleteMapping("/{userId}")
    public Mono<Void> deleteUser(@PathVariable Long userId) {
        return this.userRepository.deleteById(userId);
    }

}
 

기능 변형인 "WebFlux.fn"은 다음 예와 같이 라우팅 구성을 요청의 실제 처리와 분리합니다.

@Configuration(proxyBeanMethods = false)
public class MyRoutingConfiguration {

    private static final RequestPredicate ACCEPT_JSON = accept(MediaType.APPLICATION_JSON);

    @Bean
    public RouterFunction<ServerResponse> monoRouterFunction(MyUserHandler userHandler) {
        return route()
                .GET("/{user}", ACCEPT_JSON, userHandler::getUser)
                .GET("/{user}/customers", ACCEPT_JSON, userHandler::getUserCustomers)
                .DELETE("/{user}", ACCEPT_JSON, userHandler::deleteUser)
                .build();
    }

}
 
@Component
public class MyUserHandler {

    public Mono<ServerResponse> getUser(ServerRequest request) {
        ...
    }

    public Mono<ServerResponse> getUserCustomers(ServerRequest request) {
        ...
    }

    public Mono<ServerResponse> deleteUser(ServerRequest request) {
        ...
    }

}
 

WebFlux는 Spring Framework의 일부이며 자세한 정보는 참조 문서 에서 확인할 수 있습니다 .

  RouterFunction라우터의 정의를 모듈화하기 위해 원하는 만큼 빈을 정의할 수 있습니다 . 우선순위를 적용해야 하는 경우 콩을 주문할 수 있습니다.

시작하려면 spring-boot-starter-webflux애플리케이션에 모듈을 추가하십시오.

  애플리케이션에 spring-boot-starter-web및 모듈을 모두 추가하면 WebFlux가 아닌 Spring Boot 자동 구성 Spring MVC가 생성됩니다. 이 동작은 많은 Spring 개발자가 반응형을 사용하기 위해 Spring MVC 애플리케이션에 spring-boot-starter-webflux추가하기 때문에 선택되었습니다 . 선택한 애플리케이션 유형을 로 설정하여 여전히 선택을 적용할 수 있습니다 . spring-boot-starter-webfluxWebClientSpringApplication.setWebApplicationType(WebApplicationType.REACTIVE)

2.1.1. Spring WebFlux 자동 구성

Spring Boot는 대부분의 애플리케이션에서 잘 작동하는 Spring WebFlux에 대한 자동 구성을 제공합니다.

자동 구성은 Spring의 기본값 위에 다음 기능을 추가합니다.

Spring Boot WebFlux 기능 을 유지하고 추가 WebFlux 구성을@Configuration 추가하려는 경우 type의 자체 클래스를 추가할 수 WebFluxConfigurer있지만 . @EnableWebFlux

@ConfigurationSpring WebFlux를 완전히 제어 하려면 @EnableWebFlux.

2.1.2. HttpMessageReaders 및 HttpMessageWriters가 있는 HTTP 코덱

Spring WebFlux는 HttpMessageReader및 HttpMessageWriter인터페이스를 사용하여 HTTP 요청 및 응답을 변환합니다. CodecConfigurer클래스 경로에서 사용 가능한 라이브러리를 확인하여 합리적인 기본값을 갖도록 구성됩니다 .

Spring Boot는 코덱에 대한 전용 구성 속성을 제공합니다 spring.codec.*. 또한 인스턴스를 사용하여 추가 사용자 정의를 적용합니다 CodecCustomizer. 예를 들어 spring.jackson.*구성 키는 Jackson 코덱에 적용됩니다.

CodecCustomizer코덱을 추가하거나 사용자 지정해야 하는 경우 다음 예와 같이 사용자 지정 구성 요소를 생성할 수 있습니다 .

@Configuration(proxyBeanMethods = false)
public class MyCodecsConfiguration {

    @Bean
    public CodecCustomizer myCodecCustomizer() {
        return (configurer) -> {
            configurer.registerDefaults(false);
            configurer.customCodecs().register(new ServerSentEventHttpMessageReader());
            // ...
        };
    }

}
 

2.1.3. 정적 콘텐츠

기본적으로 Spring Boot는 클래스 경로에서 /static(또는 /public또는 /resources또는 /META-INF/resources)라는 디렉토리의 정적 콘텐츠를 제공합니다. Spring WebFlux의 를 사용하므로 자신만의 메서드를 추가 하고 재정의하여 ResourceWebHandler해당 동작을 수정할 수 있습니다 .WebFluxConfigureraddResourceHandlers

기본적으로 리소스는 에 매핑되지만 /**속성을 설정하여 조정할 수 있습니다 spring.webflux.static-path-pattern. 예를 들어 /resources/**다음과 같이 모든 리소스를 재배치할 수 있습니다.

spring.webflux.static-path-pattern=/resources/**
 

를 사용하여 정적 리소스 위치를 사용자 지정할 수도 있습니다 spring.web.resources.static-locations. 이렇게 하면 기본값이 디렉터리 위치 목록으로 대체됩니다. 그렇게 하면 기본 시작 페이지 감지가 사용자 정의 위치로 전환됩니다. 따라서 시작 시 위치에 가 있으면 index.html애플리케이션의 홈 페이지입니다.

앞서 나열된 "표준" 정적 리소스 위치 외에도 Webjars 콘텐츠 에 대한 특별한 경우가 있습니다 . 기본적으로 경로가 있는 리소스는 /webjars/**Webjars 형식으로 패키징된 경우 jar 파일에서 제공됩니다. 경로는 spring.webflux.webjars-path-pattern속성으로 사용자 정의할 수 있습니다.

  Spring WebFlux 애플리케이션은 서블릿 API에 엄격하게 의존하지 않으므로 war 파일로 배포할 수 없으며 디렉토리를 사용하지 않습니다 src/main/webapp.

2.1.4. 환영 페이지

Spring Boot는 정적 및 템플릿 시작 페이지를 모두 지원합니다. index.html먼저 구성된 정적 콘텐츠 위치에서 파일을 찾습니다 . 템플릿 이 없으면 템플릿을 찾습니다 index. 둘 중 하나가 발견되면 자동으로 애플리케이션의 시작 페이지로 사용됩니다.

2.1.5. 템플릿 엔진

REST 웹 서비스뿐만 아니라 Spring WebFlux를 사용하여 동적 HTML 콘텐츠를 제공할 수도 있습니다. Spring WebFlux는 Thymeleaf, FreeMarker 및 Mustache를 포함한 다양한 템플릿 기술을 지원합니다.

Spring Boot에는 다음 템플릿 엔진에 대한 자동 구성 지원이 포함되어 있습니다.

이러한 템플릿 엔진 중 하나를 기본 구성으로 사용하면 템플릿이 에서 자동으로 선택됩니다 src/main/resources/templates.

 

2.1.6. 오류 처리

Spring Boot는 WebExceptionHandler합리적인 방식으로 모든 오류를 처리하는 를 제공합니다. 처리 순서에서 그 위치는 마지막으로 간주되는 WebFlux에서 제공하는 핸들러 바로 앞에 있습니다. 머신 클라이언트의 경우 오류 세부 정보, HTTP 상태 및 예외 메시지가 포함된 JSON 응답을 생성합니다. 브라우저 클라이언트의 경우 동일한 데이터를 HTML 형식으로 렌더링하는 "whitelabel" 오류 처리기가 있습니다. 오류를 표시하기 위해 고유한 HTML 템플릿을 제공할 수도 있습니다( 다음 섹션 참조 ).

Spring Boot에서 직접 오류 처리를 사용자 지정하기 전에 Spring WebFlux에서 RFC 7807 문제 세부 정보 지원을 활용할 수 있습니다 . Spring WebFlux는 application/problem+json다음과 같은 미디어 유형으로 사용자 지정 오류 메시지를 생성할 수 있습니다.

{
  "type": "https://example.org/problems/unknown-project",
  "title": "Unknown project",
  "status": 404,
  "detail": "No project found for id 'spring-unknown'",
  "instance": "/projects/spring-unknown"
}
 

spring.webflux.problemdetails.enabled이 지원은 로 설정하여 활성화할 수 있습니다 true.

이 기능을 사용자 지정하는 첫 번째 단계는 종종 기존 메커니즘을 사용하지만 오류 내용을 대체하거나 보강하는 것입니다. 이를 위해 유형의 bean을 추가할 수 있습니다 ErrorAttributes.

오류 처리 동작을 변경하려면 ErrorWebExceptionHandler해당 유형의 빈 정의를 구현하고 등록할 수 있습니다. ErrorWebExceptionHandleran 은 매우 낮은 수준이기 때문에 Spring Boot AbstractErrorWebExceptionHandler는 다음 예제와 같이 WebFlux 기능 방식으로 오류를 처리할 수 있는 편리한 기능도 제공합니다.

@Component
public class MyErrorWebExceptionHandler extends AbstractErrorWebExceptionHandler {

    public MyErrorWebExceptionHandler(ErrorAttributes errorAttributes, Resources resources,
            ApplicationContext applicationContext) {
        super(errorAttributes, resources, applicationContext);
    }

    @Override
    protected RouterFunction<ServerResponse> getRoutingFunction(ErrorAttributes errorAttributes) {
        return RouterFunctions.route(this::acceptsXml, this::handleErrorAsXml);
    }

    private boolean acceptsXml(ServerRequest request) {
        return request.headers().accept().contains(MediaType.APPLICATION_XML);
    }

    public Mono<ServerResponse> handleErrorAsXml(ServerRequest request) {
        BodyBuilder builder = ServerResponse.status(HttpStatus.INTERNAL_SERVER_ERROR);
        // ... additional builder calls
        return builder.build();
    }

}
 

DefaultErrorWebExceptionHandler보다 완전한 그림을 위해 직접 하위 클래스를 지정하고 특정 메서드를 재정의 할 수도 있습니다 .

경우에 따라 컨트롤러 또는 핸들러 기능 수준에서 처리되는 오류가 메트릭 인프라 에 의해 기록되지 않습니다 . 애플리케이션은 처리된 예외를 요청 속성으로 설정하여 이러한 예외가 요청 메트릭과 함께 기록되도록 할 수 있습니다.

@Controller
public class MyExceptionHandlingController {

    @GetMapping("/profile")
    public Rendering userProfile() {
        // ...
        throw new IllegalStateException();
    }

    @ExceptionHandler(IllegalStateException.class)
    public Rendering handleIllegalState(ServerWebExchange exchange, IllegalStateException exc) {
        exchange.getAttributes().putIfAbsent(ErrorAttributes.ERROR_ATTRIBUTE, exc);
        return Rendering.view("errorView").modelAttribute("message", exc.getMessage()).build();
    }

}
 
사용자 지정 오류 페이지

주어진 상태 코드에 대한 사용자 정의 HTML 오류 페이지를 표시하려는 경우 error/*예를 들어 /error디렉토리에 파일을 추가하여 에서 확인하는 보기를 추가할 수 있습니다. 오류 페이지는 정적 HTML(즉, 정적 리소스 디렉터리 아래에 추가됨)이거나 템플릿으로 작성될 수 있습니다. 파일의 이름은 정확한 상태 코드, 상태 코드 시리즈 마스크 또는 error일치하는 항목이 없는 경우 기본값이어야 합니다. 기본 오류 보기의 경로는 이지만 error/errorSpring MVC에서는 기본 오류 보기가 입니다 error.

예를 들어 404정적 HTML 파일에 매핑하려면 디렉토리 구조가 다음과 같습니다.

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- public/
             +- error/
             |   +- 404.html
             +- <other public assets>
 

Mustache 템플릿을 사용하여 모든 오류를 매핑하려면 5xx디렉터리 구조는 다음과 같습니다.

src/
 +- main/
     +- java/
     |   + <source code>
     +- resources/
         +- templates/
             +- error/
             |   +- 5xx.mustache
             +- <other templates>
 

2.1.7. 웹 필터

Spring WebFlux는 WebFilterHTTP 요청-응답 교환을 필터링하기 위해 구현할 수 있는 인터페이스를 제공합니다. WebFilter애플리케이션 컨텍스트에서 발견된 빈은 각 교환을 필터링하는 데 자동으로 사용됩니다.

필터의 순서가 중요한 경우 필터를 구현하거나 Ordered주석을 달 수 있습니다 @Order. Spring Boot 자동 구성은 웹 필터를 구성할 수 있습니다. 그렇게 하면 다음 표에 표시된 주문이 사용됩니다.

웹 필터주문하다
ServerHttpObservationFilter(마이크로미터 관찰성) Ordered.HIGHEST_PRECEDENCE + 1
WebFilterChainProxy(스프링 시큐리티) -100
HttpExchangesWebFilter Ordered.LOWEST_PRECEDENCE - 10

2.2. 임베디드 리액티브 서버 지원

Spring Boot는 Reactor Netty, Tomcat, Jetty 및 Undertow와 같은 임베디드 반응형 웹 서버에 대한 지원을 포함합니다. 대부분의 개발자는 적절한 "스타터"를 사용하여 완전히 구성된 인스턴스를 얻습니다. 기본적으로 내장 서버는 포트 8080에서 HTTP 요청을 수신합니다.

2.3. 반응적 서버 리소스 구성

Reactor Netty 또는 Jetty 서버를 자동 구성할 때 Spring Boot는 서버 인스턴스에 HTTP 리소스를 제공할 특정 빈을 생성 ReactorResourceFactory합니다 JettyResourceFactory.

기본적으로 이러한 리소스는 다음과 같이 최적의 성능을 위해 Reactor Netty 및 Jetty 클라이언트와도 공유됩니다.

  • 동일한 기술이 서버와 클라이언트에 사용됩니다.
  • 클라이언트 인스턴스는 WebClient.BuilderSpring Boot에 의해 자동 구성된 bean을 사용하여 빌드됩니다.

ReactorResourceFactory개발자는 사용자 지정 또는 bean 을 제공하여 Jetty 및 Reactor Netty에 대한 리소스 구성을 재정의할 수 있습니다 JettyResourceFactory. 이는 클라이언트와 서버 모두에 적용됩니다.

WebClient Runtime 섹션 에서 클라이언트 측 리소스 구성에 대해 자세히 알아볼 수 있습니다 .

3. 정상적인 종료

정상적인 종료는 4개의 내장 웹 서버(Jetty, Reactor Netty, Tomcat 및 Undertow) 모두와 반응형 및 서블릿 기반 웹 애플리케이션 모두에서 지원됩니다. 애플리케이션 컨텍스트 닫기의 일부로 발생하며 SmartLifecycleBean 중지의 가장 초기 단계에서 수행됩니다. 이 처리 중지는 기존 요청을 완료할 수 있지만 새 요청은 허용되지 않는 유예 기간을 제공하는 제한 시간을 사용합니다. 새로운 요청이 허용되지 않는 정확한 방법은 사용 중인 웹 서버에 따라 다릅니다. Jetty, Reactor Netty 및 Tomcat은 네트워크 계층에서 요청 수락을 중지합니다. Undertow는 요청을 수락하지만 즉시 서비스 불가(503) 응답으로 응답합니다.

  Tomcat으로 정상적으로 종료하려면 Tomcat 9.0.33 이상이 필요합니다.

정상적인 종료를 활성화하려면 server.shutdown다음 예와 같이 속성을 구성합니다.

server.shutdown=graceful
 

제한 시간을 구성하려면 spring.lifecycle.timeout-per-shutdown-phase다음 예와 같이 속성을 구성합니다.

spring.lifecycle.timeout-per-shutdown-phase=20s
 
  IDE에서 정상적인 종료를 사용하면 적절한 신호를 보내지 않으면 제대로 작동하지 않을 수 있습니다 SIGTERM. 자세한 내용은 IDE 설명서를 참조하십시오.

4. 스프링 시큐리티

Spring Security가 클래스 경로에 있으면 웹 애플리케이션이 기본적으로 보호됩니다 . Spring Boot는 Spring Security의 콘텐츠 협상 전략을 사용하여 httpBasic또는 formLogin. 웹 애플리케이션에 메서드 수준 보안을 추가하기 위해 @EnableGlobalMethodSecurity원하는 설정으로 추가할 수도 있습니다. 추가 정보는 Spring Security Reference Guide 에서 찾을 수 있습니다 .

기본값에는 UserDetailsService단일 사용자가 있습니다. 사용자 이름은 이고 user암호는 무작위이며 다음 예와 같이 응용 프로그램이 시작될 때 WARN 수준에서 인쇄됩니다.

생성된 보안 암호 사용: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35

이 생성된 암호는 개발용으로만 사용됩니다. 프로덕션 환경에서 애플리케이션을 실행하기 전에 보안 구성을 업데이트해야 합니다.
  로깅 구성을 미세 조정하는 경우 org.springframework.boot.autoconfigure.security범주가 로그 WARN수준 메시지로 설정되어 있는지 확인하십시오. 그렇지 않으면 기본 암호가 인쇄되지 않습니다.

spring.security.user.name및 를 제공하여 사용자 이름과 암호를 변경할 수 있습니다 spring.security.user.password.

웹 애플리케이션에서 기본적으로 제공되는 기본 기능은 다음과 같습니다.

  • 메모리 내 저장소가 있는 빈 UserDetailsService(또는 ReactiveUserDetailsServiceWebFlux 애플리케이션의 경우) 및 생성된 암호가 있는 단일 사용자( SecurityProperties.User사용자 속성은 참조).
  • Accept전체 애플리케이션(액추에이터가 클래스 경로에 있는 경우 액추에이터 끝점 포함)에 대한 양식 기반 로그인 또는 HTTP 기본 보안(요청의 헤더에 따라 다름 ).
  • DefaultAuthenticationEventPublisher인증 이벤트를 게시하기 위한 A입니다 .

AuthenticationEventPublisher빈을 추가하여 다른 것을 제공할 수 있습니다 .

4.1. MVC 보안

기본 보안 구성은 SecurityAutoConfiguration및 에서 구현됩니다 UserDetailsServiceAutoConfiguration. 웹 보안을 위해 SecurityAutoConfiguration가져오고 웹이 아닌 애플리케이션과 관련된 인증을 구성합니다. 기본 웹 애플리케이션 보안 구성을 완전히 끄거나 OAuth2 Client 및 Resource Server와 같은 여러 Spring Security 구성 요소를 결합하려면 유형의 bean을 추가합니다 (그렇게 해도 구성 또는 Actuator의 보안이 비활성화되지 않음 ).SpringBootWebSecurityConfigurationUserDetailsServiceAutoConfigurationSecurityFilterChainUserDetailsService

또한 구성을 끄려면 , 또는 UserDetailsService유형의 bean을 추가할 수 있습니다 .UserDetailsServiceAuthenticationProviderAuthenticationManager

액세스 규칙은 사용자 지정 bean을 추가하여 재정의할 수 있습니다 SecurityFilterChain. Spring Boot는 액추에이터 엔드포인트 및 정적 리소스에 대한 액세스 규칙을 재정의하는 데 사용할 수 있는 편리한 메서드를 제공합니다. 속성을 기반으로 하는 EndpointRequest를 만드는 데 사용할 수 있습니다 . 일반적으로 사용되는 위치에서 리소스를 만드는 데 사용할 수 있습니다 .RequestMatchermanagement.endpoints.web.base-pathPathRequestRequestMatcher

4.2. 웹플럭스 시큐리티

Spring MVC 애플리케이션과 마찬가지로 spring-boot-starter-security종속성을 추가하여 WebFlux 애플리케이션을 보호할 수 있습니다. 기본 보안 구성은 ReactiveSecurityAutoConfiguration및 에서 구현됩니다 UserDetailsServiceAutoConfiguration. 웹 보안을 위해 ReactiveSecurityAutoConfiguration가져오고 웹이 아닌 애플리케이션과 관련된 인증을 구성합니다. 기본 웹 애플리케이션 보안 구성을 완전히 끄려면 유형의 bean을 추가할 수 있습니다 (그렇게 해도 구성 또는 Actuator의 보안이 비활성화되지 않음 ).WebFluxSecurityConfigurationUserDetailsServiceAutoConfigurationWebFilterChainProxyUserDetailsService

구성 을 끄려면 또는 UserDetailsService유형의 bean을 추가할 수 있습니다 .ReactiveUserDetailsServiceReactiveAuthenticationManager

액세스 규칙 및 OAuth 2 클라이언트 및 리소스 서버와 같은 여러 스프링 보안 구성 요소의 사용은 사용자 지정 SecurityWebFilterChain빈을 추가하여 구성할 수 있습니다. Spring Boot는 액추에이터 엔드포인트 및 정적 리소스에 대한 액세스 규칙을 재정의하는 데 사용할 수 있는 편리한 메서드를 제공합니다. 속성을 기반으로 하는 EndpointRequest를 만드는 데 사용할 수 있습니다 .ServerWebExchangeMatchermanagement.endpoints.web.base-path

PathRequestServerWebExchangeMatcher일반적으로 사용되는 위치에서 리소스를 만드는 데 사용할 수 있습니다 .

예를 들어 다음과 같은 항목을 추가하여 보안 구성을 사용자 지정할 수 있습니다.

@Configuration(proxyBeanMethods = false)
public class MyWebFluxSecurityConfiguration {

    @Bean
    public SecurityWebFilterChain springSecurityFilterChain(ServerHttpSecurity http) {
        http.authorizeExchange((exchange) -> {
            exchange.matchers(PathRequest.toStaticResources().atCommonLocations()).permitAll();
            exchange.pathMatchers("/foo", "/bar").authenticated();
        });
        http.formLogin(withDefaults());
        return http.build();
    }

}
 

4.3. OAuth2

OAuth2 는 Spring에서 지원하는 널리 사용되는 인증 프레임워크입니다.

4.3.1. 고객

클래스 경로에 있는 경우 spring-security-oauth2-client일부 자동 구성을 활용하여 OAuth2/Open ID Connect 클라이언트를 설정할 수 있습니다. 이 구성은 아래의 속성을 사용합니다 OAuth2ClientProperties. 서블릿 및 반응형 애플리케이션 모두에 동일한 속성을 적용할 수 있습니다.

spring.security.oauth2.client다음 예와 같이 접두사 아래에 여러 OAuth2 클라이언트 및 공급자를 등록할 수 있습니다 .

spring.security.oauth2.client.registration.my-client-1.client-id=abcd
spring.security.oauth2.client.registration.my-client-1.client-secret=password
spring.security.oauth2.client.registration.my-client-1.client-name=Client for user scope
spring.security.oauth2.client.registration.my-client-1.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-1.scope=user
spring.security.oauth2.client.registration.my-client-1.redirect-uri=https://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-1.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-1.authorization-grant-type=authorization_code

spring.security.oauth2.client.registration.my-client-2.client-id=abcd
spring.security.oauth2.client.registration.my-client-2.client-secret=password
spring.security.oauth2.client.registration.my-client-2.client-name=Client for email scope
spring.security.oauth2.client.registration.my-client-2.provider=my-oauth-provider
spring.security.oauth2.client.registration.my-client-2.scope=email
spring.security.oauth2.client.registration.my-client-2.redirect-uri=https://my-redirect-uri.com
spring.security.oauth2.client.registration.my-client-2.client-authentication-method=basic
spring.security.oauth2.client.registration.my-client-2.authorization-grant-type=authorization_code

spring.security.oauth2.client.provider.my-oauth-provider.authorization-uri=https://my-auth-server/oauth/authorize
spring.security.oauth2.client.provider.my-oauth-provider.token-uri=https://my-auth-server/oauth/token
spring.security.oauth2.client.provider.my-oauth-provider.user-info-uri=https://my-auth-server/userinfo
spring.security.oauth2.client.provider.my-oauth-provider.user-info-authentication-method=header
spring.security.oauth2.client.provider.my-oauth-provider.jwk-set-uri=https://my-auth-server/token_keys
spring.security.oauth2.client.provider.my-oauth-provider.user-name-attribute=name
 

OpenID Connect 검색을 지원하는 OpenID Connect 공급자의 경우 구성을 더욱 간소화할 수 있습니다. 공급자는 issuer-uri발급자 식별자로 어설션하는 URI를 사용하여 구성해야 합니다. 예를 들어 issuer-uri제공된 것이 "https://example.com"인 경우 "https://example.com/.well-known/openid-configuration"에 "OpenID 공급자 구성 요청"이 생성됩니다. 결과는 "OpenID 공급자 구성 응답"이 될 것으로 예상됩니다. 다음 예는 다음을 사용하여 OpenID Connect 공급자를 구성하는 방법을 보여줍니다 issuer-uri.

spring.security.oauth2.client.provider.oidc-provider.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
 

기본적으로 Spring Security는 OAuth2LoginAuthenticationFilter일치하는 URL만 처리합니다 /login/oauth2/code/*. 다른 패턴 을 사용하도록 사용자 정의하려면 redirect-uri해당 사용자 정의 패턴을 처리하기 위한 구성을 제공해야 합니다. SecurityFilterChain예를 들어, 서블릿 애플리케이션의 경우 다음과 유사한 자체 애플리케이션을 추가할 수 있습니다 .

@Configuration(proxyBeanMethods = false)
public class MyOAuthClientConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests((requests) -> requests.anyRequest().authenticated());
        http.oauth2Login((login) -> login.redirectionEndpoint().baseUri("custom-callback"));
        return http.build();
    }

}
 
  InMemoryOAuth2AuthorizedClientServiceSpring Boot는 클라이언트 등록 관리를 위해 Spring Security에서 사용하는 를 자동 구성합니다 . 에는 InMemoryOAuth2AuthorizedClientService기능이 제한되어 있으므로 개발 환경에서만 사용하는 것이 좋습니다. 프로덕션 환경의 경우 를 사용 JdbcOAuth2AuthorizedClientService하거나 OAuth2AuthorizedClientService.
공통 제공자를 위한 OAuth2 클라이언트 등록

Google, Github, Facebook 및 Okta를 포함한 일반적인 OAuth2 및 OpenID 공급자의 경우 공급자 기본값 집합( 각각 google, github, facebook및 okta)을 제공합니다.

이러한 공급자를 사용자 지정할 필요가 없는 경우 provider속성을 기본값을 유추해야 하는 속성으로 설정할 수 있습니다. 또한 클라이언트 등록을 위한 키가 지원되는 기본 공급자와 일치하는 경우 Spring Boot는 이를 유추합니다.

즉, 다음 예의 두 구성은 Google 공급자를 사용합니다.

spring.security.oauth2.client.registration.my-client.client-id=abcd
spring.security.oauth2.client.registration.my-client.client-secret=password
spring.security.oauth2.client.registration.my-client.provider=google
spring.security.oauth2.client.registration.google.client-id=abcd
spring.security.oauth2.client.registration.google.client-secret=password
 

4.3.2. 리소스 서버

클래스 경로에 있는 경우 spring-security-oauth2-resource-serverSpring Boot는 OAuth2 리소스 서버를 설정할 수 있습니다. JWT 구성의 경우 다음 예와 같이 JWK 설정 URI 또는 ​​OIDC 발급자 URI를 지정해야 합니다.

spring.security.oauth2.resourceserver.jwt.jwk-set-uri=https://example.com/oauth2/default/v1/keys
 
spring.security.oauth2.resourceserver.jwt.issuer-uri=https://dev-123456.oktapreview.com/oauth2/default/
 
  권한 부여 서버가 JWK 설정 URI를 지원하지 않는 경우 JWT의 서명을 확인하는 데 사용되는 공개 키로 리소스 서버를 구성할 수 있습니다. spring.security.oauth2.resourceserver.jwt.public-key-location이것은 값이 PEM 인코딩된 x509 형식의 공개 키를 포함하는 파일을 가리켜야 하는 속성을 사용하여 수행할 수 있습니다 .

서블릿 및 반응형 애플리케이션 모두에 동일한 속성을 적용할 수 있습니다.

또는 JwtDecoder서블릿 애플리케이션용 또는 ReactiveJwtDecoder반응형 애플리케이션용으로 고유한 bean을 정의할 수 있습니다.

JWT 대신 불투명 토큰을 사용하는 경우 검사를 통해 토큰을 검증하도록 다음 속성을 구성할 수 있습니다.

spring.security.oauth2.resourceserver.opaquetoken.introspection-uri=https://example.com/check-token
spring.security.oauth2.resourceserver.opaquetoken.client-id=my-client-id
spring.security.oauth2.resourceserver.opaquetoken.client-secret=my-client-secret
 

다시 말하지만 서블릿 및 반응형 애플리케이션 모두에 동일한 속성을 적용할 수 있습니다.

또는 OpaqueTokenIntrospector서블릿 애플리케이션용 또는 ReactiveOpaqueTokenIntrospector반응형 애플리케이션용으로 고유한 bean을 정의할 수 있습니다.

4.3.3. 인증 서버

Spring Authorization Server 프로젝트를 사용하여 OAuth 2.0 Authorization Server를 구현할 수 있습니다.

4.4. SAML 2.0

4.4.1. 신뢰 당사자

클래스 경로에 있는 경우 spring-security-saml2-service-provider일부 자동 구성을 활용하여 SAML 2.0 신뢰 당사자를 설정할 수 있습니다. 이 구성은 아래의 속성을 사용합니다 Saml2RelyingPartyProperties.

신뢰 당사자 등록은 ID 공급자(IDP)와 서비스 공급자(SP) 간의 쌍 구성을 나타냅니다. spring.security.saml2.relyingparty다음 예와 같이 접두사 아래에 여러 신뢰 당사자를 등록할 수 있습니다 .

spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party1.signing.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party1.decryption.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party1.decryption.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party1.singlelogout.url=https://myapp/logout/saml2/slo
spring.security.saml2.relyingparty.registration.my-relying-party1.singlelogout.response-url=https://remoteidp2.slo.url
spring.security.saml2.relyingparty.registration.my-relying-party1.singlelogout.binding=POST
spring.security.saml2.relyingparty.registration.my-relying-party1.assertingparty.verification.credentials[0].certificate-location=path-to-verification-cert
spring.security.saml2.relyingparty.registration.my-relying-party1.assertingparty.entity-id=remote-idp-entity-id1
spring.security.saml2.relyingparty.registration.my-relying-party1.assertingparty.sso-url=https://remoteidp1.sso.url

spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party2.signing.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party2.decryption.credentials[0].private-key-location=path-to-private-key
spring.security.saml2.relyingparty.registration.my-relying-party2.decryption.credentials[0].certificate-location=path-to-certificate
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.verification.credentials[0].certificate-location=path-to-other-verification-cert
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.entity-id=remote-idp-entity-id2
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.sso-url=https://remoteidp2.sso.url
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.singlelogout.url=https://remoteidp2.slo.url
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.singlelogout.response-url=https://myapp/logout/saml2/slo
spring.security.saml2.relyingparty.registration.my-relying-party2.assertingparty.singlelogout.binding=POST
 

SAML2 로그아웃의 경우 기본적으로 Spring Security Saml2LogoutRequestFilter와 Saml2LogoutResponseFilter일치하는 URL만 처리합니다 /logout/saml2/slo. urlAP에서 시작된 로그아웃 요청이 전송되는 대상 또는 response-urlAP가 로그아웃 응답을 전송하는 대상을 사용자 지정하여 다른 패턴을 사용하려면 해당 사용자 지정 패턴을 처리하는 구성을 제공해야 합니다. SecurityFilterChain예를 들어, 서블릿 애플리케이션의 경우 다음과 유사한 자체 애플리케이션을 추가할 수 있습니다 .

@Configuration(proxyBeanMethods = false)
public class MySamlRelyingPartyConfiguration {

    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests().anyRequest().authenticated();
        http.saml2Login();
        http.saml2Logout((saml2) -> saml2.logoutRequest((request) -> request.logoutUrl("/SLOService.saml2"))
            .logoutResponse((response) -> response.logoutUrl("/SLOService.saml2")));
        return http.build();
    }

}
 

5. 스프링 세션

Spring Boot는 다양한 데이터 저장소에 대한 Spring 세션 자동 구성을 제공합니다. 서블릿 웹 애플리케이션을 구축할 때 다음 저장소를 자동 구성할 수 있습니다.

  • 레디스
  • JDBC
  • Hazelcast
  • 몽고DB

서블릿 자동 구성은 @Enable*HttpSession.

클래스 경로에 단일 Spring 세션 모듈이 있는 경우 Spring Boot는 해당 저장소 구현을 자동으로 사용합니다. 둘 이상의 구현이 있는 경우 Spring Boot는 특정 구현을 선택하기 위해 다음 순서를 사용합니다.

  1. 레디스
  2. JDBC
  3. Hazelcast
  4. 몽고DB
  5. Redis, JDBC, Hazelcast 및 MongoDB를 사용할 수 없는 경우 SessionRepository.

반응형 웹 애플리케이션을 구축할 때 다음 저장소를 자동 구성할 수 있습니다.

  • 레디스
  • 몽고DB

반응형 자동 구성은 @Enable*WebSession.

서블릿 구성과 유사하게 하나 이상의 구현이 있는 경우 Spring Boot는 특정 구현을 선택하기 위해 다음 순서를 사용합니다.

  1. 레디스
  2. 몽고DB
  3. Redis와 MongoDB를 모두 사용할 수 없는 경우 ReactiveSessionRepository.

각 상점에는 특정한 추가 설정이 있습니다. 예를 들어 다음 예와 같이 JDBC 저장소의 테이블 이름을 사용자 지정할 수 있습니다.

spring.session.jdbc.table-name=SESSIONS
 

세션의 제한 시간을 설정하려면 spring.session.timeout속성을 사용할 수 있습니다. 해당 속성이 서블릿 웹 응용 프로그램으로 설정되지 않은 경우 자동 구성은 의 값으로 대체됩니다 server.servlet.session.timeout.

@Enable*HttpSession(servlet) 또는 @Enable*WebSession(reactive)를 사용하여 Spring 세션의 구성을 제어할 수 있습니다 . 이렇게 하면 자동 구성이 백오프됩니다. 그런 다음 이전에 설명한 구성 속성이 아닌 주석의 속성을 사용하여 Spring 세션을 구성할 수 있습니다.

6. GraphQL용 스프링

GraphQL 애플리케이션을 빌드하려는 경우 Spring for GraphQL 에 대한 Spring Boot의 자동 구성을 활용할 수 있습니다 . Spring for GraphQL 프로젝트는 GraphQL Java 를 기반으로 합니다 . spring-boot-starter-graphql최소한 스타터가 필요합니다 . GraphQL은 전송에 구애받지 않기 때문에 웹을 통해 GraphQL API를 노출하려면 애플리케이션에 하나 이상의 추가 스타터가 있어야 합니다.

기동기수송구현
spring-boot-starter-web HTTP 스프링 MVC
spring-boot-starter-websocket 웹소켓 서블릿 앱용 WebSocket
spring-boot-starter-webflux HTTP, 웹소켓 스프링 웹플럭스
spring-boot-starter-rsocket TCP, 웹소켓 Reactor Netty의 Spring WebFlux

6.1. GraphQL 스키마

Spring GraphQL 애플리케이션에는 시작 시 정의된 스키마가 필요합니다. 기본적으로 ".graphqls" 또는 ".gqls" 스키마 파일을 작성할 수 있으며 src/main/resources/graphql/**Spring Boot가 자동으로 선택합니다. 로 위치를 사용자 정의하고 spring.graphql.schema.locations로 파일 확장자를 사용자 정의할 수 있습니다 spring.graphql.schema.file-extensions.

  Spring Boot가 모든 애플리케이션 모듈의 스키마 파일과 해당 위치에 대한 종속성을 감지하도록 하려면 ( 접두사 참고) spring.graphql.schema.locations로 설정할 수 있습니다."classpath*:graphql/**/"classpath*:

다음 섹션에서는 두 가지 유형과 두 가지 쿼리를 정의하는 이 샘플 GraphQL 스키마를 살펴보겠습니다.

type Query {
    greeting(name: String! = "Spring"): String!
    project(slug: ID!): Project
}

""" A Project in the Spring portfolio """
type Project {
    """ Unique string id used in URLs """
    slug: ID!
    """ Project name """
    name: String!
    """ URL of the git repository """
    repositoryUrl: String!
    """ Current support status """
    status: ProjectStatus!
}

enum ProjectStatus {
    """ Actively supported by the Spring team """
    ACTIVE
    """ Supported by the community """
    COMMUNITY
    """ Prototype, not officially supported yet  """
    INCUBATING
    """ Project being retired, in maintenance mode """
    ATTIC
    """ End-Of-Lifed """
    EOL
}
 
  기본적으로 GraphiQL과 같은 도구에 필요하므로 스키마에서 필드 검사가 허용됩니다. 스키마에 대한 정보를 노출하지 않으려면 로 설정하여 검사를 비활성화할 수 spring.graphql.schema.introspection.enabled있습니다 false.

6.2. GraphQL Runtime배선

GraphQL Java는 사용자 지정 스칼라 유형, 지시문, 유형 확인자 등을 RuntimeWiring.Builder등록하는 데 사용할 수 있습니다 . Spring 구성에서 빈을 DataFetcher선언하여 . Spring Boot는 이러한 빈을 감지하고 GraphQlSource 빌더 에 추가합니다 .RuntimeWiringConfigurerRuntimeWiring.Builder

그러나 일반적으로 애플리케이션은 직접 구현하지 않고 대신 주석이 달린 컨트롤러를DataFetcher 생성합니다 . Spring Boot는 주석 처리기 메서드가 있는 클래스를 자동으로 감지하고 이를 s로 등록합니다. 다음은 클래스를 사용한 인사말 쿼리에 대한 샘플 구현입니다 .@ControllerDataFetcher@Controller

@Controller
public class GreetingController {

    @QueryMapping
    public String greeting(@Argument String name) {
        return "Hello, " + name + "!";
    }

}
 

6.3. Querydsl 및 QueryByExample 리포지토리 지원

Spring Data는 Querydsl 및 QueryByExample 리포지토리를 모두 지원합니다. Spring GraphQL은 Querydsl 및 QueryByExample 리포지토리를DataFetcher .

다음 중 하나로 주석이 추가되고 다음 중 하나를 확장하는 Spring Data 리포지토리 @GraphQlRepository:

  • QuerydslPredicateExecutor
  • ReactiveQuerydslPredicateExecutor
  • QueryByExampleExecutor
  • ReactiveQueryByExampleExecutor

Spring Boot에 의해 감지되고 DataFetcher일치하는 최상위 쿼리의 후보로 간주됩니다.

6.4. Transports

6.4.1. HTTP와 웹소켓

GraphQL HTTP 엔드포인트는 /graphql기본적으로 HTTP POST에 있습니다. 경로는 spring.graphql.path.

  RouterFunctionSpring MVC와 Spring WebFlux 모두 에 @Order대한 HTTP 엔드포인트는 0. 고유한 빈을 정의하는 경우 올바르게 정렬되도록 RouterFunction적절한 주석을 추가할 수 있습니다 .@Order

GraphQL WebSocket 엔드포인트는 기본적으로 꺼져 있습니다. 활성화하려면:

  • Servlet 애플리케이션의 경우 WebSocket 스타터를 추가하십시오.spring-boot-starter-websocket
  • WebFlux 애플리케이션의 경우 추가 종속성이 필요하지 않습니다.
  • 둘 다에 대해 spring.graphql.websocket.path애플리케이션 속성을 설정해야 합니다.

Spring GraphQL은 Web Interception 모델을 제공합니다. 이것은 HTTP 요청 헤더에서 정보를 검색하고 GraphQL 컨텍스트에서 설정하거나 동일한 컨텍스트에서 정보를 가져와서 응답 헤더에 쓰는 데 매우 유용합니다. WebInterceptorSpring Boot를 사용하면 bean을 선언하여 웹 전송에 등록 할 수 있습니다 .

Spring MVC  Spring WebFlux는 CORS(Cross-Origin Resource Sharing) 요청을 지원합니다. CORS는 다른 도메인을 사용하는 브라우저에서 액세스하는 GraphQL 애플리케이션의 웹 구성에서 중요한 부분입니다.

Spring Boot는 spring.graphql.cors.*네임스페이스에서 많은 구성 속성을 지원합니다. 다음은 짧은 구성 샘플입니다.

spring.graphql.cors.allowed-origins=https://example.org
spring.graphql.cors.allowed-methods=GET,POST
spring.graphql.cors.max-age=1800s
 

6.4.2. RSocket

RSocket은 WebSocket 또는 TCP 위에서 전송으로도 지원됩니다. RSocket 서버가 구성되면 를 사용 하여 특정 경로에서 GraphQL 핸들러를 구성할 수 있습니다 spring.graphql.rsocket.mapping. 예를 들어 해당 매핑을 구성 "graphql"하면 RSocketGraphQlClient.

RSocketGraphQlClient.Builder<?>Spring Boot는 구성 요소에 삽입할 수 있는 빈을 자동으로 구성합니다 .

@Component
public class RSocketGraphQlClientExample {

    private final RSocketGraphQlClient graphQlClient;

    public RSocketGraphQlClientExample(RSocketGraphQlClient.Builder<?> builder) {
        this.graphQlClient = builder.tcp("example.spring.io", 8181).route("graphql").build();
    }
 

그런 다음 요청을 보냅니다.

Mono<Book> book = this.graphQlClient.document("{ bookById(id: \"book-1\"){ id name pageCount author } }")
    .retrieve("bookById")
    .toEntity(Book.class);
 

6.5. 예외 처리

Spring GraphQL을 사용하면 애플리케이션이 순차적으로 호출되는 하나 이상의 Spring DataFetcherExceptionResolver구성 요소를 등록할 수 있습니다. Exception은 객체 목록으로 해결되어야 합니다 graphql.GraphQLError. Spring GraphQL 예외 처리 문서를 참조하세요 . Spring Boot는 자동으로 DataFetcherExceptionResolver빈을 감지하고 GraphQlSource.Builder.

6.6. GraphiQL 및 스키마 프린터

Spring GraphQL은 GraphQL API를 사용하거나 개발할 때 개발자를 돕기 위한 인프라를 제공합니다.

Spring GraphQL은 기본적으로 노출되는 기본 GraphiQL"/graphiql" 페이지와 함께 제공됩니다 . 이 페이지는 기본적으로 비활성화되어 있으며 속성을 사용하여 켤 수 있습니다 spring.graphql.graphiql.enabled. 이러한 페이지를 노출하는 많은 애플리케이션은 사용자 정의 빌드를 선호합니다. 기본 구현은 개발 중에 매우 유용하므로 개발 중에 자동으로 노출됩니다 spring-boot-devtools.

/graphql/schema속성이 활성화될 때 텍스트 형식으로 GraphQL 스키마를 노출하도록 선택할 수도 있습니다 spring.graphql.schema.printer.enabled.

7. Spring HATEOAS

하이퍼미디어를 활용하는 RESTful API를 개발하는 경우 Spring Boot는 대부분의 애플리케이션에서 잘 작동하는 Spring HATEOAS에 대한 자동 구성을 제공합니다. 자동 구성은 (클라이언트 측 지원을 위한) 응답을 원하는 표현으로 올바르게 마샬링하도록 구성된 구성을 @EnableHypermediaSupport포함하여 하이퍼미디어 기반 애플리케이션을 쉽게 구축할 수 있도록 여러 빈을 사용하고 등록할 필요성을 대체합니다.  다양한 특성을 설정하거나 존재하는 경우 bean에 의해 사용자 정의됩니다.LinkDiscoverersObjectMapperObjectMapperspring.jackson.*Jackson2ObjectMapperBuilder

를 사용하여 Spring HATEOAS의 구성을 제어할 수 있습니다 @EnableHypermediaSupport. 이렇게 하면 ObjectMapper앞에서 설명한 사용자 지정이 비활성화됩니다.

  spring-boot-starter-hateoasSpring MVC에만 해당되며 Spring WebFlux와 결합해서는 안됩니다. org.springframework.hateoas:spring-hateoasSpring WebFlux와 함께 Spring HATEOAS를 사용하려면 spring-boot-starter-webflux.

8. 다음에 읽을 내용

이제 Spring Boot로 웹 애플리케이션을 개발하는 방법을 잘 이해하셨을 것입니다. 다음 몇 개의 섹션에서는 Spring Boot가 다양한 데이터 기술 , 메시징 시스템 및 기타 IO 기능과 어떻게 통합되는지 설명합니다. 애플리케이션의 필요에 따라 이들 중 하나를 선택할 수 있습니다.

 

출처

https://docs.spring.io/spring-boot/docs/current/reference/html/web.html

반응형