java - 为 JerseyTest 配置带有 SSL 的 JettyTestContainer

标签 java ssl jax-rs jersey-2.0 jersey-test-framework

我的任务是为我的团队的代码设置集成测试。这些测试需要向 Jersey 2.27 中实现的 REST 端点执行 HTTPS 请求。在我寻找如何执行此类测试时,我偶然发现了 this article from Baeldung这让我了解了 Jersey 测试框架和他们为此目的实现的提供程序容器。我选择了 Jetty 容器,因为我们的代码使用“自己部署”的 Jetty 实例来完成这一切。我开始实现我们的测试,但在为 JettyTestContainer 配置 SSL 来提供其余请求时遇到了困难。我开始收到 IllegalArgumentException,指出“不使用 SSL 时,URI 方案应为 http”。我不知道如何继续。

这是我的测试类:

public class ProjectTest extends JerseyTest {



 private SSLContext sslCtx;
    
    @Override
    protected Application configure() {
        ResourceConfig conf = new ResourceConfig(Sets.newHashSet(RestSuite1.class));
        SslConfigurator sslConfig = SslConfigurator.newInstance()
            .trustStoreFile()
            .trustStorePassword()
            .keyStoreFile()
            .keyStorePassword()
        sslCtx = sslConfig.createSSLContext();
    }

    @Override
    public URI getBaseUri() {
        return URI.create("https://localhost:1234")
    }

    @Override
    public Client getClient() {
        return ClientBuilder.newBuilder().sslContext(sslCtx).build();
    }

    @Test
    public void test1() throws Exception { 
        String testString = "HelloWorld";
        OurObject oo = target("/restSuite1")
            .request()
            .post(Entity.entity(testString, MediaType.APPLICATION_JSON), String.class);
    }
}

这是一个 RestSuite1:

@Path("restSuite1")
@Produces("application/json")
public class RestSuite1 {
    
    @POST
    @Consumes("application/json")
    @Produces("application/json")    
    public String doSomething(String payload) {
        // Do Something 
    }
}

这是我的 pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0   
http://maven.apache.org/xsd/maven-4.0.0.xsd">  
  
  <modelVersion>4.0.0</modelVersion>  
  
  <groupId>com.sample</groupId>  
  <artifactId>my-application1</artifactId>  
  <version>1.0</version>  
  <packaging>war</packaging>  
  
  <name>my war</name>  
  <url>http://some-url.com</url>  
  
  <dependencies>  
    <dependency>  
      <groupId>javax.ws.rs</groupId>  
      <artifactId>javax.ws.rs-api</artifactId>  
      <version>2.1</version>  
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.containers</groupId>  
      <artifactId>jersey-container-servlet</artifactId>  
      <version>2.27</version>  
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.core</groupId>  
      <artifactId>jersey-server</artifactId>  
      <version>2.27</version>  
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.core</groupId>  
      <artifactId>jersey-client</artifactId>  
      <version>2.27</version>  
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.inject</groupId>  
      <artifactId>jersey-hk2</artifactId>  
      <version>2.27</version>  
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.media</groupId>  
      <artifactId>jersey-media-json-jackson</artifactId>  
      <version>2.27</version>  
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.test-framework</groupId>  
      <artifactId>jersey-test-framework-core</artifactId>  
      <version>2.27</version>
      <scope>test</scope>
    </dependency>
    <dependency>  
      <groupId>org.glassfish.jersey.test-framework.providers</groupId>  
      <artifactId>jersey-test-framework-provider-jetty</artifactId>  
      <version>2.27</version>
      <scope>test</scope>
    </dependency>
    <dependency>  
      <groupId>junit</groupId>  
      <artifactId>junit</artifactId>  
      <version>4.8.2</version>  
      <scope>test</scope>  
    </dependency>  
  </dependencies>  
</project>

我应该注意到,在尝试 SSL 配置之前,我能够成功到达 POST/restSuite1 端点。

我找到了this question ,但它看起来不像人们在网络中使用的 Grizzly SSL 配置 Jersey测试场景。

我找到了this question ,但它看起来像是设置用户角色而不是实际的 SSL 配置。

然后我发现this question ,问这个问题的人似乎和我有同样的问题,但没有人回答这个问题。

请帮忙!

最佳答案

看起来这个选项在 JerseyTest 中不可用。我创建了一个拉取请求来添加此选项。请看这里:https://github.com/eclipse-ee4j/jersey/pull/4573我不太确定他们会多快批准并发布它......

我知道这不是您正在寻找的答案...但是,如果您仍然想使用 ssl 配置服务器并使用 https 测试您的应用程序,而不等待拉取请求获得批准,您可以看看我的github 项目,其中有一个在没有 JerseyTest 的情况下使用 grizzly 测试 Jersey 服务器的基本示例:Application & IntegrationTest

================更新 #1 20-12-2020 ===============

拉取请求已被批准、合并并发布。现在从 2.33 版本开始可用。现在可以提供带有 sslparameters 的 sslcontext 来配置您的 Jersey 测试。一个示例设置是:

public class SecuredJerseyTest extends JerseyTest {

    @Override
    protected TestContainerFactory getTestContainerFactory() {
        return new GrizzlyTestContainerFactory();
    }

    @Path("hello")
    public static class TestResource {
        @GET
        public String hello() {
            return "hello";
        }
    }

    @Override
    protected Application configure() {
        return new ResourceConfig(TestResource.class);
    }

    @Override
    protected URI getBaseUri() {
        return UriBuilder
                .fromUri("https://localhost")
                .port(getPort())
                .build();
    }

    @Override
    protected Optional<SSLContext> getSslContext() {
        SSLContext sslContext = ... // your initialised server sslContext 
        return Optional.of(sslContext);
    }

    @Override
    protected Optional<SSLParameters> getSslParameters() {
        serverSslParameters = new SSLParameters();
        serverSslParameters.setNeedClientAuth(false);
        return Optional.of(serverSslParameters);
    }

    @Test
    public void testHello() {
        SSLContext sslContext = ... // your initialised client sslContext 

        Client client = ClientBuilder.newBuilder()
                .sslContext(sslContext)
                .build();

        WebTarget target = client.target(getBaseUri()).path("hello");

        String s = target.request().get(String.class);
        Assert.assertEquals("hello", s);
    }
}

关于java - 为 JerseyTest 配置带有 SSL 的 JettyTestContainer,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63924572/

相关文章:

Java - 将用户输入添加到 ArrayList,需要用另一个 ArrayList 中的变量分隔

.htaccess - 强制 https ://www. 域到 https://domain

java - MySQL - Java SSL 连接抛出错误

使用 StackExchange.Redis 与 Redis 进行 SSL 连接

java - Jersey 2.0 HashMap 与 Json 之间的转换

logging - 如何在JAX-RS客户端中记录请求正文

java - 在java中相应地打印 double 值

java - Eclipse 命令行参数

java - 数组列表找不到对象

java - 从 MDC 中清除 requestId 的位置