栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

将Spring属性占位符与Jersey @Path和@ApplicationPath一起使用

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

将Spring属性占位符与Jersey @Path和@ApplicationPath一起使用

因此,这是答案的一半(或者可能是一个完整的答案,具体取决于解决方案

@ApplicationPath
对您的重要性)。

要了解以下解决方案,您应该首先了解Jersey的内部构造。当我们加载应用程序时,Jersey将构建所有资源的模型。资源的所有信息都封装在此模型中。Jersey使用此模型来处理请求,而不是尝试处理每个请求上的资源,而是将有关资源的所有信息保留在模型中并进行处理会更快。

借助这种架构,Jersey还允许我们使用与内部使用的相同API
来以编程方式构建资源,以保存模型属性。除了 构建 资源模型之外,我们还可以使用来 修改
现有模型

ModelProcessor

在中

ModelProcessor
,我们可以注入Spring的
PropertyResolver
,然后以编程方式解析占位符,并用已解析的占位符替换旧的资源模型路径。例如

@Autowiredprivate PropertyResolver propertyResolver;private ResourceModel processResourceModel(ResourceModel resourceModel) {    ResourceModel.Builder newResourceModelBuilder = new ResourceModel.Builder(false);    for (final Resource resource : resourceModel.getResources()) {        final Resource.Builder resourceBuilder = Resource.builder(resource);        String resolvedResourcePath = processPropertyPlaceholder(resource);        resourceBuilder.path(resolvedResourcePath);        // handle child resources        for (Resource childResource : resource.getChildResources()) { String resolvedChildPath = processPropertyPlaceholder(childResource); final Resource.Builder childResourceBuilder = Resource.builder(childResource); childResourceBuilder.path(resolvedChildPath);     resourceBuilder.addChildResource(childResourceBuilder.build());        }        newResourceModelBuilder.addResource(resourceBuilder.build());    }    return newResourceModelBuilder.build();}private String processPropertyPlaceholder(Resource resource) {    String ogPath = resource.getPath();    return propertyResolver.resolvePlaceholders(ogPath);}

就资源模型API而言

  • 这是一个
    Resource
@Path("resource")public class SomeResource {@GETpublic String get() {}}

注释的资源方法

@Path
ResourceMethod
s

  • 这是上述内容的 孩子
    Resource
    Resource
    因为带有注释
    @Path
@GET@Path("child-resource")public String get() {}

此信息应使您对上述实现的工作原理有所了解。

以下是使用Jersey测试框架的完整测试。使用以下类路径属性文件

app.properties

resource=resourcesub.resource=sub-resourcesub.resource.locator=sub-resource-locator

您可以像执行其他任何JUnit测试一样运行以下命令。

import javax.ws.rs.GET;import javax.ws.rs.Path;import javax.ws.rs.core.Response;import org.glassfish.jersey.filter.LoggingFilter;import org.glassfish.jersey.server.ResourceConfig;import org.glassfish.jersey.server.model.ModelProcessor;import org.glassfish.jersey.server.model.Resource;import org.glassfish.jersey.server.model.ResourceModel;import org.glassfish.jersey.test.JerseyTest;import org.junit.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.context.ApplicationContext;import org.springframework.context.annotation.AnnotationConfigApplicationContext;import org.springframework.context.annotation.Configuration;import org.springframework.context.annotation.PropertySource;import org.springframework.core.env.PropertyResolver;import static org.hamcrest.CoreMatchers.equalTo;import static org.hamcrest.CoreMatchers.is;import static org.junit.Assert.assertThat;public class SpringPathResolverTest extends JerseyTest {    @Path("${resource}")    public static class TestResource {        @GET        public String get() { return "Resource Success!";        }        @GET        @Path("${sub.resource}")        public String getSubMethod() { return "Sub-Resource Success!";        }        @Path("${sub.resource.locator}")        public SubResourceLocator getSubResourceLocator() { return new SubResourceLocator();        }        public static class SubResourceLocator { @GET public String get() {     return "Sub-Resource-Locator Success!"; }        }    }    @Configuration    @PropertySource("classpath:/app.properties")    public static class SpringConfig {    }    public static class PropertyPlaceholderPathResolvingModelProcessor implements ModelProcessor {        @Autowired        private PropertyResolver propertyResolver;        @Override        public ResourceModel processResourceModel(ResourceModel resourceModel,     javax.ws.rs.core.Configuration configuration) { return processResourceModel(resourceModel);        }        @Override        public ResourceModel processSubResource(ResourceModel subResourceModel,     javax.ws.rs.core.Configuration configuration) { return subResourceModel;        }        private ResourceModel processResourceModel(ResourceModel resourceModel) { ResourceModel.Builder newResourceModelBuilder = new ResourceModel.Builder(false); for (final Resource resource : resourceModel.getResources()) {     final Resource.Builder resourceBuilder = Resource.builder(resource);     String resolvedResourcePath = processPropertyPlaceholder(resource);     resourceBuilder.path(resolvedResourcePath);     // handle child resources     for (Resource childResource : resource.getChildResources()) {         String resolvedChildPath = processPropertyPlaceholder(childResource);         final Resource.Builder childResourceBuilder = Resource.builder(childResource);         childResourceBuilder.path(resolvedChildPath);         resourceBuilder.addChildResource(childResourceBuilder.build());     }     newResourceModelBuilder.addResource(resourceBuilder.build()); } return newResourceModelBuilder.build();        }        private String processPropertyPlaceholder(Resource resource) { String ogPath = resource.getPath(); return propertyResolver.resolvePlaceholders(ogPath);        }    }    @Override    public ResourceConfig configure() {        ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);        return new ResourceConfig(TestResource.class)     .property("contextConfig", ctx)     .register(PropertyPlaceholderPathResolvingModelProcessor.class)     .register(new LoggingFilter(Logger.getAnonymousLogger(), true));    }    @Test    public void pathPlaceholderShouldBeResolved() {        Response response = target("resource").request().get();        assertThat(response.getStatus(), is(200));        assertThat(response.readEntity(String.class), is(equalTo("Resource Success!")));        response.close();        response = target("resource/sub-resource").request().get();        assertThat(response.getStatus(), is(200));        assertThat(response.readEntity(String.class), is(equalTo("Sub-Resource Success!")));        response.close();        response = target("resource/sub-resource-locator").request().get();        assertThat(response.getStatus(), is(200));        assertThat(response.readEntity(String.class), is(equalTo("Sub-Resource-Locator Success!")));        response.close();    }}

同样,现在我考虑了一下,我可以看到一种解决resolve的方法

@ApplicationPath
,但是它涉及在Spring中以编程方式创建Jersey
servlet容器
WebAppInitializer
。老实说,我认为这会带来更多麻烦。我会把它吸起来,然后将其保留
@ApplicationPath
为静态字符串。


UDPATE

如果您使用的是Spring
Boot,那么通过该

spring.jersey.applicationPath
属性,应用程序路径绝对是可配置的。Spring引导加载Jersey的方式几乎就是我上一段所想到的想法,您可以在其中自行创建Jersey
servlet容器,并设置servlet映射。这就是使用Spring Boot进行配置的方式。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/412156.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号