简单的restful JSON POST,java作为服务器,jquery作为客户端
在我提问之前,我必须说,我已经阅读了20多篇关于这个问题的问题和文章,没有一篇能够解决这个问题 我的问题是我在java中有一个restful服务器,如下所示:简单的restful JSON POST,java作为服务器,jquery作为客户端,java,jquery,json,ajax,restful-architecture,Java,Jquery,Json,Ajax,Restful Architecture,在我提问之前,我必须说,我已经阅读了20多篇关于这个问题的问题和文章,没有一篇能够解决这个问题 我的问题是我在java中有一个restful服务器,如下所示: @RequestMapping (value = "/downloadByCode", method = RequestMethod.POST) @ResponseBody public void downloadByCode(@RequestBody final String stringRequest, final HttpServl
@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);
}
}
@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;
}
我尝试了不同的方法,用jquery将json发送到此服务器(但都会产生错误):
415“错误消息”:“内容类型”应用程序/x-www-form
urlencoded;字符集=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,它给出了相同的错误
我试图向@requestMapping添加不同的消费,但仍然没有成功
我试图定义自己的类而不是JsonNode,但它没有改变任何东西
有什么想法吗?试试
@RequestBody final-Map-stringRequest
此外,您还需要@RequestMapping上的consumes=“application/json”
,因为您在AJAX调用中已经有了它
如果spring不喜欢您发送ajax的格式,您将得到400个响应。我过去在这方面遇到过很多麻烦,除非必要,否则最好忽略标题类型和内容类型。您可以尝试将响应作为响应返回,而不是直接使用HttpServletResponse。我的直觉是第二个参数,HttpServletRequest参数,是导致问题的原因。我从未使用过它。我总是使用spring mvc api发送我的响应。对于Jersey api,您可以尝试: @职位 public void downloadByCode(String stringRequest)
我想你会在stringRequest中找到文章的正文。删除
downloadByCode
方法上的@ResponseBody
将方法downloadByCode()返回类型更改为String,然后返回字符串
响应体将自动将返回的字符串转换为JSON,然后适当地使用数据我对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) {
如果没有帮助,您可以将代码保存在某个地方并共享。您可以将请求正文作为字符串,使用
org.springframework.http.HttpEntity
作为请求类型,下面是以代码为基础的示例:
@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);
}
}
应用程序启动后,您可以打开html页面,使用JQuery发送POST请求,请求和响应的文本将显示在html页面上。在控制器中,我添加了两个处理程序,第一个使用HttpEntity,第二个使用POJO
控制器:
HTML页面:
项目:请尝试创建新类:
public class InputData{
private String name;
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
然后
及
查看您的错误,很明显您已经在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 converter),您应该从客户端指定“接受””头,如下所示:
$.ajax({
headers: {
"Accept" : "application/json; charset=utf-8",
"Content-Type": "application/json; charset=utf-8"
}
data: "data",
success : function(response) {
...
} })
首先,如果您使用的是maven,您应该为jackson添加依赖项
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.1</version>
</dependency>
然后你是控制器
@RequestMapping (value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public Data downloadByCode(@RequestBody final Data data, final HttpServletResponse response)
{
//your code
return data;
}
AJAX调用
$.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;
}
最后的答案是这个问题中许多答案/评论的组合,我将在这里对它们进行总结: 1-您必须确保在spring配置中有适当的json转换器,例如
MappingJacksonHttpMessageConverter
(归功于@java Anto)
2-必须创建一个与json对象具有相同结构的POJO类(请参见@Vinh Vo answer)
3-您的POJO类不能是内联类,除非它是静态类。这意味着它应该有自己的java文件,或者应该是静态的。(归功于@NTyler)
4-如果在对象映射器中适当地设置了json对象,则POJO类可能会丢失json对象的某些部分(请参见@Aman Tuladhar answer)
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"}) });
谢谢您的回答。我已将我的请求正文更改为:public void downloads ordersbycode(@RequestBody final Map requestMap,final HttpServletResponse response)
但是,我仍然收到与上述相同的400个错误。您还需要我的答案的consumes部分(或者从ajax调用中删除)-这行吗?谢谢你的响应,问题是它永远不会到达响应阶段。我的意思是当它尝试接收json作为输入时会产生错误。我的响应是一个CVS文件,我认为当前的代码应该可以,因为它与GET方法完美配合。谢谢,如果我没有一个附加API。它从未到达响应阶段。当它尝试加载json作为输入时会产生错误。没有任何更改,我认为问题与获取json作为输入有关。输出
@RequestMapping (value = "/downloadByCode", method = RequestMethod.POST)
@ResponseBody
public Data downloadByCode(@RequestBody final Data data, final HttpServletResponse response)
{
//your code
return data;
}
$.ajax({
url:"/downloadByCode",
contentType:"application/json",
type:"POST",
data: JSON.stringify({"name":"value"}) });
@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
converter.setObjectMapper(new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false));
return converter;
}
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);
}
}
$.ajax({
url:"/downloadByCode",
contentType:"application/json",
type:"POST",
data: JSON.stringify({"name":"value"}) });