java - 如何在 JAX-RS 中实现 HTTP 方法的默认功能?

标签 java rest jax-rs

我正在使用 JAX-RS,它具有 @OPTIONS@HEAD 方法的默认实现,但我想提供不同的功能。

我目前所做的是:

@GET
@Path("path/to/resource")
@Produces(MediaType.APPLICATION_JSON)
public Response resourceCall(){
    // Normal method implementation
}

@OPTIONS
@Path("path/to/resource")
@Produces(MediaType.APPLICATION_JSON)
public Response resourceCall(){
    Response.status(Response.Status.METHOD_NOT_ALLOWED).build();
}

所以基本上我对我的每一项资源都创建了一个新的调用。但我希望这里有一个catch-all方法来处理我对@OPTION@HEAD的所有调用。

如何实现这样的功能?

编辑

只是为了清楚起见。我知道如何使用 Servlet 过滤器来执行此操作,但我想知道 JAX-RS 是否针对特定情况内置了类似的功能。

最佳答案

由于您使用的是 Jersey,Jersey 具有一项功能,允许您 programmatically add and modify resources 。所以你可以添加 OPTIONSHEAD方法来访问您的所有资源,而无需触及您的资源类。下面是一个示例,除了发送带有 No <Method> 的 405 之外什么也不做。信息。可能不是您想要的,但您应该能够弄清楚需要修改哪些内容才能获得您想要的。

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.core.Configuration;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
import org.glassfish.jersey.process.Inflector;
import org.glassfish.jersey.server.model.ModelProcessor;
import org.glassfish.jersey.server.model.Resource;
import org.glassfish.jersey.server.model.ResourceModel;

@Provider
public class HeadAndOptionsModelProcessor implements ModelProcessor {

    @Override
    public ResourceModel processResourceModel(ResourceModel resourceModel,
            Configuration configuration) {
        ResourceModel.Builder resourceModelBuilder = new ResourceModel.Builder(false);
        for (Resource rootResource: resourceModel.getResources()) {
            final Resource.Builder rootResourceBuilder = Resource.builder(rootResource);
            addOptions(rootResourceBuilder);
            addHead(rootResourceBuilder);

            for (Resource childResource: rootResource.getChildResources()) {
                final Resource.Builder childResourceBuilder = Resource.builder(childResource);
                addOptions(childResourceBuilder);
                addHead(childResourceBuilder);
                rootResourceBuilder.addChildResource(childResourceBuilder.build());
            }
            resourceModelBuilder.addResource(rootResourceBuilder.build());
        }
        return resourceModelBuilder.build();
    }

    @Override
    public ResourceModel processSubResource(ResourceModel subResourceModel,
            Configuration configuration) {
        return subResourceModel;
    }

    private void addOptions(Resource.Builder resourceBuilder) {
        resourceBuilder.addMethod("OPTIONS")
                .handledBy(new Inflector<ContainerRequestContext, Response>() {
                    @Override
                    public Response apply(ContainerRequestContext context) {
                        return getOptionsResponse(context);
                    }
                }).produces(MediaType.TEXT_PLAIN).extended(true);
    }

    private void addHead(Resource.Builder resourceBuilder) {
        resourceBuilder.addMethod("HEAD")
                .handledBy(new Inflector<ContainerRequestContext, Response>() {
                    @Override
                    public Response apply(ContainerRequestContext context) {
                        return getHeadResponse(context);
                    }
                }).produces(MediaType.TEXT_PLAIN).extended(true);
    }

    private static Response getOptionsResponse(ContainerRequestContext context) {
        return Response.status(Response.Status.METHOD_NOT_ALLOWED).entity("No Options").build();
    }

    private static Response getHeadResponse(ContainerRequestContext context) {
        return Response.status(Response.Status.METHOD_NOT_ALLOWED).entity("No Head").build();
    }
}

关于java - 如何在 JAX-RS 中实现 HTTP 方法的默认功能?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35300898/

相关文章:

java - 从用户获取 http 请求并使用 REST API 将该变量值存储到任何数据结构中

php - Moodle REST API 响应中的 privatetoken 有什么用?

java - 使用 Springfox 记录 Spring 应用程序中的 jax-rs 服务

java - 返回 HttpServletRequest 的响应 (HttpServletResponse)

java - 使用sdkman安装后如何设置gradle路径

java - 在带有Scene2D的LibGDX中,按下按钮时如何连续向右行走?

资源 URL 中的 RESTful 查询字符串

spring - 如何使用 Spring Boot 1.5.2 注入(inject) Jersey 端点接口(interface)的实现?

java - 如何编写Java程序来打开特定的文件扩展名(.pef)?

java - 使用线程池时,如何让Java中的线程空闲?