【问题标题】:Jersey consume JSON on POSTJersey 在 POST 上使用 JSON
【发布时间】:2013-10-05 16:56:00
【问题描述】:

我正在尝试通过 jquery POST 将一些 json 数据发送到我本地机器上的 jersey REST 服务。

在我的服务器端,我有 Jersey 方法来使用这个 POST 的 JSON。

@Path("/question")
public class QuestionAPI {


    private final static Logger LOGGER = Logger.getLogger(HelloWorldApi.class .getName());

     @POST
     @Path("/askquestion")
     @Produces(MediaType.APPLICATION_JSON)
     @Consumes(MediaType.APPLICATION_JSON)
     public TQARequest askquestion(TQARequest tqaRequest, @Context HttpServletRequest request) {

         LOGGER.info("Inside-->askquestion-->TQARequest"+tqaRequest.getQuestion());

         return tqaRequest;

     }


}

我将 json 数据包装在请求中。这样在 server 中,我可以在该包装类中获取请求中发送的所有数据。我的请求包装类是

public class TQARequest {

    private Question question;

    public Question getQuestion() {
        return question;
    }

    public void setQuestion(Question question) {
        this.question = question;
    }

    @Override
    public String toString() {
        return "TQARequest [question=" + question + "]";
    }



}

问题 pojo 类

public class Question {

    @Id
    private Long questionID;

    private String questionText;

    private long createdOn;

    private String questionURL;

    private String questionTrackingURL;

    @Override
    public String toString() {
        return "Question [questionID=" + questionID + ", questionText="
                + questionText + ", createdOn=" + createdOn + ", questionURL="
                + questionURL + ", questionTrackingURL=" + questionTrackingURL
                + "]";
    }

    public Question(String questionText, long createdOn, String questionURL,
            String questionTrackingURL) {
        super();
        this.questionText = questionText;
        this.createdOn = createdOn;
        this.questionURL = questionURL;
        this.questionTrackingURL = questionTrackingURL;
    }

    public Long getQuestionID() {
        return questionID;
    }

    public void setQuestionID(Long questionID) {
        this.questionID = questionID;
    }

    public String getQuestionText() {
        return questionText;
    }

    public void setQuestionText(String questionText) {
        this.questionText = questionText;
    }

    public long getCreatedOn() {
        return createdOn;
    }

    public void setCreatedOn(long createdOn) {
        this.createdOn = createdOn;
    }

    public String getQuestionURL() {
        return questionURL;
    }

    public void setQuestionURL(String questionURL) {
        this.questionURL = questionURL;
    }

    public String getQuestionTrackingURL() {
        return questionTrackingURL;
    }

    public void setQuestionTrackingURL(String questionTrackingURL) {
        this.questionTrackingURL = questionTrackingURL;
    }

    public Question(){

    }


}

每当我从 jquery 发出如下所示的请求时,

 function askQuestion(){


        $.ajax({
              type: "POST",
              contentType: "application/json; charset=utf-8",
              url: "/api/question/askquestion",
              data: 
               JSON.stringify({
                   "tqaRequest" : {
                          "question" : {
                             "createdOn" : "sfddsf",
                             "questionText" : "fsdfsd",
                             "questionTrackingURL" : "http://www.google.com",
                             "questionURL" : "ssdf"
                          }
                       }
                    }

                     ),
              dataType: "json",
              success: function(response){

                  console.log(response);

              }
            });  

    }

我在控制台中收到此错误:

WARNING: /api/question/askquestion: org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "tqaRequest" (Class com.netsquid.tqa.entity.TQARequest), not marked as ignorable
 at [Source: org.mortbay.jetty.HttpParser$Input@899e3e; line: 1, column: 16] (through reference chain: com.netsquid.tqa.entity.TQARequest["tqaRequest"])

我可以通过从 jquery 发送问题 json 并在方法中接受问题参数来解决此问题。 但我需要将所有 jquery 请求包装在 TQARequest 中,并将所有请求作为 TQARequest 接受,然后从中提取问题对象。我该怎么做?

我在 web.xml 中的 POJO 映射是:

    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>

【问题讨论】:

    标签: java jquery json rest jersey


    【解决方案1】:

    相信您可以将 JSON 文档简化如下:

    {
        "question" : {
            "createdOn" : "sfddsf",
            "questionText" : "fsdfsd",
            "questionTrackingURL" : "http://www.google.com",
            "questionURL" : "ssdf"
        }
    }
    

    在这种形式下,它仍然是一个“tqaRequest”对象。

    如果您想支持问题列表,您的 JSON 可能如下所示(JSON 数组放在方括号内):

    {
        "questions" : [
            {
                "createdOn" : "date 1",
                "questionText" : "question 1",
                "questionTrackingURL" : "http://www.google.com",
                "questionURL" : "question 1 url"
            },
            {
                "createdOn" : "date 2",
                "questionText" : "question 2",
                "questionTrackingURL" : "http://www.google.com",
                "questionURL" : "question 2 url"
            }]
        }
    }
    

    你会调整你的 TQARequest 类来引用:

    private List<Question> questions;
    

    而不是

    private Question question;
    

    【讨论】:

    • 但是如果我需要多一层 JSON 怎么办?例如:{“q1”:{“question”:{“createdOn”:“sfddsf”、“questionText”:“fsdfsd”、“questionTrackingURL”:“google.com”、“questionURL”:“ssdf”}}}
    • 如果您添加另一个级别,您需要在您的 Java 对象模型中镜像它。所以在那种情况下,你会有一个 TQARequest 对象,包装一个 Q1 对象,包装一个 Question 对象。但是,您能否更具体地说明您想做什么?你想接受一系列问题吗?
    • 是的,我需要从我的 json html 页面中获取所有包含在 TQARequest 对象中的问题列表。
    【解决方案2】:

    希望这能解决问题。

    @POST
    @Path("/askquestion")
    @Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    public TQARequest askquestion(String jsonRequest){       
             TQARequest tqaRequest = MapperUtil
                                      .readAsObjectOf(TQARequest.class, jsonRequest);
        }
    

    MapperUtil.java

    com.fasterxml.jackson.databind.ObjectMapper MAPPER = new ObjectMapper();
    
     public static <T> T readAsObjectOf(Class<T> clazz, String value)
              throws MYPException {
     try {
          return MAPPER.readValue(value, clazz);
          } catch (Exception e) {
          LOGGER.error("{}, {}", e.getMessage(), e.fillInStackTrace());
     }
    }
    

    【讨论】:

    • @Consumes(MediaType.APPLICATION_JSON) ,但参数是字符串。那么我应该使用 MediaType.PLAINTEXT 吗? , 但这会破坏我的 REST 规范,我更喜欢生产者和消费者应该是 JSON。
    • 不确定,我的情况是它产生JSON,但我没有指定@Consumes,它对我来说很好用。您是否尝试过现有的设置?即,@ConsumesJSON,参数为字符串。
    • 我认为,问题不在于如何手动将 json-string 映射到对象,而在于如何配置 Jersey 以自动映射到 TQARequest。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2013-03-01
    • 2012-10-27
    • 2015-07-05
    • 2012-05-01
    • 1970-01-01
    相关资源
    最近更新 更多