web-dev-qa-db-ja.com

Jacksonメッセージコンバーターを使用してJSON応答を行うSpring 3.0

私はジャクソンのものとしてメッセージコンバータを設定します

class Foo{int x; int y}

そしてコントローラーで

@ResponseBody
public Foo method(){
   return new Foo(3,4)
}

それから、他の設定なしでサーバーからJSON文字列{x: '3'、y: '4'}を返すことを期待しています。しかし、私のajaxリクエストに対する404エラー応答を取得する

メソッドに@ResponseBodyアノテーションが付けられている場合、戻り値のタイプは応答HTTP本文に書き込まれます。戻り値は、HttpMessageConvertersを使用して、宣言されたメソッド引数タイプに変換されます。

私が間違っている ?または、シリアライザーを使用して自分で応答オブジェクトをJson文字列に変換し、その文字列を応答として返す必要があります(文字列応答を正しく行うことができます)または他の設定を行う必要がありますか?クラスFooに注釈を追加するような

ここに私のconf.xmlがあります

<bean id="jacksonMessageConverter" class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter">
  <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
<property name="messageConverters">
  <list>
    <ref bean="jacksonMessageConverter"/>
  </list>
</property>
23
dupdup

次のものが必要です。

  1. 注釈駆動型プログラミングモデルを設定します。<mvc:annotation-driven />spring.xmlを配置します
  2. クラスパスにjaskson jar(Maven artifactId is org.codehaus.jackson:jackson-mapper-asl)を配置します。
  3. 次のように使用します。

    @RequestMapping(method = { RequestMethod.GET, RequestMethod.POST })
    public @ResponseBody Foo method(@Valid Request request, BindingResult result){
    return new Foo(3,4)
    }
    

これは私のために動作します。

その点に注意してください

  1. @ResponseBodyは、メソッド定義ではなく戻り値の型に適用されます。
  2. Springがそれを検出するためには、@RequestMappingアノテーションが必要です。
22
uthark

MessageConverterインターフェース http://static.springsource.org/spring/docs/3.0.x/javadoc-api/ は、MappingJacksonMessageCoverterがapplication/jsonを返すgetSupportedMediaTypes()メソッドを定義します

public MappingJacksonHttpMessageConverter() {
    super(new MediaType("application", "json", DEFAULT_CHARSET));
}

Accept:application/jsonリクエストヘッダーが欠落していると思います。

3
Sven Haiges

これは私のために働いた:

_@RequestMapping(value = "{p_LocationId}.json", method = RequestMethod.GET)
protected void getLocationAsJson(@PathVariable("p_LocationId") Integer p_LocationId,
     @RequestParam("cid") Integer p_CustomerId, HttpServletResponse response) {
        MappingJacksonHttpMessageConverter jsonConverter = 
                new MappingJacksonHttpMessageConverter();
        Location requestedLocation = new Location(p_LocationId);
        MediaType jsonMimeType = MediaType.APPLICATION_JSON;
        if (jsonConverter.canWrite(requestedLocation.getClass(), jsonMimeType)) {
        try {
            jsonConverter.write(requestedLocation, jsonMimeType,
                                   new ServletServerHttpResponse(response));
            } catch (IOException m_Ioe) {
                // TODO: announce this exception somehow
            } catch (HttpMessageNotWritableException p_Nwe) {
                // TODO: announce this exception somehow
            }
        }
}
_

メソッドは何も返さないことに注意してください:MappingJacksonHttpMessageConverter#write()は魔法を使います。

3
Boris Brudnoy

HTTP 404エラーは、リソースが見つからないことを意味します。それには2つの原因があります。

  1. リクエストURLが間違っています(指定されたリンク/ボタンのクライアント側エラーまたは間違ったURL)。
  2. リソースは、予期した場所にありません(サーバー側エラー)。

1を修正するには、正しいリクエストURLを使用または提供していることを確認してください(大文字と小文字を区別します!)。 2を修正するには、サーバーの起動ログで起動エラーを確認し、それに応じて修正します。

これはすべて、これまでに投稿されたコードと情報を超えています。

2
BalusC

Jackson-mapper-asl.jarだけでなく、jackson-core-asl.jarも必要であることがわかりました

1
ricor

ここでの答えに加えて..

クライアント側でjqueryを使用している場合、これは私のために働いた:

Java:

@RequestMapping(value = "/ajax/search/sync") 
public ModelAndView sync(@RequestBody Foo json) {

Jquery(JSON.stringify関数を使用するには、Douglas Crockfordのjson2.jsを含める必要があります):

$.ajax({
    type: "post",
    url: "sync", //your valid url
    contentType: "application/json", //this is required for spring 3 - ajax to work (at least for me)
    data: JSON.stringify(jsonobject), //json object or array of json objects
    success: function(result) {
        //do nothing
    },
    error: function(){
        alert('failure');
    }
});
0

これは単なる推測に過ぎませんが、デフォルトでは、Jacksonはパブリックフィールド(およびパブリックゲッター。ただし、可視性に関係なくすべてのセッター)のみを自動検出します。これを設定して(バージョン 1.5 で)、必要に応じてプライベートフィールドを自動検出することもできます(詳細については here を参照)。

0
StaxMan

404はHttpMessageConverterとは関係ないと思います。私は同じ404問題を抱えていました。その理由は、一致するリクエストだけを忘れていたためです<url-pattern>がDispatcherServletに送信されます(要求のマッピングを* .doから* .jsonに変更しました)。たぶんこれもあなたの場合です。