Tagged: jersey

profiling different implementations for testing


I’m writing a small library which used JAX-RS API.

<dependency>
  <groupId>javax.ws.rs</groupId>
    <artifactId>javax.ws.rs-api</artifactId>
    <version>2.0.1</version>
    <scope>provided</scope>
</dependency>

Profiles can help for testing the code against each implementation.

<profile>
  <id>jersey</id>
  <activation>
    <activeByDefault>true</activeByDefault>
  </activation>
  <dependencies>
    <dependency>
      <groupId>org.glassfish.jersey.core</groupId>
      <artifactId>jersey-client</artifactId>
      <version>2.23.1</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</profile>    
<profile>
  <id>cxf</id>
  <dependencies>
    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-rs-client</artifactId>
      <version>3.1.6</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</profile>    
<profile>
  <id>resteasy</id>
  <dependencies>
    <dependency>
      <groupId>org.jboss.resteasy</groupId>
      <artifactId>resteasy-client</artifactId>
      <version>3.0.17.Final</version>
      <scope>test</scope>
    </dependency>
  </dependencies>
</profile>

Test against each implementation like this.

$ mvn -Pjersey verify
$ mvn -Pcxf verify
$ mvn -Presteasy verify

Unit-Testing JAX-RS with Jersey Test Framework and Weld


요 근래 JAX-RS에 기반한 라이브러리를 하나 만들던 중 단위 테스트에 문제가 생겨서 SO에 이것 저것 물어봤다.

References

JAX-RS

만들고 있는 라이브러리는 JAX-RS와 DI만 사용한다.

<dependency>
  <groupId>javax.inject</groupId>
  <artifactId>javax.inject</artifactId>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>javax.ws.rs</groupId>
  <artifactId>javax.ws.rs-api</artifactId>
  <scope>provided</scope>
</dependency>

Jersey Test Framework

단위 시험을 하기위해 다음과 같이 Jersey Test Framework을 추가하였다.

<dependency>
  <groupId>org.glassfish.jersey.test-framework.providers</groupId>
  <artifactId>jersey-test-framework-provider-grizzly2</artifactId>
  <scope>test</scope>
</dependency>

Weld

Jersey가 사용하고 있는 HK2(JSR-330)은 주입(injection)은 잘 수행하는 듯 하나 JSR-250에 해당하는 @PostConstruct 등은 수행하지 못한다. 다음과 같이 dependency를 추가했다.

<dependency>
  <groupId>org.glassfish.jersey.ext.cdi</groupId>
  <artifactId>jersey-weld2-se</artifactId>
  <scope>test</scope>
</dependency>

그리고 다음과 같이 Weld를 적용시켰다.

@Override
protected Application configure() {

    final Weld weld = new Weld();
    weld.initialize();
    Runtime.getRuntime().addShutdownHook(new Thread(() -> weld.shutdown()));

    // ...
}

suppressing application.wadl with jax-rs


@PreMatching
@Provider
public class EpdResourcesRequestFilter implements ContainerRequestFilter {

    @Override
    public void filter(final ContainerRequestContext requestContext)
        throws IOException {

        // abort any request whose uri includes ".wadl" with 404
        if (requestContext.getUriInfo().getPath().contains(".wadl")) {
            requestContext.abortWith(Response.status(Status.NOT_FOUND).build());
        }
    }

}

@MatrixParam with Jersey


With, currently the newest (3.1.2.2), GlassFish, @MatrixParam doesn’t work as expected.

http://.../path1/path2;value={value} does work,
http://.../path1;value={value}/path2 does not work.

And it’s still open.

One of workarounds is, as stated at Inheritance of duplicate @MatrixParam, using PathSegment along with @PathParam.

@GET
@Path("/{path1: path1}/path2")
public Resource read(
    @PathParam("path1") final PathSegment path1) {

    assert path1 != null;
    assert path1.getPath().equals("path1");

    final MultivaluedMap<String, String> matrixParameters = path1.getMatrixParameters();
    final List<String> values = matrixParameters.get("value");
    final String value = matrixParameters.getFirst("value");

    // ...
}

CRUD for RESTful Web Services


Jersey를 사용하지 않고 그냥 만들어야 할 경우 CRUD에 관계된 Resource URI와 HTTP Method가 종종 헷갈리는 경우가 있다.

plural
.../resources/items
singular
.../resources/items/1234
GET
<R>
모든 Item들을 반환한다.


<items>
  <item id="1233">...</item>
  <item id="1234">...</item>
</items>


1234에 해당하는 Item 1개를 반환한다.


<item id="1234">
  ...
</item>


PUT
<U>
모든 Item들을 교체한다. 1234에 해당하는 Item 1개의 내용을 갱신한다. 없으면 새로 만드는 게 아니라 Not Found(404)이다.
POST
<C>
새로운 Item을 생성한다. 이 때 사로이 생성된 Item의 uri를 CREATED(201)로 리턴한다. 1234에 해당하는 리소스를 plural resource으로 보고 그 안에 새로운 singular resource를 생성한다.
DELETE
<D>
다 날린다. 1234에 해당하는 Item 1개를 제거한다.