org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present




아주 희안한 버그였다 


//Servlet 2. x 에서 사용하는 설정

@Bean

public MultipartResolver multpartResolver() {


CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();


multipartResolver.setMaxUploadSize(1024*1024*100L);

multipartResolver.setMaxInMemorySize(1024*1024*40L);


return multipartResolver;

}




스프링 MultipartFile 로 파일 받아오는 api를 짜고있는데 


PostMan 으로 테스트 해보니  확장자 .mp3  파일은  성공적으로 받아지는데


그 이외의 확장자들은 전부 BadRequest 


org.springframework.web.bind.MissingServletRequestParameterException: Required MultipartFile parameter 'file' is not present
 


이렇게 에러코드 400을 뱉는 것이였다.

(이게 원래는 전부 안되야 되는데 .mp3 확장자만 되는 것은 무엇????)



아 이거 Spring In Action 에서 봤던 내용이였는데 


이걸 읽어놓고 까먹어서 구글링하고 있다



스프링 부트는 1.2.x 버젼 이상에서는 기본적으로 Servlet 3.x 을 사용한다


 서블릿 3.x 이상 스펙에서는  multipartResolver를 외부 라이브러리 없이 


쓸수있게 자체 구현되어있는데 


스프링에서 Servlet 2.x 와 3.x 에서 다르게 구현체를 만들어놓았음



  • Servlet 3.0 Part API를 바탕으로 한 MultipartResolver 인터페이스 구현체
  • bean 을 선언할 때 별다른 확장설정을 하지 않고 “multipartResolver”로 선언
  • multipart와 관련된 업로드 파일 최대크기, 저장위치 등 설정을 하고 싶다면
    • web.xml에서 하거나
    • Servlet 등록하는 과정에서 MultipartConfigElement을 선언하면서 설정
    • @MultipartConfig라는 애노테이션 사용
  • Servlet 3.0 에서는 MultipartResolver 레벨에서 설정하는 것을 허용치 않는다.


  • 출처: http://java.ihoney.pe.kr/351 [허니몬(Honeymon)의 자바guru]




    //Servlet 3 이상 버젼에서의 설정 

    @Bean

    public MultipartConfigElement multipartConfigElement() {

        MultipartConfigFactory factory = new MultipartConfigFactory();


        factory.setMaxFileSize(MAX_UPLOAD_FILE_SIZE);

        factory.setMaxRequestSize(MAX_REQUEST_SIZE);

        factory.setFileSizeThreshold(FILE_SIZE_THREADHOLD);

        


        return factory.createMultipartConfig();

    }


    @Bean

    public MultipartResolver multipartResolver() {

        return new StandardServletMultipartResolver();

    }

















    해결 방법 참고 url


    https://www.cameronezell.com/failed-to-start-service-unit-service-not-found/





    스프링 부트 jar 파일을 Aws에 배포하려고 


    서비스 등록을 하려고 스크립트 파일을 짜서 올렸는데 


    Failed to start service: Unit service not found 


    계속해서 서비스 파일이 등록안되고 찾을수 없다고 에러가 떳다





    원인은 이거다 


     It turns out that between the LTS versions of Ubuntu, Canonical decided that 15.04 would be the start of a transition from upstart to systemd as the default for managing boot and system service startup.


    Ubuntu의 LTS 버전 사이에서 Canonical은 부팅 및 시스템 서비스 시작 관리를위한 기본값으로 15.04가 upstart에서 systemd 로의 전환의 시작이라고 결정했다.






    우분투 14 에서 16으로 버전이 올라가는 과정에서 무언가가 있던게 사라진듯 싶다...



    해결법


    1. sudo apt-get install upstart-sysv

    2. sudo update-initramfs -u



    명령어 두번으로 15버젼에서 패치된 내용을 이렇게 적용 줄수있다 
















    뭔가 억울한데 어디 하소연할수도 없고 진짜 하...


    아니.... 



    Retrofit2 로 구글API에서  자바빈으로 안받고  Json객체로 받으려고 


    @GET("maps/api/place/textsearch/json")
    Call<JSONObject> findDestinationWithRadius(@Query("query")String searchKeyword);


    이렇게 줬는데 계속해서 response.body()가 null이 들어오는 것이다..


    아니 이게 파싱이 안되면 익셉션이라도 떠야되는데 


    계속해서 null이 뜨길래 무슨 문제인지 계속 고민하다가 


    하필이면 비동기 통신이라서 동시성문제 인가 싶어서 Thread.sleep으로 일부로 지연시켜보고 별 짓을 다했는데 




    원인은 이거다




    JSONObject => org.json.JSONObject  객체이고


    JsonObject -> com.google.gson.JsonObject 객체이다 



    레트로핏2 빌드할때 GsonConverter를 줬는데 

    Retrofit retrofit=new Retrofit.Builder()
    .addConverterFactory(GsonConverterFactory.create())
    .client(client)
    .baseUrl(BASE_URI)
    .build();



    파싱 반환값음 org.json의 객체인 JSONObject로 반환 받으니까 


    익셉션이 안뜨고 그냥 null로 비워버리는 문제가 발생했다

    (이거 버그 같은데?)



    반환 값을 JsonObject로 바꾸니까 정상적으로 파싱되었다 



    아 진짜 나도 사수가 있었으면 좋겠다 

    무의미한 오타찾기 삽질기간을 줄이고 싶은데 항상 누구하나 물어볼사람은 없고...



    공부는 항상 외롭다.











    405 Get was not supported 


    Swagger2  json으로 문서화 하는건 되는데 


    Swagger-ui.html 으로 접속하려하면 405 Get not supported   가 뜬다


     


    처음에는 스프링 시큐리티 문제인지 알았다. 


    결론 : 정확한 원인은 알수가 없지만  


    스프링 부트 버젼을 1.5.6 으로 올리고 (이건 별 상관 없는듯 싶다)


    내가  해결한 방법은


    thymeleaf 을 활성화 해준 것 이다 . @Controller 하나 따로 파서 


    HelloWorld.html 을 하나 만들어서 thymeleaf 를 활성화 시켜주니 


    Swagger-ui 가  제대로 돌아갔다.


    그 중간과정에 


    버젼 변경이라던지 이것저것 매우 삽질을 했지만 문제는 이것인 것 같다.

    (참고로 최종적으로 적용한 버젼은 2..7.0이다 )








    + Recent posts