Dropwizard示例在创建新资源时给出400错误

dev*_*esh 5 java rest json dropwizard

我是Dropwizard框架的新手。我正在尝试创建一个新资源,该资源类似于此处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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我的文件道就是这样,

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"));
}
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试在文档资源上调用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();
    }
}
Run Code Online (Sandbox Code Playgroud)

但是我从客户请求中得到了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());
}
Run Code Online (Sandbox Code Playgroud)

我尝试调试问题,但该调用最初没有到达POST方法。似乎它不是从JSON字符串创建文档对象,但我看不到原因。另外,当我直接在数据库中输入条目并进行GET调用时,会收到与object等效的完美JSON字符串。

cak*_*aww 8

要获得有关 400 错误的有用消息,请在球衣上注册:

environment.jersey().register(new JsonProcessingExceptionMapper(true));
Run Code Online (Sandbox Code Playgroud)

它将提供有关 400 响应的更详细消息,对调试很有用。

  • 这是完美的,应该是公认的答案。天哪,它应该在 Dropwizard 中默认打开...... (2认同)

MrM*_*ter 5

一点背景:Dropwizard 使用 Jersey,而 Jersey 是最终给你回复的东西400 Bad Request,可能伴随着模糊和简洁的信息。

为了确切了解是什么困扰了杰克逊(这反过来又困扰了泽西岛),我首先发送一个空白(空)JSON 对象并查看它是否被接受(它确实被接受了 - 以及 POJO 中零初始化的所有字段)。然后我开始添加字段,发送每个这样的对象,直到我到达有问题的字段(在我的例子中它是一个boolean应该是 a 的字段Boolean)。

我想我可以在你的 POJO(Document课程)中发现两个困难:

  1. getter / setter方法应该被标注@JsonProperty

  2. 尝试将Id的类型更改为Long(nullable long)。如果您担心null在该字段中获取 a ,则可以让 getter 返回零或任何默认值。


小智 0

HTTP 状态 400 表示“错误请求”。确实如此,您发送的 json 不是有效的Document. 这反过来意味着你永远无法到达

@POST
@UnitOfWork
public Document createDocument(Document document){}
Run Code Online (Sandbox Code Playgroud)

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

String input = "{\"id\":\"123456789\",\"processed\":\"new process\",\"ProcessingSetID\":\"new iD\"}";
Run Code Online (Sandbox Code Playgroud)

替换123456789为您的实际 ID。

附言。创建 DTO 而不是Document传递实际实体可能是一个好主意(取决于您的场景)。