using sub resources with jax-rs


Direct Initialization

그냥 새로 만들고 돌아가는 데에 필요한 값들을 직접 설정한다.

@Path("/parents")
public class ParentsResource {

    @Path("/{parentId: \\d+}/children");
    public SubResource resourceSubResource(
            @PathParam("parentId") final long parentId) {
        return new ChildrenResource()
                .parentId(parentId)
                .persistenceService(persistenceService);
    }

    @Inject
    private PersistenceService persistenceService;
}

ResourceContext

ResourceContext를 이용하여 생성한다. 필요한 값들은 알아서 주입된다.

@Path("/parents")
public class ParentsResource {

    @Path("/{parentId: \\d+}/children");
    public SubResource resourceSubResource(
            @PathParam("parentId") final long parentId) {
        return resourceContext.getResource(ChildrenResource.class);
    }

    @Context
    private ResourceContext resourceContext;

    @Inject
    private PersistenceService persistenceService;
}

Direct Injection

Sub Resource 자체를 직접 주입받아서 사용한다.

@Path("/parents")
public class ParentsResource {

    @Path("/{parentId: \\d+}/children");
    public SubResource resourceSubResource(
            @PathParam("parentId") final long parentId) {
        return childrenResource;
    }

    @Inject
    private PersistenceService persistenceService;

    @Inject
    private ChildrenResource childrenResource;
}

이 경우 주의할 점이 하나 있는데, childrenResource 개체가 주입되는 시점이 그 리소스가 실제로 사용될 시점보다 앞선다는 점이다. 다음과 같이 ChildrenResource 클래스에서 @PostContruct 같은 생명주기 어노테이션을 사용할 경우 없는 값을 사용할 수 있다.
다음 코드를 기반으로 /parents 혹은 /parents/1 까지만 호출 했을 경우에도 childrenResource 는 주입이 되고, 그렇게 주입되기 전에 childrenResource 자체의 모든 주입위치에도 값들이 주입되게 되는데 아래와 같이 에러를 발생할 소지가 있다.

public class ChildrenResource {

    @PostConstruct
    private void fetchMatrix() {
        //parentName // NullPointerExeption
        //    = children.getMatrixParameters().getFirst("parentName");
    }

    @PathParam("children")
    private PathSegment children; // maybe null

    private String parentName;
}

다음과 같이 Optional을 사용할 수도 있지만 그리 좋다고는 볼 수 없다.

        parentName = ofNullable(children)
                .map(v -> v.getMatrixParameters().getFirst("parentName"))
                .orElse(null);

ResourceContext 클래스를 괜히, 늦게나마, 만들어 놓은게 아닌 듯 하다.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s