스프링 사이트(https://spring.io/)가 리모델링을 거쳤다.

전체적으로 깔끔해지고 카테고리가 정리되었다.

그와 함께 스프링 부트의 위상이 크게 격상되었다는 것도 보인다.

스프링 부트로 만들고

스프링 클라우드로 결합시키고

스프링 클라우드 데이터 플로우로 뭐든지 연결한다!? (아직 스프링 클라우드 데이터 플로우 쪽에는 가보지도 못했는데...)

말그대로 스프링 플랫폼을 위한 기반으로서 확고한 자리를 잡았다. 쉽게 개발하고 배포 및 운영이 용이하기 때문에 앞으로도 꾸준하게 사용자가 늘어날 것이다.

그런 의미에서!! 다음달 중에 나올 제 책을 꼭~ 봐주세요. ㅎㅎ


스프링 부트 2.0 정식 출시

스프링 부트 2.0 새로운 점:

  • A Java 8 baseline, and Java 9 support.
  • Reactive web programming support with Spring WebFlux/WebFlux.fn.
  • Auto-configuration and starter POMs for reactive Spring Data Cassandra, MongoDB, Couchbase and Redis.
  • Support for embedded Netty.
  • HTTP/2 for Tomcat, Undertow and Jetty.
  • A brand new actuator architecture, with support for Spring MVC, WebFlux and Jersey.
  • Micrometer based metrics with exporters for Atlas, Datadog, Ganglia, Graphite, Influx, JMX, New Relic, Prometheus, SignalFx, StatsD and Wavefront.
  • Quartz scheduler support.
  • Greatly simplified security auto-configuration.

정리

기다리고 기다리던 스프링 부트 2.0이 정식으로 출시되었다.

스프링 부트 2.0 출시에 맞춰서 쓰고 있는 책은 내일 교정본을 받고 최대한 빨리 출간할 예정이다.

스프링 부트 2.0에서 크게 달라진 점은 스프링 프레임워크 5를 기반으로 하여 리액티브 지원이 가장 큰 부분이라고 생각된다.

아직까지는 리액티브 웹 프로그래밍을 적극적으로 활용한 경험은 없는 상태라서 살펴봐야할 부분이 많다.

살펴볼 수 있다.

관심가는 변화 중 하나는 JDBC 라이브러리가 Tomcat JDBC에서 HikariCP 로 변경되었다.

기존에는 Tomcat JDBC를 제외(exclude)하고 HikariCP 의존성을 추가해야했지만 지금은 굳이 그럴 필요가 없어졌다.

그리고 운영과 관련된 액츄에이터(Actuator)에서 DropWizard에 맞춰 지원하던 형식이 Micrometer에서 쉽게 사용할 수 있도록 개편되었다. 더불어서 액츄에이터 기본경로에 /actuator가 접두사로 붙게 되었다.

그레이들 관련한 플러그인도 조금 더 개선이 될 것으로 보인다.

참고


스프링 시큐리티와 연계하여 로그인에 실패했을 경우 로그인화면으로 리다이렉트 시키면서 이메일을 다시 입력폼에 유지하려고 여러가지 시도를 해봤다.

스프링 시큐리티에서 로그인 실패를 담당하는 인터페이스는 AuthenticationFailureHandler 이다.

public interface AuthenticationFailureHandler {
 
/**
 * Called when an authentication attempt fails.
 * @param request the request during which the authentication attempt occurred.
 * @param response the response.
 * @param exception the exception which was thrown to reject the authentication
 * request.
 */
void onAuthenticationFailure(HttpServletRequest request,
HttpServletResponse response, AuthenticationException exception)
throws IOExceptionServletException;
}

위의 형태를 가지는 간단한 인터페이스로, 스프링 시큐리티 설정에서 formLogin() 에 설정하면 로그인이 실패했을 떄 호출되며 이에 대한 처리를 수행한다.

@Override
protected void configure(HttpSecurity http) throws Exception {
    http
        .anyRequest().authenticated()
        // form 로그인 
        .and()
        .formLogin()
        .loginPage("/login").permitAll()
        .usernameParameter(USERNAME_PARAMETER)
        .passwordParameter(PASSWORD_PARAMETER)
        .successHandler(authenticationSuccessHandler()) (1)
        .failureHandler(authenticationFailureHandler()) (2)
}
 
// 생략 
@Bean
AuthenticationSuccessHandler authenticationSuccessHandler() {
    return new HoneymonUserAuthenticationSuccessHandler();
}
 
@Bean
AuthenticationFailureHandler authenticationFailureHandler() {
    return new HoneymonUserAuthenticationFailureHandler();
}
로그인 성공시 후속처리
로그인 실패시 후속처리

그리고 HoneymonUserAuthenticationFailureHandler가 호출되면 /login?error={message}&email={email}의 형식으로 리다이렉트되도록 해뒀다. 그런데 암만 로그인 실패가 나도 /login?error= 로 리다이렉트 되지를 않는 것이다. 이 문제 떄문에 한참 씨름을 했다.

public class HoneymonUserAuthenticationFailureHandler implements AuthenticationFailureHandler {
 
    @Override
    public void onAuthenticationFailure(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOExceptionServletException {
        if(exception instanceof BadCredentialsException) {
            exception = new BadCredentialsException("security.exception.bad_credentials");
        }
        response.sendRedirect("/login?error=" + exception.getMessage() + "&email=" + request.getParameter(USERNAME_PARAMETER));
    }
}

옆에 누군가가 봐줬으면 참 좋았을텐데…​

그러다가 정말 우연찮게

'아, 내가 LoginWeb' 클래스를 지우고 ViewController 로 처리하도록 했지?

하는 생각이 미쳤다. 리다이렉트가 되지 않고 있는 url에 대해서는 다음과 같이 설정되어 있었다.

@Configuration
public class WebConfig  extends WebMvcConfigurerAdapter {
  @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("front/login");  // 로그인 
        registry.addViewController("/signup").setViewName("front/signup");  // 회원가입 
    }
}

이 간단한 설정이 나를 괴롭혔던 주 원인이었다.

ViewController 에서 /login 요청에 대한 처리를 수행하기는 하지만 뒤에 전달되는 파라미터들을 모두 소거시킨다는 것을 이해하지 못한 것이다.

어떤 장애든지 기본적인 접근은 그 장애에 영향을 주는 설정부터 살펴보도록 하자. ㅡ_-);; 내가 허비한 시간 우짤꺼야!!

This is a shortcut for defining a ParameterizableViewController that immediately forwards to a view when invoked. Use it in static cases when there is no Java controller logic to execute before the view generates the response.



현재 스프링부트 1.3.1 버전으로 해서

spring-webmvc-4.2.4.RELEASE

버전을 사용중인데,

윈도우와 리눅스에서 결과가 미묘하게 다르다?

윈도우에서는 컨트롤러에서 발생한 NullPointException을 @ControllerAdvice 컴포넌트서 잡질 못하고 그대로 NullPointException을 뱉었고

리눅스에서는 컨트롤러에서 발생한 NullPointException을 @ControllerAdvice 컴포넌트에서 잡아서 변환처리를 해줬다.

+ Recent posts