RESTful POST 메서드에서 매개 변수에 액세스하는 방법


123

내 POST 방법은 다음과 같습니다.

@POST
@Consumes({"application/json"})
@Path("create/")
public void create(String param1, String param2){
    System.out.println("param1 = " + param1);
    System.out.println("param2 = " + param2);
}

Netbeans에서 Jersey Client를 만들 때 post 메서드를 호출하는 메서드는 다음과 같습니다.

public void create(Object requestEntity){
    webResource.path("create").type(MediaType.APPLICATION_JSON).post(requestEntity);
}

이 테스트를 실행할 때 :

@Test
public void hello(){
    String json = "{param1=\"hello\",param2=\"hello2\"}";
    this.client.create(json);
}

서버에서 다음 출력을 제공합니다.

INFO: param1 = {param1="hello",param2="hello2"}
INFO: param2 = 

매개 변수가 올바른 값을 제공하려면 무엇을 변경해야합니까?


Android 애플리케이션에서 이것을 사용하고 있습니까?
Android-Droid 2011

마침내 안드로이드 앱에서이 post 메소드를 호출하고 싶습니다. 어떻게 든 웹 서비스는 매개 변수에 값을 서명하는 방법을 모릅니다. 어떻게하는지 알고 싶습니다.
Klaasvaak

답변:


356

귀하의 @POST방법 대신 문자열의 JSON 개체를 수용해야한다. Jersey는 JAXB를 사용하여 JSON 객체 마샬링 및 비 마샬링을 지원합니다 (자세한 내용 은 jersey 문서 참조 ). 다음과 같은 클래스를 만듭니다.

@XmlRootElement
public class MyJaxBean {
    @XmlElement public String param1;
    @XmlElement public String param2;
}

그러면 @POST방법은 다음과 같습니다.

@POST @Consumes("application/json")
@Path("/create")
public void create(final MyJaxBean input) {
    System.out.println("param1 = " + input.param1);
    System.out.println("param2 = " + input.param2);
}

이 메소드는 HTTP POST의 본문으로 JSON 오브젝트를 수신 할 것으로 예상합니다. JAX-RS는 HTTP 메시지의 내용 본문을 주석이없는 매개 변수 ( input이 경우)로 전달합니다. 실제 메시지는 다음과 같습니다.

POST /create HTTP/1.1
Content-Type: application/json
Content-Length: 35
Host: www.example.com

{"param1":"hello","param2":"world"}

이러한 방식으로 JSON을 사용하는 것은 명백한 이유로 매우 일반적입니다. 그러나 JavaScript가 아닌 다른 곳에서 생성하거나 소비하는 경우 데이터를 적절하게 이스케이프하도록주의해야합니다. JAX-RS에서는 이를 구현 하기 위해 MessageBodyReaderMessageBodyWriter 를 사용합니다. Jersey는 이미 필수 유형 (예 : Java primitives 및 JAXB 래핑 된 클래스)과 JSON에 대한 구현이 있다고 생각합니다. JAX-RS는 데이터 전달을위한 여러 다른 방법을 지원합니다. 간단한 인수 전달을 사용하여 데이터가 전달되기 때문에 새 클래스를 만들 필요가 없습니다.


HTML <FORM>

매개 변수는 @FormParam을 사용하여 주석이 추가됩니다 .

@POST
@Path("/create")
public void create(@FormParam("param1") String param1,
                   @FormParam("param2") String param2) {
    ...
}

브라우저는 "application / x-www-form-urlencoded"를 사용하여 양식을 인코딩합니다 . JAX-RS 런타임은 본문을 디코딩하고 메서드에 전달합니다. 다음은 유선에서 확인해야하는 내용입니다.

POST /create HTTP/1.1
Host: www.example.com
Content-Type: application/x-www-form-urlencoded;charset=UTF-8
Content-Length: 25

param1=hello&param2=world

이 경우 콘텐츠는 URL로 인코딩 됩니다.

FormParam의 이름을 모르는 경우 다음을 수행 할 수 있습니다.

@POST @Consumes("application/x-www-form-urlencoded")
@Path("/create")
public void create(final MultivaluedMap<String, String> formParams) {
    ...
}

HTTP 헤더

HTTP 헤더를 통해 매개 변수를 전달하려는 경우 @HeaderParam 주석을 사용할 수 있습니다 .

@POST
@Path("/create")
public void create(@HeaderParam("param1") String param1,
                   @HeaderParam("param2") String param2) {
    ...
}

HTTP 메시지는 다음과 같습니다. 이 POST에는 본문이 없습니다.

POST /create HTTP/1.1
Content-Length: 0
Host: www.example.com
param1: hello
param2: world

