使用jetty客户端发布在restlet中提供null表示

时间:2015-07-29 09:38:27

标签: java jetty restlet

我在以下问题上被困了几个小时:

  • 我有一个Jetty嵌入式服务器,其Restlet应用程序(MyApplication)绑定到一个线程上的Restlet ServerResource(MyResource)
  • 我在主线程上有一个Jetty客户端,使用虚拟参数POST到服务器p = toto
  • 我启动导航器并浏览到http://localhost:8082/model以获得执行相同操作的html按钮 - 至少预期为 - POST请求(p = toto)

我目睹了以下行为:

  • 当通过Jetty客户端发布帖子时,给予MyResource.acceptItem的Representation为null。我只能通过调用getReference()获取表单然后获取参数.getQueryAsForm();
  • 当通过导航器发布帖子时,给予MyResource.acceptItem的Representation不为null。我可以通过新表格(实体)
  • 获取表格

所以我的问题是:触发这些行为的两个POST请求之间有什么区别?

这是输出(我们可以首先看到由jetty发出的POST,然后从导航器获取html表单,最后从导航器发出POST

11:26:33.140 [main] INFO  org.sample.Sample - launching server on port 8082
2015-07-29 11:26:33.203:INFO::main: Logging initialized @359ms
2015-07-29 11:26:33.375:INFO:oejs.Server:Thread-0: jetty-9.2.7.v20150116
2015-07-29 11:26:33.437:INFO:oejsh.ContextHandler:Thread-0: Started o.e.j.s.ServletContextHandler@24cca73f{/,null,AVAILABLE}
2015-07-29 11:26:33.437:INFO:oejs.ServerConnector:Thread-0: Started ServerConnector@746ab811{HTTP/1.1}{0.0.0.0:8082}
2015-07-29 11:26:33.437:INFO:oejs.Server:Thread-0: Started @609ms
11:26:35.312 [main] INFO  org.sample.Sample - now posting
2015-07-29 11:26:35.687:INFO:/:qtp115342900-21: org.restlet.ext.servlet.ServerServlet-27a1f635: [Restlet] ServerServlet: component class is null
2015-07-29 11:26:35.734:INFO:/:qtp115342900-21: org.restlet.ext.servlet.ServerServlet-27a1f635: [Restlet] Attaching application: org.sample.MyApplication@6e47c1bf to URI: 
11:26:35.828 [qtp115342900-21] INFO  org.sample.Sample - proceeding POST
11:26:35.828 [qtp115342900-21] WARN  org.sample.Sample - entity is null !
11:26:35.828 [qtp115342900-21] INFO  org.sample.Sample - param p : toto
juil. 29, 2015 11:26:35 AM org.restlet.engine.log.LogFilter afterHandle
INFO: 2015-07-29    11:26:35    127.0.0.1   -   127.0.0.1   8082    POST    /model  p=toto  204 0   0   63  http://localhost:8082   Jetty/9.2.7.v20150116   -
juil. 29, 2015 11:26:39 AM org.restlet.engine.log.LogFilter afterHandle
INFO: 2015-07-29    11:26:39    127.0.0.1   -   127.0.0.1   8082    GET /model  -   200 172 0   0   http://localhost:8082   Mozilla/5.0 (Windows NT 5.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0    -
11:26:43.515 [qtp115342900-22] INFO  org.sample.Sample - proceeding POST
11:26:43.515 [qtp115342900-22] INFO  org.sample.Sample - entity exists : [application/x-www-form-urlencoded,UTF-8]
11:26:43.515 [qtp115342900-22] INFO  org.sample.Sample - param p : toto
juil. 29, 2015 11:26:43 AM org.restlet.engine.log.LogFilter afterHandle
INFO: 2015-07-29    11:26:43    127.0.0.1   -   127.0.0.1   8082    POST    /model  -   204 0   6   0   http://localhost:8082   Mozilla/5.0 (Windows NT 5.2; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0    http://localhost:8082/model

这是我的项目: 的pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
                         http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.sample</groupId>
<artifactId>simple</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>Jetty Server with Restlet Sample</name>

<properties>
    <junit.version>4.12</junit.version>
    <slf4j.version>1.7.7</slf4j.version>
    <logback.version>1.1.2</logback.version>
    <jdk.version>1.7</jdk.version>
    <jetty.version>9.2.7.v20150116</jetty.version>
    <restlet.version>2.2.2</restlet.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

</properties>

<build>
    <!-- <finalName>atgm</finalName> -->
    <plugins>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>3.2</version>
            <configuration>
                <source>${jdk.version}</source>
                <target>${jdk.version}</target>
            </configuration>
        </plugin>
    </plugins>
</build>

<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>${slf4j.version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>${logback.version}</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>${logback.version}</version>
    </dependency>
    <dependency>
        <groupId>org.restlet.jee</groupId>
        <artifactId>org.restlet</artifactId>
        <version>${restlet.version}</version>
    </dependency>
    <dependency>
        <groupId>org.restlet.jee</groupId>
        <artifactId>org.restlet.ext.spring</artifactId>
        <version>${restlet.version}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-server</artifactId>
        <version>${jetty.version}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-servlet</artifactId>
        <version>${jetty.version}</version>
    </dependency>
    <dependency>
        <groupId>org.eclipse.jetty</groupId>
        <artifactId>jetty-client</artifactId>
        <version>${jetty.version}</version>
    </dependency>

</dependencies>

的src /主/ JAVA /组织/样品/ Sample.java

package org.sample;

import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.restlet.ext.servlet.ServerServlet;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Sample {
    private static final Logger LOGGER = LoggerFactory.getLogger(Sample.class);

    private static final int PORT=8082;

    private static Server server;


    public static void main (String []args) throws Exception {
        LOGGER.info("launching server on port "+PORT);
        new Thread() {
            @Override
            public void run() {
                try {
                    // now create the web server
                    server = new Server(PORT);

                    final ServletContextHandler servletContext = new ServletContextHandler(ServletContextHandler.SESSIONS);
                    servletContext.setContextPath("/");
                    servletContext.setInitParameter("org.restlet.application", MyApplication.class.getName());
                    servletContext.addServlet(ServerServlet.class, "/*");
                    servletContext.addServlet(DefaultServlet.class, "/");

                    server.setHandler(servletContext);
                    server.start();
                    server.join();

                } catch (Exception ex) {
                    LOGGER.info("Failed to start server", ex);
                }
            }
        }.start();

        HttpClient client = new HttpClient();
        client.start();

        // waiting for the server to be online
        final int lapse = 2000;
        Thread.sleep(lapse);

        LOGGER.info("now posting");
        client.POST("http://localhost:"+PORT+"/model")
        .param("p", "toto")
        .send();
    }
}

的src /主/ JAVA /组织/样品/ MyApplication.java

package org.sample;

import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Restlet;
import org.restlet.routing.Router;

public class MyApplication extends Application {
    public MyApplication () {
        super();
    }

    public MyApplication (Context parentContext) {
        super(parentContext);
    }

    @Override
    public Restlet createInboundRoot() {
        Router router = new Router(getContext());
        router.attach("/model", MyResource.class);
        return router;
    }
}

的src /主/ JAVA /组织/样品/ MyResource.java

package org.sample;

import org.restlet.data.Form;
import org.restlet.representation.Representation;
import org.restlet.resource.Get;
import org.restlet.resource.Post;
import org.restlet.resource.ServerResource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class MyResource extends ServerResource {
    private static final Logger LOGGER = LoggerFactory.getLogger(Sample.class);

    @Post
    public Representation acceptItem(Representation entity) throws Exception {
        Representation result = null;
        LOGGER.info("proceeding POST");
        Form form;
        if (null != entity) {
            LOGGER.info("entity exists : "+entity.toString());
            form = new Form(entity);
        } else {
            LOGGER.warn("entity is null !");
            form = getReference().getQueryAsForm();
        }
        LOGGER.info("param p : "+form.getFirstValue("p"));
        return result;
    }

    @Get("html")
    public String represent() {
        return "<html>"+
                "<head><script src=\"http://code.jquery.com/jquery-1.11.3.min.js\"></script></head>"+
                "<body>"+
                "<button onclick=\"$.post('model',{p:'toto'});\">POST</button>"+
                "</form>"+
                "</body>"+
                "</html>";
    }
}

1 个答案:

答案 0 :(得分:1)

我不确切知道你是如何从浏览器发出POST请求的,但这里有一些提示:

  • getQuery()对应于查询字符串中提供的元素。可能困扰你的是这些数据可以显示为表格。实际上,类Form类似于表单,并且不一定与有效负载相对应。因此,如果您使用这样的网址:http://localhost:8082/model?p=toto,参数p将出现在查询参数中
  • 收到的表示(类似于getEntity())对应于有效载荷。如果您使用内容类型application/x-www-form-urlencoded,它可以是一个表单,但通常它实际上不是表单。在第一种情况下,您可以从表示/实体创建Form实例。因此,如果您使用此类请求,您的代表/实体中将有一个名为p的条目:

    POST /model
    Content-Type:application/x-www-form-urlencoded
    
    p=toto
    

如果您想使用Jetty客户端创建此类请求,则需要更新以下代码:

Field p = new Field("p", "toto");
Fields fields = new Fields();
fields.put(p);

client.POST("http://localhost:"+PORT+"/model")
      .content(new FormContentProvider(fields))
      .send();

希望它可以帮到你, 亨利