私の質問は本質的に 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" }
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によって記述されているようにラッパークラスを使うべきです。
この質問を投稿してから、 JSONObject (maven dependency info )の使用を開始しました。特にチームと協力して、私が欲しいのが単純な文字列だけである場合、ラッパーオブジェクトよりも文字列が返されることを期待する方が簡単だと思います。
使用例
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return JSONObject.quote("Hello World");
}
}
次のように、プロパティJSON
にString
を付けてresponse
を簡単に返すことができます。
@RestController
public class TestController {
@RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE)
public Map getString() {
return Collections.singletonMap("response", "Hello World");
}
}
デフォルトの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
を使用して同じテクニックを実装することができますが、もう少し作業がかかります。私はこの質問は古いことを知っていますが、私も貢献したいと思います。
他のレスポンスとの主な違いはハッシュマップリターンです。
@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"}
次のように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"]
出力ストリームに戻りデータを書き込む@ResponseBody
アノテーションを追加します。
簡単にする:
@GetMapping("/health")
public ResponseEntity<String> healthCheck() {
LOG.info("REST request health check");
return new ResponseEntity<>("{\"status\" : \"UP\"}", HttpStatus.OK);
}
Spring MVC 4では、オブジェクトのデフォルトのレスポンスタイプはJSONです。だからあなたがする必要があるのはいくつかのオブジェクトであなたの文字列をラップすることです。
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// getters and setters
}
Stringの代わりにStringResponse
を返すことを除いて、コントローラに変更はありません。