web-dev-qa-db-ja.com

Spring 4.x / 3.x(Web MVC)REST APIおよびJSON2 Postリクエスト、すべてを一度正しく行う方法は?

詳細に入る前に、Stackoverflowで多くの会話と関連する質問があったことを知っています。それらはすべてさまざまな方法で私を助けてくれるので、私の調査結果を単一の組織化されたFAQとしてまとめて、調査結果をまとめると思いました。

関連概念

きっとあなたはこれらについて知っていますが、私はそれらを簡単なレビューとして書いています。何かが足りない場合は、自由に編集してください。

HTTP POSTリクエスト:

ポストリクエストは、Webサービスまたはサーバー側アプリケーションにオブジェクトを送信する場合に使用されます。

シリアル化:

Webブラウザーからサーバー側アプリケーションにオブジェクトを取得するプロセスです。 jQuery Ajax呼び出しまたはCurl投稿リクエストを使用できます。

シリアル化プロトコル:

最近最も人気のあるものはJSONとXMLです。 XMLタグ付けの性質により、シリアル化されたxmlオブジェクトのサイズが比較的大きいため、XMLの人気は低下しています。これでFAQ主な焦点は JSON2 シリアル化です。

春:

Springフレームワークとその強力な注釈により、Webサービスを効率的な方法で公開できます。 Springにはさまざまなライブラリがあります。ここでの焦点は Spring web MVC です。

Curl vs JQuery:

これらは、クライアント側で投稿リクエストを行うために使用できるツールです。 JQuery ajax呼び出しを使用する予定がある場合でも、Curlを使用してデバッグを行うことをお勧めします。Curlを使用すると、送信リクエスト後に詳細な応答が得られるためです。

@RequestBody vs @ RequestParam/@ PathVariable vs @ModelAttribute:

Java EEモデルに依存しないWebサービスがある場合、@ RequestBodyを使用する必要があります。モデルを使用しており、JSONオブジェクトがモデルに追加される場合、リクエストがGETリクエストまたはGETであり、POSTリクエストの組み合わせである場合のみ、@ RequestParam/@ PathVariableを使用する必要があります。

@RequestBody vs @ResposeBody:

名前からわかるように、サーバー側のメソッドがリクエストを処理した後にクライアントにレスポンスを送信する場合、@ ResponseBodyのみが必要です。

RequestMappingHandlerAdapter対AnnotationMethodHandlerAdapter:

RequestMappingHandlerAdapterは、Spring 3.1以降AnnotationMethodHandlerAdapterに代わるSpringフレームワークの新しいマッピングハンドラーです。既存の構成がまだAnnotationMethodHandlerAdapterにある場合、この投稿が役立つことがあります。私の投稿で提供されている構成は、RequestMappingHandlerAdapterのセットアップ方法に関するアイデアを提供します。

セットアップ

メッセージコンバーターをセットアップする必要があります。これは、シリアル化されたJSONメッセージ本文がサーバー側でローカルJavaオブジェクトに変換される方法です。

here からの基本設定。コンバーターは 基本構成サンプル ではMarshallingHttpMessageConverterとCastorMarshallerでしたが、MappingJackson2HttpMessageConverterとMappingJacksonHttpMessageConverterに置き換えました。

構成を配置する場所

プロジェクトのセットアップ方法には、2つの構成ファイルがあります。

  • アプリケーションコンテキストXML:セッションファクトリBean、dataSource Beanなどが配置されているアプリケーションコンテキストXMLファイル。
  • MVCディスパッチャーサーブレットXML:ここにビューリゾルバーBeanがあり、アプリケーションコンテキストXMLをインポートします。

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と通常のBeanの両方の形式が使用されています(個人的にはrefタグをより適切なものとして使用しています)。

REST API

REST APIを公開しているサンプルコントローラーを次に示します。

コントローラー

REST HTTPポストリクエストの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;
    }
}

Javaオブジェクト

@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ポストコール

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

関連する投稿と質問

