복붙노트

[SPRING] Spring 4.x / 3.x (Web MVC) REST API 및 JSON2 Post 요청은 모든 요청을 한 번 올바르게 가져 오는 방법을 알려줍니다.

SPRING

Spring 4.x / 3.x (Web MVC) REST API 및 JSON2 Post 요청은 모든 요청을 한 번 올바르게 가져 오는 방법을 알려줍니다.

세부 사항으로 가기 전에, Stackoverflow에 관한 많은 대화와 관련 질문이 있다는 것을 알고 있습니다. 그들 모두가 다른 방식으로 저를 도와 주므로 제 연구 결과를 요약 한 단일 자주 묻는 질문으로 모든 결론을 정리했다고 생각했습니다.

확실히 이것들에 대해 알고 있지만, 나는 단지 그것들을 빠른 리뷰로 적는다. 내가 뭔가를 놓친 경우에 대비하여 편집하십시오.

게시물 요청은 웹 서비스 나 서버 측 응용 프로그램으로 개체를 보내려고 할 때 사용됩니다.

웹 브라우저에서 서버 측 응용 프로그램으로 객체를 가져 오는 프로세스입니다. jQuery Ajax 호출 또는 컬 포스트 요청을 사용할 수있다.

가장 인기있는 논문은 JSON과 XML입니다. 직렬화 된 XML 객체가 XML 태깅의 특성으로 인해 상대적으로 크기가 커짐에 따라 XML은 덜 인기가 있습니다. 이 FAQ에서 주요 초점은 JSON2 직렬화입니다.

Spring 프레임 워크와 강력한 주석은 웹 서비스를 효율적으로 노출 할 수있게 해준다. Spring에는 여러 라이브러리가 있습니다. 우리의 초점은 Spring Web MVC입니다.

이들은 클라이언트 측에서 게시물 요청을하는 데 사용할 수있는 도구입니다. JQuery ajax 호출을 사용하려는 경우에도 게시 요청을 한 후에 자세한 응답을 제공하므로 디버깅 용도로 Curl을 사용하는 것이 좋습니다.

Java EE 모델에 의존하지 않는 웹 서비스가있는 경우 @RequestBody를 사용해야합니다. 모델을 사용하고 JSON 객체가 모델에 추가되면 @ModelAttribute를 통해 객체에 액세스 할 수 있습니다. 요청이 GET 요청이거나 GET 및 POST 요청 조합 인 경우에만 @ RequestParam / @ PathVariable을 사용해야합니다.

이름에서 알 수 있듯이 서버 측 메소드가 요청을 처리 한 후 클라이언트에게 응답을 보내는 경우 @ResponseBody 만 필요합니다.

RequestMappingHandlerAdapter는 Spring 3.1 이후 AnnotationMethodHandlerAdapter를 대체 한 Spring 프레임 워크를위한 새로운 매핑 핸들러이다. 기존 구성이 AnnotationMethodHandlerAdapter에있는 경우이 게시물이 유용 할 수 있습니다. 내 게시물에 제공된 설정은 RequestMappingHandlerAdapter를 설정하는 방법에 대한 아이디어를 제공합니다.

메시지 변환기를 설정해야합니다. 직렬화 된 JSON 메시지 본문을 서버 측에서 로컬 Java 객체로 변환하는 방법입니다.

여기에서 기본 구성을 선택하십시오. 변환기는 MarshallingHttpMessageConverter와 CastorMarshaller를 기본 구성 샘플로 사용하여 MappingJackson2HttpMessageConverter 및 MappingJacksonHttpMessageConverter로 대체했습니다.

내 프로젝트가 설정되는 방식으로 두 개의 config 파일이 있습니다.

hadlerAdapter bean은 나중에 MVC Dispatcher XML 파일에 있어야합니다.

<bean name="handlerAdapter"
class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
    <property name="messageConverters">
        <list>
            <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
            <ref bean="jsonConverter"/>

        </list>

    </property>
    <property name="requireSession" value="false"/>

