简化REST URL与JSON参数

问题描述 投票:1回答:3

我被分配一个任务,我真的不知道如何甚至开始解决它,所以任何帮助,将不胜感激。请看下面的例子:

@Path("/v1/{server}:{port}/instance")  
public class WSInstance {
        private static final Log        log = LogFactory.getLog(WSInstance.class);

        private final String    PLANNING_PROPNAME = "**PLNG_NAME**";
        private final String    PLANNING_PROPVAL = "**CALENDAR_NAME**";

        @GET
        @Path("/{instanceName}")
        @Produces("text/plain")
        public String getInstanceStatus(@Context HttpHeaders headers, 
                @PathParam("server")String server, 
                @PathParam("port")int port,
                @PathParam("instanceName") String instName,
                @DefaultValue("") @QueryParam("date") String date,
                @DefaultValue("") @QueryParam("instnum") String numexec)
        {
            return getInstanceStatus(Utils.extractUserInfo(headers), server, port, instName, numexec, date);    
        }

上述方法调用的一个例子将是这样的:

/v1/serverName:portNumber/instance/toto?date=21090207&instnum=0000

什么任务要求是,以取代在该网址(serverNameportNumbertotodateinstnum)使用JSON参数的所有变量。这是为了简化REST URL。

任何想法从哪里开始?


**编辑:感谢大家对自己的答案,你肯定对我帮助很大。这是我迄今所做的:

我决定采取“简单”的类和方法与程序,熟悉自己。所以我把这个:

@Path("/v2/{server}:{port}/admin/")
public class WSAdmin {
    private static final Log log    = LogFactory.getLog(WSAdmin.class);

    @PUT
    @Path("/device")
    @Produces("text/plain")
    @Consumes("application/json")
    public String putDevice(String jsonObject, @Context HttpHeaders headers,
                                    @PathParam("server")String server,
                                    @PathParam("port")int port)
    {
        ObjectMapper mapper = new ObjectMapper();

        try
        {
            return updateDevice(mapper.readTree(jsonObject), Utils.extractUserInfo(headers), server, port);
        }
        catch (JsonProcessingException e)
        {
            return e.getMessage();
        }
        catch (IOException e)
        {
            return e.getMessage();
        }
    }

我改成了这样:

@Path("/v2/admin/")
public class WSAdmin {
    private static final Log log    = LogFactory.getLog(WSAdmin.class);

    @POST
    @Path("/device")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response putDevice(Admin admin)
    {
            String output = admin.toString();
            return Response.status(200).entity(output).build();
    }

然后,我创建了相应的POJO:

@XmlRootElement
public class Admin {

    private String server;
    private int port;
    private Date date;
    private String instnum;

// Constructors + getters + setters

