Spring MVCで@ResponseBodyを使ったら500エラーになった

Spring
Spring

Ajaxでのリクエストに対応するためSpringで@ResponseBodyアノテーションを使ってレスポンスを返すコントローラーメソッドを作成しようとしたらちょっとハマったので、備忘録を残しておきます。

起こったこと

Ajaxリクエストの応答としてデータを返却するコントローラーメソッドを作成しました。

@PostMapping("send")
@ResponseBody
public Map<String, Object> send(Model model) {
    Map<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("value", "Hello Ajax World");
    return paramMap;
}

これに対し、Ajax送信を行うスクリプトを書いて、Ajax通信を実行してみました。

$("#ajax").on("click", () => {
    $.ajax({
        url: "send",
        type: "POST"
    }).done((data) => {
        $("#text").text(data.value);
    });
});

で、いざ"#ajax"なボタンを押してみると、

ステータスが500エラーになってしまいました。
サーバ側のログには例外などは吐き出されていませんでした。

原因

ざっくり言うと「レスポンスデータがJSON等にパースできていない」というのが原因でした。

Springの設定タグで、様々なアノテーションの機能をよしなに設定してくれる<mvc:annotation-driven />というXMLのタグがあります。このタグの働きとして、
JAXBがクラスパスに存在すれば、XMLを読み書きする機能を提供する」
Jacksonがクラスパスに存在すれば、JSONを読み書きする機能を提供する」
というものがあります。
タグ一つ記入するだけで設定できちゃうなんてありがたい限りですね。

で、私が何をやらかしていたかというと、Jacksonの依存関係の定義をしていなかったのです。まあ凡ミス。。。

解決方法

Jacksonがクラスパスにあって、<mvc:annotation-driven />の記載がSpringの設定XMLにあれば問題なく動きます。
今回はクラスパスの方が欠けていたので、Jacksonの依存関係を定義します。

dependencies {
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.12.2'
    implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.12.2'
}

ちなみにSpringの設定ファイルも。

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-4.3.xsd
        http://www.springframework.org/schema/mvc
        http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd">

    <mvc:annotation-driven />

</beans>
  • どちらもいろいろ省略しています。

これでビルドしなおしてから動かすことで、無事にパースが行われて200番で返ってくるようになりました。

ちなみに、@ResponseBodyのメソッドの戻り値をStringにしてBodyを直接書いて返却すると、Jacksonなしでも正常に動作するみたいです。パースしてないから当然か。


Spring Bootとかだとこの辺の設定なども意識せずにできてるようになってるのかな?と思います。
Spring MVCだとそういった優しさはないので、こういったこともトライ&エラーで覚えていかなければいけませんね。

参考

https://zrsbqzz4wu6limdjn6cnjegmw4-jj2cvlaia66be-stackoverflow-com.translate.goog/questions/24766728/response-code-500-when-returning-an-object-using-responsebody
https://sites.google.com/site/soracane/home/springnitsuite/spring-mvc/06-she-dingfairu

 

コメント

タイトルとURLをコピーしました