</bean>
<bean id="jsonConverter" class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
    <property name="supportedMediaTypes" value="application/json"/>
</bean>

여러 메시지 변환기를 가질 수 있습니다. 여기서는 일반 JSON과 JSON 2 메시지 변환기를 만들었습니다. XML 파일의 Ref와 Normal Bean 형식이 모두 사용되었습니다 (개인적으로 저는 ref 태그를 선호하지 않습니다).

다음은 REST API를 노출하는 샘플 컨트롤러입니다.

여기에서 HTTP POST 요청에 대한 REST API가 노출됩니다.

@Component
@Controller
@RequestMapping("/api/user")
public class UserController {
@RequestMapping(value = "/add", method = RequestMethod.POST, consumes = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public String insertUser(@RequestBody final User user) {
    System.out.println(user.toString());
    userService.insertUser(user);
    String userAdded = "User-> {" + user.toString() + "} is added";
    System.out.println(userAdded);
        return userAdded;
    }
}
@JsonAutoDetect
public class User {

private int id;
private String username;
private String name;
private String lastName;
private String email;

public int getId() {
    return externalId;
}

public void setId(final int id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(final String name) {
    this.name = name;
}

public String getEmail() {
    return email;
}

public void setEmail(final String email) {
    this.email = email;
}
public String getUsername() {
    return username;
}

public void setUsername(final String username) {
    this.username = username;
}

public String getLastName() {
    return lastName;
}

public void setLastName(final String lastName) {
    this.lastName = lastName;
}

@Override
public String toString() {
    return this.getName() + " | " + this.getLastName()  + " | " + this.getEmail()
            + " | " + this.getUsername()  + " | " + this.getId()  + " | ";
    }

}
curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add

다음 게시물 및 질문을 제공 한 모든 사람들에게 해당되지 않는 경우이 FAQ를 사용할 수 없습니다 (유용한 게시물 / 질문과 관련하여이 목록이 확장됩니다).

해결법

  1. ==============================

    1.

    curl -i -H "Content-Type: application/json" -X POST -d '{"id":100,"username":"JohnBlog","name":"John","lastName":"Blog","email":"JohnBlog@user.com"}' http://localhost:8080/[YOURWEBAPP]/api/user/add
    

    여기서 나는 말장난을 한 다음에 무엇이 잘못되었을 지 모르는 여러 가지 오류를 살펴 봅니다.

    HTTP/1.1 404 Not Found
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 949
    Date: Tue, 04 Jun 2013 02:59:35 GMT
    

    이는 REST API가 제공 한 URL에 존재하지 않는다는 것을 의미합니다.

    모든 것이 완벽하게 올바르게 수행되고 구성이나 URL에 문제가 없는지 확인한 후에는 다음을 수행하십시오. - Maven clean을 실행하십시오. - 웹 앱 배포를 취소하거나 단순히 삭제하십시오. - 웹 앱 재배포 - 당신의 maven / gradle에서 Spring 버전을 하나만 사용하도록하십시오.

    HTTP/1.1 400 Bad Request
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 968
    Date: Tue, 04 Jun 2013 03:08:05 GMT
    Connection: close
    

    이것의 유일한 이유는 요청이 올바르게 형식화되어 있지 않다는 사실입니다. 자세한 컬 응답을 체크 아웃하면 "클라이언트가 보낸 요청이 구문 상 올바르지 않습니다."라는 메시지가 나타납니다.

    JSON 형식이 올바르지 않거나 JAVA 객체의 필수 매개 변수가 누락되었습니다.

