在我提出问题之前,我必须说我已经阅读了20多个关于这个问题的问题和文章,但没有一个能解决它。
我的问题是我在java中有一个安静的服务器:
@RequestMapping (value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public void downloadByCode(@RequestBody final String stringRequest, final HttpServletResponse response)
{
try
{
final ObjectMapper objectMapper = new ObjectMapper();
final JsonNode jsonRequest = objectMapper.readValue(stringRequest, JsonNode.class);
// ...
// some processings here to create the result
// ....
final ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(result);
// Flush the result
outputStream.flush();
}
catch (final Exception exception)
{
LOG.debug("Exception Thrown [downloadByCode]", exception);
}
}
我尝试过使用jquery将json发送到此服务器的不同方法(但所有这些都会产生错误):
$.ajax({
url:"/downloadByCode",
type:"POST",
data: JSON.stringify({"name":"value"}) });
415“错误消息”:“内容类型”应用程序/ x-www-form urlencoded; charset = UTF-8'不支持“,”类型“: “HttpMediaTypeNotSupportedError”
所以我尝试通过添加contentType来修复它:
$.ajax({
url:"/downloadByCode",
contentType:"application/json",
type:"POST",
data: JSON.stringify({"name":"value"}) });
400“错误消息”:“无法为类实例化JAXBContext [类java.lang.String]:null;嵌套异常是 javax.xml.bind.JAXBException \ n - 已链接 异常:\ n [java.lang.NullPointerException“,”type“ : “HttpMessageConversionError”
我试图直接发送json对象而不是JSON.stringify,它给出了相同的400错误。
我试图在@requestMapping中添加不同的消耗但仍然没有运气。
我试图定义自己的类而不是JsonNode,但它不会改变任何东西。
有什么想法吗?
答案 0 :(得分:3)
请尝试创建新课程:
public class InputData{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
然后
public void downloadByCode(@RequestBody InputData stringRequest, final HttpServletResponse response)
并且
$.ajax({
url:"/downloadByCode",
contentType:"application/json",
type:"POST",
data: JSON.stringify({"name":"value"}) });
答案 1 :(得分:1)
尝试@RequestBody final Map<String, String> stringRequest
你也需要consumes = "application/json"
@RequestMapping,因为你在AJAX调用中有这个
如果spring不喜欢你发送ajax的格式,你会得到400 - 我过去遇到过这么多麻烦,除非必要,否则最好忽略标题类型和内容类型
答案 2 :(得分:1)
您可以尝试将响应作为ResponseEntity发回,而不是直接使用HttpServletResponse。我的预感是第二个参数,HttpServletRequest参数,是导致问题的原因。我从来没用过那个。我总是使用spring mvc api发回我的回复。
答案 3 :(得分:1)
使用Jersey api,您可以尝试: @POST public void downloadByCode(String stringRequest)
我想你会在stringRequest中找到帖子的正文。
答案 4 :(得分:1)
您可以将请求正文作为字符串使用listBox1
作为请求类型,以下是您的代码作为基础的示例:
org.springframework.http.HttpEntity<String>
但是如果你打算将结果作为字符串值返回,也许最好还使用String作为返回类型,如下所示:
@RequestMapping (value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public void downloadByCode(final HttpEntity<String> request, final HttpServletResponse response)
{
try
{
final ObjectMapper objectMapper = new ObjectMapper();
final JsonNode jsonRequest = objectMapper.readValue(request.getBody(), JsonNode.class);
// ...
// some processings here to create the result
// ....
final ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(result);
// Flush the result
outputStream.flush();
}
catch (final Exception exception)
{
LOG.debug("Exception Thrown [downloadByCode]", exception);
}
}
我使用Spring Boot使用HttpEntity使用提议的解决方案以及使用POJO的其他示例,使用Maven和JDK&gt; = 1.7来运行应用程序。
@RequestMapping (value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public String downloadByCode(HttpEntity<String> request) {
String requestBody = request.getBody();
String result;
// ...
// some processings here to create the result text
// ....
return result;
}
启动应用程序后,您可以打开http://localhost:8080,您将看到简单使用JQuery发送POST请求的html页面,请求和响应的文本将在html页面上显示,在控制器中我添加了两个处理程序,首先使用HttpEntity,然后使用POJO。
HTML页面:index.html
项目:https://github.com/mind-blowing/samples/tree/master/spring-boot/rest-handler-for-plain-text
答案 5 :(得分:1)
查看您的错误,很明显您已在spring配置中配置了“Jaxb2RootElementHttpMessageConverter”或类似的XML转换器。由于您已注册XML转换器,因此@RequestBody和@ResponseBody基于已注册的消息转换器工作。
因此,要解决您的问题,请使用JSON消息转换器,例如'MappingJacksonHttpMessageConverter'。注册JSON消息转换器后,创建一个bean类来保存json数据并将其与RequestBody一起使用,如下所示:
// It has to meet the json structure you are mapping it with
public class YourInputData {
//properties with getters and setters
}
更新1:
由于您已定义了多个消息转换器,因此Spring会尝试使用默认情况下可用的第一个消息转换器。为了使用特定的消息转换器(在本例中为Jackson转换器),您应该从客户端指定“接受”标头,如下所示:
$.ajax({
headers: {
"Accept" : "application/json; charset=utf-8",
"Content-Type": "application/json; charset=utf-8"
}
data: "data",
success : function(response) {
...
} })
答案 6 :(得分:1)
首先如果你正在使用maven,你应该为jackson添加依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1</version>
</dependency>
或者你可以下载jar并把它放在我们的项目类路径中(你也可以使用其他mapper)
然后您应该创建一个模型或DTO类,您可以在其中映射您的json
public class Data{
private String name;
pubilc Data(){}
//getter and setter
}
然后你是控制者
@RequestMapping (value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public Data downloadByCode(@RequestBody final Data data, final HttpServletResponse response)
{
//your code
return data;
}
AJAX CALL
$.ajax({
url:"/downloadByCode",
contentType:"application/json",
type:"POST",
data: JSON.stringify({"name":"value"}) });
(可选)您可以通过如下定义bean来告知对象映射器不会因缺少属性而失败来覆盖行为:
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false));
return converter;
}
http://websystique.com/springmvc/spring-mvc-requestbody-responsebody-example/
答案 7 :(得分:0)
删除@ResponseBody
方法
downloadByCode
答案 8 :(得分:0)
将方法downloadByCode()的返回类型更改为String,然后返回String
响应主体会自动将返回的String转换为JSON,然后适当地使用数据
答案 9 :(得分:0)
我不是很精通java,但我知道你的java代码必须是这样的。
public class downloadByCode{
@GET
@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
public Response downloadByCode(@QueryParam("paramater1") final String parameter 1, @Context HttpServletRequest httpRequest) {
如果这没有帮助,您可以在某处保留代码并分享。
答案 10 :(得分:0)
最后的答案是这个问题中的一些答案/评论的组合,我将在这里总结一下:
1-您必须确保在弹簧配置中有适当的json转换器,例如MappingJacksonHttpMessageConverter
(@java Anto的信用)
2-您必须创建一个与json对象具有相同结构的POJO类(请参阅@Vinh Vo答案)
3-您的POJO类不能是内联类,除非它是静态类。这意味着它应该有自己的java文件,或者它应该是静态的。 (归功于@NTyler)
4-如果你在对象映射器中正确设置了它,你的POJO类可能会遗漏你的json对象的部分内容(参见@Aman Tuladhar的回答)
5-您的ajax电话需要contentType:"application/json"
,您应该使用JSON.stringify
以下是完美运行的最终代码:
public static class InputData
{
private String name
public String getName()
{
return name;
}
public void setName(final String name
{
this.name = name;
}
}
@RequestMapping(value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public void downloadByCode(@RequestBody final InputData request, final HttpServletResponse response)
{
try
{
String codes = request.getName();
// ...
// some processings here to create the result
// ....
final ServletOutputStream outputStream = response.getOutputStream();
outputStream.write(result);
// Flush the result
outputStream.flush();
}
catch (final Exception exception)
{
LOG.debug("Exception Thrown [downloadByCode]", exception);
}
}
这是jquery Ajax请求:
$.ajax({
url:"/downloadByCode",
contentType:"application/json",
type:"POST",
data: JSON.stringify({"name":"value"}) });