Restlet client resource “not modified” condition

2019-07-07 19:12发布

问题:

I've got a Restlet based application, and I'm trying to use Restlet client resources to test certain parts of it.

Since upgrading from Restlet 2.2.3 to 2.3.4, my ETag verification tests have started failing. Here's how I was adding the header in the old version:

Series<Header> headers = (Series<Header>) currentClientResource.getRequest().getAttributes().get("org.restlet.http.headers");
if (headers == null) {
    headers = new Series<Header>(Header.class);
}
headers.add("If-None-Match", "\"" + eTag + "\"");
currentClientResource.getRequestAttributes().put("org.restlet.http.headers", headers);

Then when calling represent() again on the wrapped clientResource I was getting a 304 Not Modified response (which is what I want).

In 2.3.4 this started returning a 200 OK instead, and I noticed a log message about not setting the If-None-Match header directly. Instead I'm now trying this:

currentClientResource.getRequest().getConditions().getNoneMatch().add(new Tag(eTag));

However this is still giving me a 200 OK. If I do the request manually through a REST client I can get a 304 Not Modified, so the server is still doing the right behavior. What do I need to do in the tests to see what I want to see?

回答1:

I made a try and it works for me with version 2.3.4 of Restlet.

Here is what I did:

  • The Maven dependencies for my test

    <project>
      <modelVersion>4.0.0</modelVersion>
      (...)
    
      <properties>
        <java-version>1.7</java-version>
        <restlet-version>2.3.4</restlet-version>
      </properties>
    
      <dependencies>
        <dependency>
          <groupId>org.restlet.jse</groupId>
          <artifactId>org.restlet</artifactId>
          <version>${restlet-version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.restlet.jse</groupId>
          <artifactId>org.restlet.ext.jetty</artifactId>
          <version>${restlet-version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.restlet.jse</groupId>
          <artifactId>org.restlet.ext.jackson</artifactId>
          <version>${restlet-version}</version>
        </dependency>
    
        <dependency>
          <groupId>org.restlet.jse</groupId>
          <artifactId>org.restlet.ext.crypto</artifactId>
          <version>${restlet-version}</version>
        </dependency>
      </dependencies>
    
      <repositories>
        <repository>
          <id>maven-restlet</id>
          <name>Public online Restlet repository</name>
          <url>http://maven.restlet.com</url>
        </repository>
      </repositories>
    </project>
    
  • A server resource that sets the etag on the returned representation:

    public class ETagServerResource extends ServerResource {
      @Get
      public Representation test() {
        String test = "test";
        String md5 = DigestUtils.toMd5(test);
    
        StringRepresentation repr = new StringRepresentation(test);
        repr.setTag(new Tag(md5));
        return repr;
      }
    }
    
  • The client that makes two calls: a first one without the etag and a second one with the etag that should return a 304 status code.

    // First call
    ClientResource cr
         = new ClientResource("http://localhost:8182/test");
    Representation repr = cr.get();
    Tag tag = repr.getTag();
    System.out.println(">> cr = "+cr); // Status code: 200
    
    // Second call
    cr.getRequest().getConditions().getNoneMatch().add(tag);
    cr.get();
    System.out.println(">> cr = "+cr); // Status code: 304
    

I don't know what you use within the server resource. Feel free to tell me.

Hope it helps you, Thierry