You will be fine

<Spring> DeviceUtils.getCurrentDevice Null 이슈

by BFine
반응형

가. Spring Boot 디바이스 확인 

 a. 디바이스 감지하기

  -  웹어플리케션에서 request가 어떤 디바이스에서 왔는지 확인하여 처리를 다르게 해주어야 할 경우가 있다.

  -  이때 spring-mobile-device 의 라이브러리를 사용하면 간단하게 확인이 가능하다.

  -  간단하게 DeviceUtils.getCurrentDevice의 메서드를 활용하여 모바일,테블릿,기타(PC)를 확인할 수 있다.

 

나. 이슈사항

 a.  getCurrentDevice null 

  -  간단하게 의존성을 추가하고 사용하려고 했더니 DeviceUtils.getCurrentDevice 리턴값이 null이 나온다...

  -  나는 이 오류를 Spring Boot 버전을 올리는 작업을 하다가 발견을 했다.  => 기존 branch를 테스트했을때는 전혀 문제가 없었었다.

  -  처음에는 단순히 라이브러리 버전만 올리면 되겠지? 하면서 라이브러리 버전을 올렸지만 해결되지 않았다.

  -  그래서 원인이 무엇일까 하면서 라이브러리 내부를 하나하나 뒤져보았다. 

 

 b.  원인

  -  원인은 Spring Boot 2.x 버전에서 이 라이브러리를 그대로 사용하면 해당 오류가 발생한다. 이유가 뭘까?

  -  먼저 1.5 버전의 dependency를 살펴보면 autoconfigure.mobile에서 Device 관련 부분이 보인다.

  -  DeviceResolverAutoConfiguration 살펴보면 WebMvcConfiguerAdapter 상속해 인터셉터를 추가하고 있다.

  -  즉 autoconfigure를 통해 자동으로 HttpServletRequest에 대한 처리가 되고 있는 것이다.

 c. Spring Boot 2.x 에서 확인해보자

  -  gradle에서 Spring Boot 버전을 2.0.0으로 올리고 autoconfigure의 내부를 살펴 보자

  -  엇.. mobile 패키지가 사라졌다. Spring Boot 2가 되면서 Deprecated 되어버린것 이다.! 

  -  즉 HttpServletRequest에 대해서 인터셉터해서 currentDevice를 적용하는 부분이 빠져버린것이다.!

다. 해결하기

 a. 사용하는 메서드에서 처리하기

  -  추천하지 않는 방식이다. 그래도 메서드가 어떻게 쓰이는지 보여주기 때문에 한번 확인하면 좋은 것 같다.

@RestController
public class HelloController {



    @GetMapping("/")
    public void test(HttpServletRequest request){

        Device device = new LiteDeviceResolver().resolveDevice(request);

        request.setAttribute(DeviceUtils.CURRENT_DEVICE_ATTRIBUTE,device);

        Device currentDevice = DeviceUtils.getCurrentDevice(request);

        currentDevice.isMobile();

    }

}

 

 b. 인터셉터 추가하기 

  -   위처럼 할경우 만약에 여러군데일 경우 저 코드가 중복해서 사용되어 질 것 이다.

       => 물론 코드가 2줄밖에 안되긴 하지만 중복코드는 최대한 줄여주자!

  -  autoconfig.mobile 에서 해준 것 처럼 addInterceptor에 추가만 해주면 간단하게 된다.

@Configuration
public class WebConfig implements WebMvcConfigurer {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(new DeviceResolverHandlerInterceptor());
    }
}

null 오류없이 처리

 c. 정리

  -  작은 범위에서만 확인하다보니 라이브러리 내부에서만 디버깅해서 어디서 문제가 되는것지 판단하기 어려웠다.

  -  버전을 업데이트 하거나 라이브러리 사용할때 호환성 뿐만 아니라 Deprecated 영향이 있는지도 확인해보자!

반응형

블로그의 정보

57개월 BackEnd

BFine

활동하기