このFAQは、以下の投稿や質問を提供したすべての人に向けられていなかった場合、不可能でした(有用な関連する投稿/質問に出会った場合、このリストは拡大します):

  1. correctJSONコンテンツタイプとは
  2. Spring 3.0はjacksonメッセージコンバーターを使用してJSON応答を行う
  3. How to POST JSONデータをCurlでターミナル/コマンドラインからSpring RESTをテストするには?
  4. JSONをREST API に投稿)
  5. https://github.com/geowarin/spring-mvc-examples
  6. JSONをPHP with curl =に投稿する方法)==
  7. 春REST | MappingJacksonHttpMessageConverterは無効なJSONを生成します
  8. https://github.com/eugenp/REST
  9. Spring Web MVC-個々のリクエストパラメーターを検証する
  10. How to POST JSONデータをCurlでターミナル/コマンドラインからSpring RESTをテストするには?
  11. Java Servlet からJSONオブジェクトをどのように返しますか
  12. JSONがREST API? によって返される場合、どのMIMEタイプか
42
AmirHd

CURLポストコール

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

さまざまなエラーシナリオ:

ここでは、curl呼び出しを行った後に遭遇する可能性のあるさまざまなエラーと、問題が発生した可能性のある原因について説明します。

シナリオ1:

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をクリーンに実行します。 -Webアプリをアンデプロイするか、単に削除します。 -Webアプリを再デプロイします-Maven/Gradleで必ず1つのバージョンのSpringのみを使用してください

シナリオ2:

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

この背後にある唯一の理由は、リクエストが正しくフォーマットされていないという事実です。詳細なcurlレスポンスをチェックアウトすると、「クライアントから送信されたリクエストが構文的に正しくありませんでした」と表示されるはずです。

JSON形式が正しくないか、Javaオブジェクトの必須パラメーターが欠落しています。

JSONオブジェクトを正しい形式で、適切な数のパラメーターで指定してください。 Nullableプロパティは必須ではありませんが、すべてのNotNullableプロパティにデータを提供する必要があります。 SpringがJavaリフレクションを使用してJSONファイルをJavaオブジェクトに変換します。これはどういう意味ですか?変数とメソッドを意味しますか?名前はCasE SensItiVeです。JSONファイルが変数「userName」を送信している場合、Javaオブジェクト内の一致する変数も「userName」と命名する必要があります。ゲッターとセッターがある場合、それらは前の例と一致するように、getUserNameとsetUserNameも同じルールに従う必要があります。

セナリオ3:

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メディアタイプは、Webサービスでサポートされていません。これは、注釈がメディアタイプを指定していないか、Curl postコマンドでメディアタイプを指定していないことが原因である可能性があります。

メッセージコンバーターが正しく設定されていることを確認し、Webサービスアノテーションが上記の例と一致することを確認してください。これらが問題ない場合は、Curl投稿リクエストでコンテンツタイプを指定してください。

Jsonメディアタイプは、Webサービスでサポートされていません。

セナリオN(!):

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。

スプリングチェックアウトの設定方法の詳細については、スプリングmvcガイドを参照してください。

関連する投稿と質問

このFAQは、以下の投稿や質問を提供したすべての人に向けられていなかった場合、不可能でした(有用な関連する投稿/質問に出会った場合、このリストは拡大します):

  1. correctJSONコンテンツタイプとは
  2. Spring 3.0はjacksonメッセージコンバーターを使用してJSON応答を行う
  3. How to POST JSONデータをCurlでターミナル/コマンドラインからSpring RESTをテストするには?
  4. JSONをREST API に投稿)
  5. https://github.com/geowarin/spring-mvc-examples
  6. JSONをPHP with curl =に投稿する方法)==
  7. 春REST | MappingJacksonHttpMessageConverterは無効なJSONを生成します
  8. https://github.com/eugenp/REST
  9. Spring Web MVC-個々のリクエストパラメーターを検証する
  10. How to POST JSONデータをCurlでターミナル/コマンドラインからSpring RESTをテストするには?
  11. Java Servlet からJSONオブジェクトをどのように返しますか
  12. JSONがREST API? によって返される場合、どのMIMEタイプか
11
AmirHd

Beanクラスは、オプションの@JsonIgnoreなしで1つのフィールドに2つ以上のセッターがある場合、Beanクラスが[〜#〜] not [〜#〜]を処理できることに注意してください。 Spring/JacksonはHttpMediaTypeNotSupportedExceptionおよびhttpステータス415をサポートしていませんメディアタイプ。

例:

@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は不要なようです。

1