创建新资源时,Dropwizard示例出现400错误

6
我是一个新手,刚接触Dropwizard框架。我正在尝试创建一个类似于教程中提到的person和people资源的新资源,链接在这里:https://github.com/dropwizard/dropwizard/tree/master/dropwizard-example
我正在创建一个类似于下面这样的文档类 -
@Entity
@Table(name = "document")
@NamedQueries({
        @NamedQuery(
                name = "com.example.helloworld.core.Document.findAll",
                query = "SELECT d FROM Document d"
        ),
        @NamedQuery(
                name = "com.example.helloworld.core.Document.findById",
                query = "SELECT d FROM Document d WHERE d.Id = :Id"
        )
})
public class Document {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long Id;

    @Column(name = "ProcessingSetID")
    private String ProcessingSetID;

    @Column(name = "processed")
    private String processed;

    public long getId() {
        return Id;
    }

    public void setId(long id) {
        this.Id = id;
    }

    public String getProcessingSetID() {
        return ProcessingSetID;
    }

    public void setProcessingSetID(String processingSetID) {
        ProcessingSetID = processingSetID;
    }

    public String getProcessed() {
        return processed;
    }

    public void setProcessed(String processed) {
        this.processed = processed;
    }
}

我的Dao文档如下所示:
public Optional<Document> findById(Long id) {
    return Optional.fromNullable(get(id));
}

public Document create(Document document) {
    return persist(document);
}

public List<Document> findAll() {
    return list(namedQuery("com.example.helloworld.core.Document.findAll"));
}
}

我正在尝试在我的文档资源上调用POST方法,

@Path("/documents")
@Produces(MediaType.APPLICATION_JSON)

public class DocumentsResource {

    private final DocumentDao documentDAO;
    private static final Logger log = LoggerFactory.getLogger(DocumentsResource.class);

    public DocumentsResource(DocumentDao documentDAO) {
        this.documentDAO = documentDAO;
    }

    @POST
    @UnitOfWork
    public Document createDocument(Document document) {
        log.info("inside POST method of document.");
        System.out.println("inside POST method of document.....");
        return documentDAO.create(document);
    }

    @GET
    @UnitOfWork
    public List<Document> listDocuments() {
        return documentDAO.findAll();
    }
}

但是我从客户端请求中收到了400的响应,请查看以下客户端请求。
Client client = Client.create();

WebResource webResource = client.resource("http://localhost:8080/documents");

String input = "{\"processed\":\"new process\",\"ProcessingSetID\":\"new iD\"}";

ClientResponse response = 
        webResource.type("application/json").post(ClientResponse.class, input);

if (response.getStatus() != 200) {
    throw new RuntimeException("Failed : HTTP error code : "
            + response.getStatus());
}

我试图调试这个问题,但是请求首先没有到达POST方法。似乎它没有从JSON字符串创建文档对象,但我找不到原因。此外,当我直接在数据库中进行输入并进行GET调用时,会收到完美的JSON字符串等效对象。

5个回答

8

要获取与400错误相关的有用信息,请在Jersey上注册此内容:

environment.jersey().register(new JsonProcessingExceptionMapper(true));

它可以提供更详细的400响应消息,对于调试非常有用。


2
这非常完美,应该被接受为答案。该功能甚至应该在Dropwizard中默认开启... - Doches

5
一些背景信息:Dropwizard使用Jersey,而Jersey最终会返回400 Bad Request响应,可能还伴随着一个模糊而简洁的消息。
为了确切地知道Jackson有什么问题(反过来影响Jersey),我首先发送了一个空的JSON对象,并查看它是否被接受(确实如此——POJO中的所有字段都是零初始化的)。然后我开始添加字段,每次发送这样的对象,直到达到有问题的字段(在我的情况下,它是一个应该是Boolean而不是boolean的字段)。
我认为我能够发现你的POJO(Document类)中存在两个困难。
  1. 获取器/设置器应该用 @JsonProperty 进行注释。

  2. 尝试将 Id 的类型更改为 Long(可为空的长整型)。如果您担心在该字段中获得 null,则可以使 getter 方法返回零或任何默认值。


1
你发布“从零开始,逐步提高”的方法论真是太棒了,这让我摆脱了困境。 - barclay
你的问题领域是什么? - MrMister
哦,原来是日期时间字符串的格式问题。我在日期和时间之间加了一个空格。我把它替换成了 T,问题就解决了。 - barclay

1
我遇到了同样的问题。错误被抑制了,并且在堆栈跟踪中没有正确传递。我所做的是在函数周围添加try catch。然后在异常中添加调试器断点。我能够找出确切的原因。
你可以尝试类似这样的方法。
@POST
@UnitOfWork
public Document createDocument(Document document) throws Exception{
....
}

在异常类中添加调试点。这样你就能找到解析失败的确切原因。
希望我表述清楚了并且有所帮助!

0

Http状态码400表示“错误请求”。这意味着您发送的JSON不是有效的文档。 这又意味着您将永远无法访问正文。

@POST
@UnitOfWork
public Document createDocument(Document document){}

要解决这个问题,请尝试传递json:

String input = "{\"id\":\"123456789\",\"processed\":\"new process\",\"ProcessingSetID\":\"new iD\"}";

123456789替换为您的实际ID。

附注:根据您的情况,创建Document的DTO而不是传递实际实体可能是个好主意。


0

如果您在Dropwizard的*Application.java中的run(...)方法中注册Jersey的CsrfProtectionFilter,请确保将X-Requested-By头添加到所有状态更改的HTTP调用(POSTPUT等)中。如果请求中未找到该标头,则服务器将返回HTTP 400 Bad Request


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接