如何使用curl测试Java RESTful Web服务-PUT动词问题 [英] How to test a Java RESTful web service with curl - problems with PUT verb

查看:102
本文介绍了如何使用curl测试Java RESTful Web服务-PUT动词问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试我的第一个Java RESTful Web服务,可能我不清楚一些机制.

I'm trying my first Java RESTful web service and probably I don't have clear some mechanisms.

这是我的代码示例:

@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:索引33处查询中的非法字符:/geocon/users?id = 007&adata =%7B"name":%7B"first":"james","last" :债券"%7D%7D

Root Cause: java.net.URISyntaxException: Illegal character in query at index 33: /geocon/users?id=007&metadata=%7B"name":%7B"first":"james","last":"bond"%7D%7D

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

Googling around, I've tried this different solution:

Googling around, I've tried this different solution:

但是使用这种方法,我不知道如何将更新ID为007的用户的意愿传递给Web服务(因为AFAIK,我只传达{"name":{"first":"james," last:" bond}}).

but with this approach, I don't know how to pass to the web service my will of updating the user with ID 007 (since, AFAIK, I'm only communicating {"name":{"first":"james","last":"bond"}}).

你会怎么做?谢谢!

推荐答案

我将完全重构此解决方案.

I would completely refactor this solution.

首先:更改url方案以使id成为URI路径的一部分.这是一种更RESTful的方法

First: Change the url scheme to make the id part of the URI path. This is a more RESTful approach

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

第二:请求实体正文应为JSON.我认为这没有任何理由成为元数据".您可以完全摆脱它.您想用发送的数据更新资源表示形式,因此这应该是正文的一部分.

Second: The request entity body should be the JSON. I don't see any reason for this to be "metadata". You can get rid of that altogether. You want to update the resource representation with the data you are sending, so this should be part of the body.

第三步::如果您使用的是JSON,则应使用Jackson之类的提供程序使用Pojo Mapping.这将自动将JSON解析为Pojo.您可以做类似的事情

Third: If you're working with JSON, you should take advantage of Pojo Mapping with a provider like Jackson. This will automatically pars the JSON to a Pojo. You can do something like

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

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

然后在方法签名中仅包含Agent参数,表明它是请求的正文.

Then just have the Agent argument in the method signature, signifying that it is the body of the request.

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

您需要将Jackson提供程序添加到项目中.希望您正在使用Maven.您可以添加

You will need to add the Jackson provider to the project. Hopefully you are using Maven. You can add

<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,就像您已经在做的一样(没有注释)

Then in your application configuration, register the JacksonJsonProvider. If you need help with this, then show how you are configuration your application (whether web.xml or an Application subclass). If you want to skip the Pojo mapping and just get the raw JSON, the just set the method argument type to String as you already are doing (just without the annotation)

第四:然后,您的请求将是(我在Windows上,我们需要使用双引号并转义内部引号)

Fourth: Then your request would be (I'm on Windows, where we need to use double quotes and escape the interior quotes)

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

第五步:我也将更改@GET方法,以使id成为URL路径的一部分,而不是查询参数.

Fifth: I would change the @GET method also, to make the id part of the URL path, instead of a query param.

这篇关于如何使用curl测试Java RESTful Web服务-PUT动词问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