    @Override
    public String toString() {
        return new StringBuffer("Server: ").append(this.server)
                .append("Port: ").append(this.port).append("Date: ")
                .append(this.date).append("InstNum: ")
                .append(this.instnum).toString();
    }
}

然后,我编辑的web.xml文件,以便能够编组和取消编组的Java OBJETS:

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

但由于某些原因,我得到以下错误,当我拨打电话从邮递员:

GRAVE [http-nio-8080-exec-5] com.sun.jersey.spi.container.ContainerRequest.getEntity A message body reader for Java class com.ws.v3.models.Admin, and Java type class com.ws.v3.models.Admin, and MIME media type application/json was not found.
The registered message body readers compatible with the MIME media type are:
application/json ->
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$App
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$App
*/* ->
  com.sun.jersey.core.impl.provider.entity.FormProvider
  com.sun.jersey.core.impl.provider.entity.StringProvider
  com.sun.jersey.core.impl.provider.entity.ByteArrayProvider
  com.sun.jersey.core.impl.provider.entity.FileProvider
  com.sun.jersey.core.impl.provider.entity.InputStreamProvider
  com.sun.jersey.core.impl.provider.entity.DataSourceProvider
  com.sun.jersey.core.impl.provider.entity.XMLJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.ReaderProvider
  com.sun.jersey.core.impl.provider.entity.DocumentProvider
  com.sun.jersey.core.impl.provider.entity.SourceProvider$StreamSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$SAXSourceReader
  com.sun.jersey.core.impl.provider.entity.SourceProvider$DOMSourceReader
  com.sun.jersey.json.impl.provider.entity.JSONJAXBElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLListElementProvider$General
  com.sun.jersey.core.impl.provider.entity.XMLRootObjectProvider$General
  com.sun.jersey.core.impl.provider.entity.EntityHolderReader
  com.sun.jersey.json.impl.provider.entity.JSONRootElementProvider$General
  com.sun.jersey.json.impl.provider.entity.JSONListElementProvider$General

这些谁也有类似的错误得到它通过增加或者gersonjersey-jsonin pom.xml中消失。我已经添加了他们,但问题并没有得到解决。

任何想法?

java json rest maven jersey
3个回答
0
投票

大概必须更改方法类型到POST并传递数据作为JSON在请求的主体中。

GET请求

GET /v1/yourServerName:8080/instance/toto?date=21090207&instnum=0000

可以成为以下POST请求

POST /v1/instance
{
  "serverName":"yourServerName",
  "portNumber":8080,
  "date":21090207,
  "instnum":"0000"
}

需要注意的是instnum是不是数字字段,因为你传递的字符串0000不能被表示为一个数值。相反portNumberdate可以是数字值。


0
投票

考虑使用杰克逊。杰克逊地图JSON < - >对象。阅读关于如何通过泽西岛(REST)在这里使用它:https://www.mkyong.com/webservices/jax-rs/json-example-with-jersey-jackson/


0
投票

每一个specification请求GET的有效载荷是未定义的。你应该,therfore,从发送体用GET请求制止。正如达维德已经建议你应该切换到这里,而不是POST,这里收到的有效载荷的语义由您定义,服务器/ API维护者。

然而,当你标记您的文章与你或许应该考虑复制在网络中使用的概念为超过20年,现在它翻译成你的API的设计。首先,REST架构不关心你的URI的结构。该URI本身只是一个指向资源和客户应该不需要解释,也没有破解它。需要为客户做出与众不同的选择的所有信息都应该由服务器开始提供。随着客户不应该分析和解释的URI他们如何确定一个URI是否是使用客户端或不是?

那么,我们如何与人类在网络页面的URI互动?通常它们被注释与总结了链接的内容(与本说明书中即高于)人类可读的文本。这些简短而有意义的名字,通常被称为链接关系的名称和应“attachted”每个URI。客户端阅读这样的链接关系的名字,只是调用伴随URI将能够继续工作,如果服务器曾经有需要改变它的URI结构。这是对从服务器去耦客户一个重要步骤。这样的链接关系的名字应该是standardized但也可以common knowlege指定,或在媒体类型本身指定。

一个常见的错误很多所谓的“REST API的”做的是为支持application/xml和/或application/json只。这些都是非常差的媒体类型的REST架构,因为他们只定义的语法使用,但没有相应的元素的语义。因此难的客户端来确定这样的文件的意图,并易于落入陷阱typed resource并假定某个资源具有一定的类型。如果这样的(非标准化)表示的变化,很可能是高是客户端将打破与该服务/ API进一步进行互操作。

媒体类型有一定接收的负载应该帮助给接收内容的一些意义,它可能会用它来做更多或更少的标准化处理规则。一个可能公知的介质类型是HTML时某些元件是可行的,并且每个元件具有约束定义。它还定义元素如何某些被渲染和它是如何落后与前版本兼容。这是事实上的标准,当涉及到的链接和链接关系的支持。虽然HALCollection+JSON,...是步入中的支持链接和相关名词术语的正确方向,他们远离提供相同的语义HTML呢,虽然他们应该是最好平原JSON因为它们不仅指定某些元素如_links即它的语法,但也语义帮助客户区分内容的链接。

媒体类型是在客户端向服务器请求返回的表示格式的客户端可以理解的内容类型协商的条款尤为重要。如果服务器不能够产生这样的表示,将通知客户有足够的表现错误代码(406)。如果服务器无法处理客户端所提供的媒体类型(在POST,PUT,PATCH,...操作)也将通知客户端,它不理解这样的格式(415)。

在设计的REST API一般的建议是,在Web服务器方面,也与德兴像整个互动想到的API。即如果客户端具有执行certian输入它不应该与一些随机领域(在一些外部文件中指定)发送到服务器只是一个儿戏JSON文件,但服务器应该讲授如何发送这样的开始与请求的客户端。类似于Web表单,其中人类应该输入文字之类的东西,REST API应该返回表示,教客户,哪些字段服务器期望,要使用的操作和目标发送有效载荷的公式推一个媒体类型。

在关于实际问题,我不知道为什么你的员工是在消除从URI参数如此热衷。正如我在上发送有效载荷第一段提到你需要切换到POST,因此自动失去保证safeidempotent功能GET操作,除了不是默认缓存。

你可以做的是,即允许用户或你的同事预先配置某些查询,并为这些预配置的URI短/微小的URL。在这里,你应该提供一个形式,如媒体类型的客户端在那里可以选择可供选择,进入进一步的必要数据的选项。一旦你收到这样的请求,你存储这样的预配置,并返回一个短/微小URL在响应的位置标头预配置。您还应该添加预配置的链接在常规反应,从而使客户能够调用它,如果它不将其存储持久性之后。通过这样做,你仍然有GET操作的优点,同时具有灵活地添加新的或定制现有查询的飞行。正如前面提到的,客户端将无法取得多大的使用等环节的普通application/json表示。如果客户端支持application/hal+json它至少会知道什么是链接关系,链接,因此能够查找并通过其附带的链接关系的名字调用URI。这基本上给你的自由,如果需要在不影响客户以后更改URI结构。

© www.soinside.com 2019 - 2024. All rights reserved.