티스토리 뷰

1. 현상 

Migration 작업 내용 

  • springboot 버전을 1.5.9에서 최근에 2.1.1로 업그레이드 시켰습니다. 
  • URI Pathvariable 값을 파라미터로 전달되는 값보다 우선으로 바인딩 되게 Configuration을 수정했습니다. 

스프링부트 업그레이드 작업이 잘되었다고 생각하고 다른 업무들을 보고 있는데 연락이 왔습니다. 

"매장 정보 수정을 하면 계속 에러가 납니다."

확인을 해보니 바인딩 객체에 값이 모두 null로 나옵니다. 

순간적으로 얼마전에 작업한 "Pathvariable 값에 우선 순위 주는 로직에 문제가 있나?"라는 생각이 들었습니다. 

소스를 원래 소스로 고치고 다시 테스트를 해보았지만 결과는 변하지 않았습니다. 

Configuration 중에 2.1.1로 바뀌면서 WebMvcConfigurationSupport로 변경한 부분이 있는데 이쪽도 의심이 들고 제가 모르는 설정이 있나 싶어서 열심히 구글링을 했지만 원하는 답을 얻을 수 없었습니다. 

Post로 전송하면 잘 작동합니다. 


그래서 PutMapping 관련해서 테스트 할 수 있는 데모 프로젝트를 생성하고 테스트해보기로 했습니다. 

간단하게 만들고 Postman을 이용해서 실행해 봤는데 결과는 잘 나옵니다. 


스프링부트 문제가 아닌가???


혹시나 싶어서 sample html을 만들어서 실행을 했는데 값이 전달이 안됩니다. 

구글링하면서 삽질을 하다가 다시 이전 버전으로 프로젝트를 생성해서 확인을 해 봤습니다. 


어라 spring boot 1.5.9에서는 아무런 문제가 없습니다. 


다시 postman에서 요청을 던지고 request를 비교해 봤습니다. 

postman에서는 put 메소드로 전송시 multipart로 던지는 걸 보고 contentType을 수정을 해보며 삽질을 하다 겨우 해결을 했습니다. 


불과 2~3시간이었지만 임시로라도 Post로 전환하고 원인을 찾을까 고민했습니다. 

다행히 오픈한지 얼마 안되서 아직 사용을 많이 하지 않나 봅니다. 차분히 원인을 찾아서 수정할 수 있었습니다. 

공통 javascript 부분만 수정을 했는데 만약 여기 저기 다 각자 쓰고 있었으면 수정할 엄두도 못 했을 거 같습니다. 


해결은 Request 보면서 삽질로 찾았지만 정확한 원인과 해결안은 여전히 알지 못합니다. 


샘플 자바 컨트롤러입니다. 

1
2
3
4
5
6
7
8
9
10
11
@RestController
@Slf4j
public class UserAuthRestController { 
 
    @PutMapping("/api/users/{userId}")
    public ResponseMessage modifyUser(User user) {
        ResponseMessage message = new ResponseMessage(HttpStatus.OK);
        message.add("user", user);
        return message;
    }
}
cs

특별한 내용은 없고 @PutMapping을 이용해서 데이터를 바인딩한 후 다시 화면에 반환한다. 

아래는 테스트 한 내용들입니다. 

2. Postman 테스트

문제 해결을 위해 동일 버전으로 프로젝트 생성 후 테스트 

정상적으로 잘 되는 것 확인. 


Postman 전송시 Request 정보. Content-Type을 잘 보셔야 합니다.  


3. html 전송 테스트 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
    var doUrlProcess = function(){
        var formData = {
                "name" : "kkaok",
                "authType" : "web"
        }
            
        $.ajax({
            type : "put",
            url : "/api/users/1234",
            data : formData,
            success : function(result) {
                //alert("OK");
            },
        })
    }
cs


Postman으로 잘 작동되던 것이 html에서 ajax로 호출 하면 데이터가 전달이 안됩니다.  

{"code":200,"message":"OK","user":{"userId":"1234","userPwd":null,"name":null,"authType":null},"status":true}



postman과 비교시 Content-Type만 다릅니다. 

4. springboot 1.5.9 버전에서 테스트 


{"code":200,"message":"OK","user":{"userId":"1234","userPwd":null,"name":"name","authType":"web"},"status":true}

정상적으로 잘 작동합니다. 


 Content-Type이 기본값이지만 아무런 문제가 없습니다. 

5. 해결안 

FormData를 이용해서 값을 전달하고 contentType, procssData를 false로 설정합니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
    var doUrlProcess = function(){
        var formData = new FormData();
        formData.append("name""kkaok");
        formData.append("authType""web");
        
        $.ajax({
            type : "put",
            url : "/api/users/1234",
            data : formData,
            contentType:false,
            processData:false,
            success : function(result) {
                //alert("OK");
            },
        })
    }
cs


정상확인 

{"code":200,"message":"OK","user":{"userId":"1234","userPwd":null,"name":"kkaok","authType":"web"},"status":true}



식은 땀이 흐르는 하루였지만 잘 마무리할 수 있게 되어 다행입니다. 


Github 링크 : https://github.com/kkaok/examples

댓글
댓글쓰기 폼