我的问题基本上是对this问题的跟进。
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return "Hello World";
}
}
在上面,Spring会在响应体中添加“Hello World”。如何将String作为JSON响应返回?我知道我可以添加引号,但这更像是一个黑客。
请提供任何示例来帮助解释这个概念。
注意:我不想直接写入HTTP Response主体,我想以JSON格式返回String(我正在使用我的Controller 使用RestyGWT,要求响应处于有效的JSON状态 格式)。
答案 0 :(得分:113)
返回text/plain
(如Return only string message from Spring MVC 3 Controller中所示)或包裹你的String是某个对象
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" }
答案 1 :(得分:41)
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所描述的包装类。
答案 2 :(得分:21)
自从我发布此问题以来,我已开始使用JSONObject(maven dependency info)。特别是与团队合作,我发现当我想要的只是一个简单的String时,更容易期望返回一个String而不是一些包装器对象。
示例用法:
@RestController
public class TestController
{
@RequestMapping("/getString")
public String getString()
{
return JSONObject.quote("Hello World");
}
}
答案 3 :(得分:17)
您可以轻松地在complete_name
属性JSON
中返回String
,如下所示
response
答案 4 :(得分:8)
只需取消注册默认的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
实现相同的技术,只需要多做一些工作。答案 5 :(得分:6)
我知道这个问题很老,但我也想贡献一点:
其他响应之间的主要区别是哈希图返回。
@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 :(得分:4)
在produces = "application/json"
注释中添加@RequestMapping
,如:
@RequestMapping(value = "api/login", method = RequestMethod.GET, produces = "application/json")
提示:作为返回值,我建议使用ResponseEntity<List<T>>
类型。因为根据其规范,JSON主体中生成的数据需要是数组或对象,而不是单个简单的字符串。它有时可能会引起问题(例如Angular2中的Observables)。
差异:
以json:String
"example"
以json:List<String>
["example"]
答案 7 :(得分:3)
添加@ResponseBody
注释,它将在输出流中写入返回数据。
答案 8 :(得分:1)
在Spring MVC 4中,对象的默认响应类型是JSON。所以你需要做的就是将String包装在一些Object中。
public class StringResponse {
private String response;
public StringResponse(String s) {
this.response = s;
}
// getters and setters
}
除了返回StringResponse
而不是String之外,不对控制器进行任何修改。
答案 9 :(得分:1)
简单点:
@GetMapping("/health")
public ResponseEntity<String> healthCheck() {
LOG.info("REST request health check");
return new ResponseEntity<>("{\"status\" : \"UP\"}", HttpStatus.OK);
}
答案 10 :(得分:0)
这个问题使我发疯了:Spring是一种强大的工具,但是,如果没有丑陋的黑客,像将输出字符串写为JSON这样简单的事情似乎是不可能的。
我的解决方案(在Kotlin中)是侵入性最低且最透明的解决方案,它是使用控制器建议并检查请求是否到达了一组特定的端点(通常是REST API,因为我们通常希望返回所有答案)此处为JSON,而不根据返回的数据是纯字符串(“不要进行JSON反序列化!”)还是其他方式(“进行JSON反序列化!”)在前端进行特殊化。积极的一面是,控制器保持不变,没有被黑客入侵。
supports
方法确保StringHttpMessageConverter
处理的所有请求(例如,处理所有返回纯字符串的控制器的输出的转换器)都在{{1}中处理}方法,我们控制在哪种情况下我们想要中断并将输出转换为JSON(并相应地修改标头)。
beforeBodyWrite
我希望将来我们会得到一个简单的注释,在其中可以覆盖应将哪个@ControllerAdvice
class StringToJsonAdvice(val ob: ObjectMapper) : ResponseBodyAdvice<Any?> {
override fun supports(returnType: MethodParameter, converterType: Class<out HttpMessageConverter<*>>): Boolean =
converterType === StringHttpMessageConverter::class.java
override fun beforeBodyWrite(
body: Any?,
returnType: MethodParameter,
selectedContentType: MediaType,
selectedConverterType: Class<out HttpMessageConverter<*>>,
request: ServerHttpRequest,
response: ServerHttpResponse
): Any? {
return if (request.uri.path.contains("api")) {
response.getHeaders().contentType = MediaType.APPLICATION_JSON
ob.writeValueAsString(body)
} else body
}
}
用于输出。
答案 11 :(得分:-3)
将此注释添加到方法
@RequestMapping(value = "/getString", method = RequestMethod.GET, produces = "application/json")