web-dev-qa-db-ja.com

Spring MVC - Rest Controllerで単純な文字列をJSONとして返す方法

私の質問は本質的に this 質問へのフォローアップです。

@RestController
public class TestController
{
    @RequestMapping("/getString")
    public String getString()
    {
        return "Hello World";
    }
}

上記では、Springはレスポンスボディに "Hello World"を追加します。 JSONレスポンスとして文字列を返すにはどうすればいいですか?私は引用符を追加できることを理解していますが、それはハックのように感じます。

この概念を説明するのに役立つどんな例でも提供してください。

注: これを直接HTTPレスポンスボディに書きたくない、私はJSONフォーマットで文字列を返したい(私は RestyGWTで私のコントローラを使っています レスポンスは有効なJSON形式で).

Spring MVC 3コントローラからの文字列メッセージのみを返す )ORのようにtext/plainを返す

public class StringResponse {

    private String response;

    public StringResponse(String s) { 
       this.response = s;
    }

    // get/set omitted...
}


あなたの応答タイプをapplication/jsonに設定してください

@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")

そしてあなたはのようなJSONがあるでしょう

{  "response" : "your string value" }
112
Shaun

JSONは本質的にPHPまたはJavaコンテキストのStringです。つまり、有効なJSONである文字列を応答として返すことができます。以下がうまくいくはずです。

  @RequestMapping(value="/user/addUser", method=RequestMethod.POST)
  @ResponseBody
  public String addUser(@ModelAttribute("user") User user) {

    if (user != null) {
      logger.info("Inside addIssuer, adding: " + user.toString());
    } else {
      logger.info("Inside addIssuer...");
    }
    users.put(user.getUsername(), user);
    return "{\"success\":1}";
  }

これは単純な文字列応答には問題ありません。しかし、複雑なJSONレスポンスのためには、Shaunによって記述されているようにラッパークラスを使うべきです。

41
pinkal vansia

この質問を投稿してから、 JSONObject (maven dependency info )の使用を開始しました。特にチームと協力して、私が欲しいのが単純な文字列だけである場合、ラッパーオブジェクトよりも文字列が返されることを期待する方が簡単だと思います。

使用例

@RestController
public class TestController
{
    @RequestMapping("/getString")
    public String getString()
    {
        return JSONObject.quote("Hello World");
    }
}

次のように、プロパティJSONStringを付けてresponseを簡単に返すことができます。

@RestController
public class TestController {
    @RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE)
    public Map getString() {
        return Collections.singletonMap("response", "Hello World");
    }
}
17
Javasick

デフォルトのStringHttpMessageConverterインスタンスを登録解除するだけです。

@Configuration
public class WebMvcConfiguration extends WebMvcConfigurationSupport {
  /**
   * Unregister the default {@link StringHttpMessageConverter} as we want Strings
   * to be handled by the JSON converter.
   *
   * @param converters List of already configured converters
   * @see WebMvcConfigurationSupport#addDefaultHttpMessageConverters(List)
   */
  @Override
  protected void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
    converters.stream()
      .filter(c -> c instanceof StringHttpMessageConverter)
      .findFirst().ifPresent(converters::remove);
  }
}

コントローラアクションハンドラメソッドとコントローラ例外ハンドラの両方でテスト済み:

@RequestMapping("/foo")
public String produceFoo() {
  return "foo";
}

@ExceptionHandler(FooApiException.class)
public String fooException(HttpServletRequest request, Throwable e) {
  return e.getMessage();
}

最終メモ:

  • extendMessageConvertersはSpring 4.1.3以降で利用可能です。もし以前のバージョンで実行しているのであれば、configureMessageConvertersを使用して同じテクニックを実装することができますが、もう少し作業がかかります。
  • アプリケーションがJSONのみを返し、他のコンテンツタイプを返さない場合は、これが他の多くの可能なアプローチの1つのアプローチでした。デフォルトのコンバーターをスキップして単一のjacksonコンバーターを追加する方が得策です。もう1つの方法は、デフォルトのコンバータを追加することですが、順序を変えて、ジャクソンコンバータが文字列よりも優先されるようにします。これにより、コントローラアクションメソッドは、レスポンスのメディアタイプに応じてStringをどのように変換するかを決定できます。
8
Amr Mostafa

私はこの質問は古いことを知っていますが、私も貢献したいと思います。

他のレスポンスとの主な違いはハッシュマップリターンです。

@GetMapping("...")
@ResponseBody
public HashMap<String, Object> endPointExample(...) {

    HashMap<String, Object> rtn = new LinkedHashMap<String, Object>();
    rtn.put("pic", image);
    rtn.put("potato", "King Potato");

    return rtn;

}

これは戻ります:

{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
6
Brenno Leal

次のようにproduces = "application/json"アノテーションに@RequestMappingを追加します。

@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")

ヒント:戻り値として、ResponseEntity<List<T>>型を使用することをお勧めします。 JSON本体で生成されたデータは、単一の単純な ストリング ではなく、その仕様に従って array または object である必要があるためです。それは時々問題を起こすかもしれません(例えばObservables in Angular 2)。

差:

jsonとしてStringを返しました:"example"

jsonとしてList<String>を返しました:["example"]

4
Aybars Yuksel

出力ストリームに戻りデータを書き込む@ResponseBodyアノテーションを追加します。

3
hugo

簡単にする:

    @GetMapping("/health")
    public ResponseEntity<String> healthCheck() {
        LOG.info("REST request health check");
        return new ResponseEntity<>("{\"status\" : \"UP\"}", HttpStatus.OK);
    }
1
samarone

Spring MVC 4では、オブジェクトのデフォルトのレスポンスタイプはJSONです。だからあなたがする必要があるのはいくつかのオブジェクトであなたの文字列をラップすることです。

    public class StringResponse {

   private String response;

   public StringResponse(String s) { 
       this.response = s;
   }

    // getters and setters 
}

Stringの代わりにStringResponseを返すことを除いて、コントローラに変更はありません。

1
Ranuka