Meine Frage ist im Wesentlichen eine Fortsetzung der Frage this .
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return "Hello World";
}
}
Im obigen Beispiel würde Spring "Hello World" in den Antworttext einfügen. Wie kann ich einen String als JSON-Antwort zurückgeben? Ich verstehe, dass ich Anführungszeichen hinzufügen könnte, aber das fühlt sich eher wie ein Hack an.
Bitte geben Sie Beispiele an, um dieses Konzept zu erläutern.
Hinweis: Ich möchte nicht, dass dies direkt in den HTTP-Antworttext geschrieben wird. Ich möchte den String im JSON-Format zurückgeben (ich verwende meinen Controller) mit RestyGWT , was erfordert, dass die Antwort im gültigen JSON-Format vorliegt).
Entweder text/plain
zurückgeben (wie in Nur String-Nachricht von Spring MVC 3 Controller zurückgeben ) OR Den String umschließen ist ein Objekt
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// get/set omitted...
}
Setzen Sie Ihren Antworttyp auf application/json
@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")
und Sie werden eine JSON haben, die aussieht
{ "response" : "your string value" }
JSON ist im Wesentlichen eine Zeichenfolge im Kontext PHP oder Java. Dies bedeutet, dass eine Zeichenfolge, die gültig ist, als Antwort zurückgegeben werden kann. Folgendes sollte funktionieren.
@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}";
}
Dies ist für eine einfache String-Antwort in Ordnung. Für komplexe JSON-Antworten sollten Sie jedoch die von Shaun beschriebene Wrapper-Klasse verwenden.
In einem Projekt haben wir dies mit JSONObject (maven dependency info ) behoben. Wir haben dies gewählt, weil wir es vorgezogen haben, einen einfachen String anstelle eines Wrapper-Objekts zurückzugeben. Eine interne Hilfsklasse kann problemlos verwendet werden, wenn Sie keine neue Abhängigkeit hinzufügen möchten.
Beispiel Verwendung:
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return JSONObject.quote("Hello World");
}
}
Sie können JSON
mit String
in der Eigenschaft response
wie folgt zurückgeben
@RestController
public class TestController {
@RequestMapping(value = "/getString", produces = MediaType.APPLICATION_JSON_VALUE)
public Map getString() {
return Collections.singletonMap("response", "Hello World");
}
}
Heben Sie einfach die Registrierung der Standardinstanz StringHttpMessageConverter
auf:
@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);
}
}
Getestet sowohl mit Controller Action Handler-Methoden als auch mit Controller Exception Handlern:
@RequestMapping("/foo")
public String produceFoo() {
return "foo";
}
@ExceptionHandler(FooApiException.class)
public String fooException(HttpServletRequest request, Throwable e) {
return e.getMessage();
}
Schlussbemerkungen:
extendMessageConverters
ist seit Spring 4.1.3 verfügbar. Wenn Sie mit einer früheren Version arbeiten und die gleiche Technik mit configureMessageConverters
implementieren können, ist nur ein wenig mehr Arbeit erforderlich.Ich weiß, dass diese Frage alt ist, aber ich möchte auch dazu beitragen:
Der Hauptunterschied zwischen anderen Antworten ist die Hashmap-Rückgabe.
@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;
}
Dies wird zurückkehren:
{"pic":"a17fefab83517fb...beb8ac5a2ae8f0449","potato":"King Potato"}
Füge produces = "application/json"
in @RequestMapping
hinzu wie:
@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")
Hinweis: Als Rückgabewert empfehle ich den Typ ResponseEntity<List<T>>
. Weil die erzeugten Daten im JSON-Body ein Array oder ein Objekt sein müssen und nicht ein einfaches String. Dies kann manchmal Probleme verursachen (z. B. Observables in Angular2).
Unterschied:
gab String
als json zurück: "example"
gab List<String>
als json zurück: ["example"]
Fügen Sie die Annotation @ResponseBody
hinzu, die die zurückgegebenen Daten in den Ausgabestream schreibt.
Machen Sie es einfach:
@GetMapping("/health")
public ResponseEntity<String> healthCheck() {
LOG.info("REST request health check");
return new ResponseEntity<>("{\"status\" : \"UP\"}", HttpStatus.OK);
}
In Spring MVC 4 ist der Standardantworttyp für Objekte JSON. Alles, was Sie tun müssen, ist, Ihren String in ein Objekt zu wickeln.
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// getters and setters
}
Keine Änderungen an der Steuerung, außer die Rückgabe von StringResponse
anstelle des Strings.