Spring BootにRestControllerのサンプルがあります:
@RestController
@RequestMapping("/api")
class MyRestController
{
@GetMapping(path = "/hello")
public JSONObject sayHello()
{
return new JSONObject("{'aa':'bb'}");
}
}
JSONライブラリorg.json
を使用しています
API /hello
をヒットすると、次のような例外が表示されます。
パス[]を持つコンテキストのサーブレット[dispatcherServlet]のServlet.service()が例外をスローしました[リクエスト処理に失敗しました。ネストされた例外はJava.lang.IllegalArgumentExceptionです:型の戻り値のコンバーターが見つかりません:クラスorg.json.JSONObject]根本原因
Java.lang.IllegalArgumentException:型の戻り値のコンバーターが見つかりません:クラスorg.json.JSONObject
問題は何ですか?誰かが正確に何が起こっているのか説明できますか?
Spring Boot Webを使用しているため、Jackson依存関係は暗黙的であり、明示的に定義する必要はありません。 Eclipseを使用している場合、依存関係階層タブのpom.xml
でJacksonの依存関係を確認できます。
また、@RestController
アノテーションを付けたので、明示的なJSON変換を行う必要はありません。 POJOを返すだけで、jacksonシリアライザーがjsonへの変換を処理します。 @Controllerで使用する場合、@ResponseBody
を使用するのと同等です。すべてのコントローラーメソッドに@ResponseBody
を配置するのではなく、Vanilla @RestController
および@Controller
の代わりに@ResponseBody
をそのコントローラーのすべてのリソースに適用します。
このリンクを参照してください:https://docs.spring.io/spring/docs/current/spring-framework -reference/html/mvc.html#mvc-ann-responsebody
あなたが直面している問題は、返されたオブジェクト(JSONObject)が特定のプロパティのゲッターを持っていないためです。また、このJSONObjectをシリアル化するのではなく、POJOをシリアル化するのが目的です。したがって、POJOを返すだけです。
このリンクを参照してください:https://stackoverflow.com/a/35822500/5039001
JSONシリアル化された文字列を返したい場合は、文字列を返します。この場合、SpringはJSONコンバーターの代わりにStringHttpMessageConverterを使用します。
現在のアプローチが機能しない理由は、オブジェクトのシリアル化と非シリアル化にデフォルトでJacksonが使用されているためです。ただし、JSONObject
をシリアル化する方法はわかりません。動的なJSON構造を作成する場合は、Map
を使用できます。例:
@GetMapping
public Map<String, String> sayHello() {
HashMap<String, String> map = new HashMap<>();
map.put("key", "value");
map.put("foo", "bar");
map.put("aa", "bb");
return map;
}
これにより、次のJSON応答が発生します。
{ "key": "value", "foo": "bar", "aa": "bb" }
子オブジェクトの追加が少し難しくなる可能性があるため、これは少し制限されています。ジャクソンには、ObjectNode
とArrayNode
を使用する独自のメカニズムがあります。それを使用するには、サービス/コントローラーでObjectMapper
を自動配線する必要があります。次に使用できます:
@GetMapping
public ObjectNode sayHello() {
ObjectNode objectNode = mapper.createObjectNode();
objectNode.put("key", "value");
objectNode.put("foo", "bar");
objectNode.put("number", 42);
return objectNode;
}
このアプローチにより、子オブジェクト、配列を追加し、すべてのさまざまなタイプを使用できます。
@vagaasenが示唆するようにString
として応答を返すか、以下のようにSpringが提供するResponseEntity
オブジェクトを使用できます。この方法により、Http status code
を返すこともできます。これは、Webサービスの呼び出しに役立ちます。
@RestController
@RequestMapping("/api")
public class MyRestController
{
@GetMapping(path = "/hello", produces=MediaType.APPLICATION_JSON_VALUE)
public ResponseEntity<Object> sayHello()
{
//Get data from service layer into entityList.
List<JSONObject> entities = new ArrayList<JSONObject>();
for (Entity n : entityList) {
JSONObject entity = new JSONObject();
entity.put("aa", "bb");
entities.add(entity);
}
return new ResponseEntity<Object>(entities, HttpStatus.OK);
}
}
このためにハッシュマップを使用することもできます
@GetMapping
public HashMap<String, Object> get() {
HashMap<String, Object> map = new HashMap<>();
map.put("key1", "value1");
map.put("results", somePOJO);
return map;
}
@RequestMapping("/api/status")
public Map doSomething()
{
return Collections.singletonMap("status", myService.doSomething());
}
PS。 1つの値に対してのみ機能します