[spring-mvc] Return JSON for ResponseEntity<String>

I have a method in my controller that should returns a String in JSON. It returns JSON for non primitive types:

@RequestMapping(value = "so", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> so() {
    return new ResponseEntity<String>("This is a String", HttpStatus.OK);
}

The curl response is:

This is a String

This question is related to spring-mvc

The answer is


This is a String, not a json structure(key, value), try:

return new ResponseEntity("{"vale" : "This is a String"}", HttpStatus.OK);


The root of the problem is that Spring (via ResponseEntity, RestController, and/or ResponseBody) will use the contents of the string as the raw response value, rather than treating the string as JSON value to be encoded. This is true even when the controller method uses produces = MediaType.APPLICATION_JSON_VALUE, as in the question here.

It's essentially like the difference between the following:

// yields: This is a String
System.out.println("This is a String");

// yields: "This is a String"
System.out.println("\"This is a String\"");

The first output cannot be parsed as JSON, but the second output can.

Something like '"'+myString+'"' is probably not a good idea however, as that won't handle proper escaping of double-quotes within the string and will not produce valid JSON for any such string.

One way to handle this would be to embed your string inside an object or list, so that you're not passing a raw string to Spring. However, that changes the format of your output, and really there's no good reason not to be able to return a properly-encoded JSON string if that's what you want to do. If that's what you want, the best way to handle it is via a JSON formatter such as Json or Google Gson. Here's how it might look with Gson:

import com.google.gson.Gson;

@RestController
public class MyController

    private static final Gson gson = new Gson();

    @RequestMapping(value = "so", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
    ResponseEntity<String> so() {
        return ResponseEntity.ok(gson.toJson("This is a String"));
    }
}

public ResponseEntity<?> ApiCall(@PathVariable(name = "id") long id) {
    JSONObject resp = new JSONObject();
    resp.put("status", 0);
    resp.put("id", id);

    return new ResponseEntity<String>(resp.toString(), HttpStatus.CREATED);
}

An alternative solution is to use a wrapper for the String, for instances this:

public class StringResponse {
    private String response;
    public StringResponse(String response) {
        this.response = response;
    }
    public String getResponse() {
        return response;
    }
}

Then return this in your controller's methods:

ResponseEntity<StringResponse>