일반화 된 매개 변수 전달에는이 방법을 사용하지 않습니다. 하지만 특정 HTTP 헤더의 값에 액세스해야하는 경우 매우 편리합니다.


HTTP 쿼리 매개 변수

이 방법은 주로 HTTP GET과 함께 사용되지만 POST에도 동일하게 적용됩니다. @QueryParam 주석을 사용합니다 .

@POST
@Path("/create")
public void create(@QueryParam("param1") String param1,
                   @QueryParam("param2") String param2) {
    ...
}

이전 기술과 마찬가지로 쿼리 문자열을 통해 매개 변수를 전달하는 데 메시지 본문이 필요하지 않습니다. 다음은 HTTP 메시지입니다.

POST /create?param1=hello&param2=world HTTP/1.1
Content-Length: 0
Host: www.example.com

클라이언트 측에서 쿼리 매개 변수 를 적절하게 인코딩 하려면 특히주의해야 합니다. 쿼리 매개 변수를 사용하는 것은 일부 프록시에 의해 적용되는 URL 길이 제한 및 인코딩과 관련된 문제로 인해 문제가 될 수 있습니다.


HTTP 경로 매개 변수

경로 매개 변수는 HTTP 리소스 경로에 포함된다는 점을 제외하고 쿼리 매개 변수와 유사합니다. 이 방법은 오늘날 선호되는 것 같습니다. 경로가 실제로 HTTP 리소스를 정의하기 때문에 HTTP 캐싱과 관련하여 영향이 있습니다. @Path 주석이 수정되고 @PathParam 을 사용하므로 코드는 다른 코드와 약간 다릅니다 .

@POST
@Path("/create/{param1}/{param2}")
public void create(@PathParam("param1") String param1,
                   @PathParam("param2") String param2) {
    ...
}

메시지는 매개 변수 이름이 메시지에 포함되지 않는다는 점을 제외하면 쿼리 매개 변수 버전과 유사합니다.

POST /create/hello/world HTTP/1.1
Content-Length: 0
Host: www.example.com

이 방법은 쿼리 매개 변수 버전과 동일한 인코딩 문제를 공유합니다. 경로 세그먼트는 다르게 인코딩 되므로 여기에서도주의해야합니다.


보시다시피 각 방법에는 장단점이 있습니다. 선택은 일반적으로 고객이 결정합니다. FORM기반 HTML 페이지를 제공하는 경우 @FormParam. 클라이언트가 JavaScript + HTML5 기반 인 경우 JAXB 기반 직렬화 및 JSON 개체를 사용하고 싶을 것입니다. MessageBodyReader/Writer이 잘못 될 수있는 한 적은 것은 그래서 구현은 당신을 위해 탈출에 필요한의주의를 기울여야한다. 클라이언트가 Java 기반이지만 좋은 XML 프로세서 (예 : Android)가없는 경우 FORM콘텐츠 본문이 URL보다 적절하게 생성하고 인코딩하는 것이 더 쉽기 때문에 인코딩을 사용할 것입니다 . 이 미니 위키 항목이 JAX-RS가 지원하는 다양한 방법에 대한 정보를 제공하기를 바랍니다.

참고 : 전체 공개를 위해 실제로 Jersey의이 기능을 사용하지 않았습니다. 많은 JAXB + JAX-RS 애플리케이션이 배포되어 모바일 클라이언트 공간으로 이동하고 있기 때문에 우리는이 문제를 해결했습니다. JSON은 HTML5 또는 jQuery 기반 솔루션에서 XML보다 훨씬 더 적합합니다.


4
어제이 기능을 테스트했습니다. @XmlElement 주석이 필요하지
않았습니다

감사합니다. 그래도 2 개의 문자열을 보내고 싶다면 나머지는 무엇을 소비 할 수 있어야합니까? 아니면 여러 매개 변수가 @PathParm에서만 작동합니까?
Klaasvaak

1
@Klaasvaak-각 매개 변수를 추출 할 위치를 지정해야합니다. 지금 가지고있는 것처럼 Jersey / NetBeans는 양식 게시를 가정하고 FormParm으로 전송 된 데이터를 추출합니다. 데이터를 원하는 위치 (PathParam, FormParam, CookieParam 등)로 각 메소드 증가에 주석을 추가합니다.
Perception

1
@Klaasvaak-다양한 주석을 사용하여 여러 예제를 추가했습니다
D.Shawley 2011

2
정말 감사합니다! 이것이 제가 찾고 있던 것이 었습니다. 당신은 내 하루를 만들었습니다;) 지금 FormParams를 사용하고 있으며 작동합니다!
Klaasvaak 2011
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.