例如,我必须按如下方式实施:
@RequestMapping(value = "/get-string", method = {RequestMethod.GET})
public @ResponseBody String getString() {
return "Hello World!";
}
当Ajax在JS文件中调用该操作时,收到的响应是:HelloWorld
。因此,如果Ajax请求配置为仅接收json编码的响应,则会收到标准的deconding错误。要在服务器端解决此问题,我需要收到"HelloWorld"
。
我的问题是:有一种干净的方法可以做到这一点,而不只是更改为下面的字符串返回的字符串?
...
return "\"Hello World!\"";
}
更新说明:在这个问题的时候,我对我之前想要的返回JSON地图而不是单个字符串的解决方案感到满意。
但是现在,我花了一些时间来搜索这个,并尝试更多地了解JSON模式。
首先,我发现我的问题与这些问题重复one,two和three。正确的answer表示问题出在Spring Boot的默认序列化程序(Jackson的库)中,它将字符串值(序列化时)视为原始JSON字符串,因此它返回值正如我所料,双引号而不是添加。
恐惧,我会选择 Bhargav的answer,它更接近我想要的东西。 ddbullfrog和RohaNayak的答案是正确的,但它们无法正确解决我的问题。 Ademir Constantino的comment也是正确的,他说使用普通/文本而不是json格式,使用这个reference。 Luay Absulraheem的answer是配置动作的正确方法,但它没有按照想要的方式工作,它继续将字符串作为原始json发送。 非常感谢您的回答!
此外,可以自定义Spring Boot以使用Gson作为其序列化器,如article所示。在您的项目上安装Gson依赖项之后,您只需在 application.properties 文件中添加此行:
...
spring.http.converters.preferred-json-mapper=gson
通过这种方式,您不必在每次要发送字符串值时进行解析 要通过Spring Boot序列化,并且在AJAX处理程序中没有双引号就不会收到它。
我试图实现与ASP.NET MVC相同的行为,后者使用JSON.NET library来执行序列化。这个以及AJAX接受单个字符串(例如" hello world")作为JSON的事实,使我对JSON模式进行了更深入的研究。
有多个"标准" JSON格式的定义。正如在Stack的其他question上所讨论的那样,当前的互联网标准" JSON值由RFC-8259定义,如文档第5页所述:
JSON值必须是对象,数组,数字或字符串,或者是其中之一 以下三个字面名称:
- 假
- 空
- 真
如上所示,在旧标准中,JSON可以是比以前更广泛的数据类型。
更新注释:另一种方法是返回char []而不是String 实例。这样,Spring Boot将无法识别为原始JSON字符串:
@RequestMapping(value = "/get-string", method = {RequestMethod.GET})
public @ResponseBody char[] getString() {
return "Hello World!".toCharArray();
}
答案 0 :(得分:3)
是的,您可以使用像gson或jackson这样的库将您的字符串转换为JSON,在那里为您提供如下所示的json输出。
Gson gson= new GsonBuilder().create();
gson.toJson(Your String);
另外,别忘了添加
produces = MediaType.APPLICATION_JSON_VALUE
暴露的方法,以便spring知道需要生成什么样的o / p。
答案 1 :(得分:2)
尝试将produces = {MediaType.APPLICATION_JSON_VALUE }
添加到@RequestMapping
,因为它会影响所写的实际内容类型。要使用UTF-8编码生成JSON响应,应使用produces = {MediaType.APPLICATION_JSON_UTF8_VALUE }
。
答案 2 :(得分:2)
Spring在默认情况下配置了一个StringHttpMessageConverter
,它可以处理从控制器返回的任何String
,而与媒体类型无关,就好像它是text/plain
。
您可以通过在Spring中配置的所有其他消息转换器之后移动StringHttpMessageConverter
或将其替换为自己的不处理*/*
媒体类型的实现并进行配置来解决此问题。
在Spring引导中:
扩展WebMvcConfigurerAdapter
,覆盖extendMessageConverters
,并根据需要修改收到的列表,例如
@Configuration
public class StringHttpMessageConverterReorganizingWebMvcConfigurerAdapter extends WebMvcConfigurerAdapter
{
@Override
public void extendMessageConverters(final List<HttpMessageConverter<?>> converters)
{
super.extendMessageConverters(converters);
// do whatever you see fit with StringHttpMessageConverter in the converters list
// ...
}
}
此后,Jackson(可能还有其他JSON序列化程序)将在结果处理中表达自己的意见,并在响应中将My string
序列化为"My string"
。
当将结果处理到HTTP响应主体中时,Spring遍历其已注册的HttpMessageConverter
,并选择与Java结果的类型和相应的媒体类型相匹配的第一个(例如,从@RequestMapping::produces
开始)。
在这种情况下,控制器返回的结果类型为String
,媒体类型为application/json
或类似的内容。
在默认配置中,有一个名为StringHttpMessageConverter
的消息转换器,它处理String
返回类型以及媒体类型text/plain
和*/*
。由于它通常是在用于处理json数据的任何其他序列化程序之前注册的,因此它将仅将任何String
转换为其身份,并完成结果转换,将未加引号且未转义的字符串写入响应中不管我们的text/plain
媒体类型如何,都好像application/json
一样。
所以我们有以下选择:
(a)接管消息转换器的创建,并提供不同的顺序或不接受StringHttpMessageConverter
的{{1}}。
(b)在选择转换器之前,接管消息转换器选择逻辑,并查看是否有比*/*
更具体的匹配项。
(c)以某种方式侵入已创建的转换器并替换/更改/删除*/*
对于选项(a),这是不切实际的,因为
1. StringHttpMessageConverter
always uses media type */*
。滚动自定义实现是很有必要的。
2. StringHttpMessageConverter
is final and cannot be overriden to choose different converters。
3.使用中的另一个配置框架(例如Spring Boot)可以使用其自己的逻辑来提供消息转换器。例如,通过依赖项注入继承和使用WebMvcConfigurationSupport::addDefaultMessageConverters
(例如,使用WebMvcConfigurationSupport
)将导致MVC的Spring Boot自动配置停止。
覆盖配置框架中的消息转换器配置可能是可行的。我对Spring Boot的搜索仅达到了HttpMessageConverters
类,该类支持忽略默认转换器,因此这也是一种实现方法。
选项(b)也不切实际。整个迭代逻辑是在AbstractMessageConverterMethodProcessor::writeWithMessageConverters
中完成的,不幸的是,它还会执行其他工作,因此没有简单的方法可以覆盖它。
因此,我们到达选项(c),该选项概述了此答案的开始。
答案 3 :(得分:1)
只需创建一个包含键值的地图。它将达到目的。 每个JSON都需要一个键和一个值 map.put(“hello”:“你的字符串值”)
返回地图;
答案 4 :(得分:0)
您可以将json格式的String值返回给客户端;
返回&#34; {\&#34;回复\&#34;:\&#34; Hello World!\&#34;}&#34;;