    올바른 형식 및 올바른 수의 매개 변수로 JSON 객체를 제공했는지 확인하십시오. Nullable 속성은 필수는 아니지만 모든 NotNullable 속성에 데이터를 제공해야합니다. Spring이 자바 리플렉션을 사용하여 JSON 파일을 Java 객체로 변환한다는 것을 기억하는 것이 중요합니다. 이는 무엇을 의미합니까? 그것은 변수와 메소드 이름이 CasE SensItiVe라는 것을 의미합니다. JSON 파일이 변수 "userName"을 보내는 경우 Java 객체의 일치하는 변수도 "userName"으로 지정해야합니다. getter와 setter가있는 경우에도 동일한 규칙을 따라야합니다. 이전 예제와 일치하도록 getUserName 및 setUserName.

    HTTP/1.1 415 Unsupported Media Type
    Server: Apache-Coyote/1.1
    Content-Type: text/html;charset=utf-8
    Content-Length: 1051
    Date: Wed, 24 Aug 2011 08:50:17 GMT
    

    Json 미디어 유형은 웹 서비스에서 지원되지 않습니다. 이것은 주석이 미디어 유형을 지정하지 않았거나 컬링 포스트 명령에서 미디어 유형을 지정하지 않았기 때문일 수 있습니다.

    메시지 변환기가 올바르게 설정되어 있는지 확인하고 웹 서비스 주석이 위의 예와 일치하는지 확인하십시오. 위 사항이 좋으면 Curl 게시 요청에서 content-type을 지정하십시오.

    json 미디어 유형은 웹 서비스에서 지원되지 않습니다.

    HTTP/1.1 200 OK 
    Server: Apache-Coyote/1.1 
    Content-Type: application/json;charset=UTF-8 
    Transfer-Encoding: chunked 
    Date: Tue, 04 Jun 2013 03:06:16 GMT 
    

    사용자가 실제로 서버 측 REST API로 보내 주신 것을 축하합니다.

    봄 체크 아웃을 설정하는 방법에 대한 자세한 내용은 spring mvc guide를 참조하십시오.

    다음 게시물 및 질문을 제공 한 모든 사람들에게 해당되지 않는 경우이 FAQ를 사용할 수 없습니다 (유용한 게시물 / 질문과 관련하여이 목록이 확장됩니다).

  2. ==============================

    2.bean 클래스가 하나의 필드에 2 개 이상의 setter를 가지고 있고 옵션 필드에 @JsonIgnore가 없으면 bean 클래스를 처리 할 수 ​​없음을 알아두면 좋습니다. Spring / Jackson이 HttpMediaTypeNotSupportedException 및 http 상태 415 Unsupported Media Type을 반환합니다.

    bean 클래스가 하나의 필드에 2 개 이상의 setter를 가지고 있고 옵션 필드에 @JsonIgnore가 없으면 bean 클래스를 처리 할 수 ​​없음을 알아두면 좋습니다. Spring / Jackson이 HttpMediaTypeNotSupportedException 및 http 상태 415 Unsupported Media Type을 반환합니다.

    예 :

    @JsonGetter
    public String getStatus() {
        return this.status;
    }
    
    @JsonSetter
    public void setStatus(String status) {
        this.status = status;
    }
    
    @JsonIgnore
    public void setStatus(StatusEnum status) {
        if (status == null) {
            throw new NullPointerException();
        }
    
        this.status = status.toString();
    }
    

    업데이트 : 이 경우 @JsonGetter 및 @JsonSetter도 지정해야하며 반환 유형으로 사용할 때 문제가 발생하지 않아야합니다.

    방금 Spring 3.2.2와 Jackson 2.2로 테스트했습니다. 매개 변수 (@RequestBody) 및 / 또는 반환 형식 (@ResponseBody)으로 잘 작동합니다.

    업데이트 2 :

    @JsonGetter 및 @JsonSetter를 지정하면 @JsonIgnore가 필요하지 않은 것처럼 보입니다.

  3. from https://stackoverflow.com/questions/16909742/spring-4-x-3-x-web-mvc-rest-api-and-json2-post-requests-how-to-get-it-right-o by cc-by-sa and MIT license