简单的休息JSON POST,java为服务器,jquery为客户端

时间:2015-12-23 23:04:31

标签: java jquery json ajax restful-architecture

在我提出问题之前,我必须说我已经阅读了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,但它不会改变任何东西。

有什么想法吗?

11 个答案:

答案 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。

控制器:SampleRestController.java

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"}) });