如何用卷曲来测试Java的RESTful Web服务 - 与PUT动词的问题(How to test

2019-10-22 05:02发布

我想我的第一个Java RESTful Web服务,也许我没有明确的机制。

这里我的代码示例:

@Path(Paths.USERS)
public class UserService {

    private static final String OK_MESSAGE_USERSERVICE_PUT = Messages.OK_MESSAGE_USERSERVICE_PUT;
    private Client esClient = ElasticSearch.getClient();

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public String get(@QueryParam(QParams.ID) String id) {
        // TODO Authentication
        try {
            GetResponse response = esClient
                    .prepareGet(PRIMARY_INDEX_NAME, USERS_TYPE_NAME, id)
                    .execute().actionGet();

            if (response != null) {
                return response.getSourceAsString();
            }


        }catch (ElasticsearchException e) {
            e.printStackTrace();
            return e.getMessage();
        }
        return Messages.RESOURCE_NOT_FOUND;
    }

    @PUT
    @Consumes(MediaType.APPLICATION_JSON)
    public String update(@QueryParam(QParams.ID) String id,
            @PathParam("metadata") String metadata) {
        // TODO Authentication
        boolean isMyself = true;

        // precondition, the user exsists. If the check fails, you
        // should put the isMyself flag at false.
        if (isMyself){

                    esClient
                    .prepareIndex(PRIMARY_INDEX_NAME, USERS_TYPE_NAME, id)
                    .setSource(metadata).execute().actionGet();
        }

        return OK_MESSAGE_USERSERVICE_PUT;
    }

我的问题是:

我应该如何通过元数据到Web服务? 我试着用

 curl -g -X PUT 'http://localhost:8080/geocon/users?id=007&metadata={"name":{"first":"james","last":"bond"}}'

但我遇到这样的错误

根本原因:java.net.URISyntaxException:?/ GEOCON /用户ID = 007&元=%7B “名”:%7B “第一”: “詹姆斯”, “最后的”: “债券” %的指数33在查询非法字符7D%7D

  java.net.URI中的$ Parser.fail(URI.java:2848) 

谷歌搜索的时候,我已经试过这不同的解决方案:

curl -X PUT -H "application/json" -d '{"name":{"first":"james","last":"bond"}}' http://localhost:8080/geocon/users/

但这种做法,我不知道如何传递到Web服务我的意志更新与ID 007的用户(因为,据我所知,我只是传达{“名”:{“第一”:“詹姆斯”, “最后一个”: “债券”}})。

你会怎么做? 谢谢!

Answer 1:

我将完全重构这个解决方案。

首先:更改URL方案,使URI路径的ID部分。 这是一个比较RESTful方法

@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public String update(@PathParam("id") String id) {

二:请求实体主体应该是JSON。 我看不出有任何理由为这是“元数据”。 你可以摆脱那干脆。 要更新与您发送的数据资源表示,所以这应该是身体的一部分。

第三:如果你使用JSON的工作,你应该利用POJO的映射与像杰克逊的供应商。 这将自动收杆的JSON到一个POJO。 你可以这样做

public class Agent {
    private Name name;
    // getters and setters

    public static class Name {
        private String first;
        private String last;
        // getters and setters
    }  
}

然后,只需有Agent的方法签名的说法,表示它是请求的主体。

@PUT
@Path("{id}")
@Consumes(MediaType.APPLICATION_JSON)
public String update(@PathParam("id") String id, Agent agent) {

您需要在杰克逊提供程序添加到项目中。 希望你是使用Maven。 你可以加

<dependency>
    <groupId>com.fasterxml.jackson.jaxrs</groupId>
    <artifactId>jackson-jaxrs-json-provider</artifactId>
    <version>2.4.0</version>
</dependency>

然后在你的应用程序配置,注册JacksonJsonProvider 。 如果您需要这方面的帮助,然后告诉你如何配置你的应用程序(无论是web.xml文件或Application子类)。 如果你想跳过这个POJO映射和刚刚得到的原始JSON,刚刚设置的方法参数类型String ,你已经在做(只是没有标注)

第四:那么您的要求将是(我在Windows上,我们需要用双引号和逃避内部引号)

curl -v -X PUT
        -H "Content-Type:application/json"
        -d "{\"name\":{\"first\":\"james\", \"last\":\"bond\"}}"
        http://localhost:8080/geocon/users/007

第五:我会改变@GET方法,也使URL路径的ID部分,而不是查询参数。



Answer 2:

它看起来像你混的参数传递给该方法GET请求( ?foo=bar )与PUT方法,它更像是POST

我期望您在JSON数据发送到像一个URL /gecon/user/13有你的URL映射正确编辑后,当然。

尝试阅读维基百科和这个答案 。



文章来源: How to test a Java RESTful web service with curl - problems with PUT verb