2

Jersey REST/Json の JUnit テストをアプリケーションに実装したいと考えています。

私の問題は、Grizzly から 404 not found が返されることです。しかし、パスは正しく、通常の Webcontainer で Curl を使用したテストは機能しています。

私はGWTPを使用しています(mavenなし)。プロパティ - > Javaビルドパスでライブラリを手動で実装しています。私は次のバージョンを使用しています:

  • Eclipse インディゴ (Windows 7 上)
  • asm-3.3.1.jar
  • jersey-client-1.12.jar
  • jersey-core-1.12.jar
  • jersey-json-1.12.jar
  • jersey-server-1.12.jar
  • jersey-servlet-1.12.jar
  • jersey-test-framework-core-1.12.jar
  • jersey-test-framework-grizzly-1.12.jar
  • grizzly-framework-1.9.45.jar
  • グリズリー-http-1.9.45.jar
  • grizzly-http-servlet-1.9.45.jar
  • grizzly-portunif-1.9.45.jar
  • grizzly-rcm-1.9.45.jar
  • grizzly-servlet-webserver-1.9.45.jar
  • grizzly-utils-1.9.45.jar
  • サーブレット-api-2.5.jar
  • junit-4.9.jar (4.10.jar でもテスト済み)

すべてのライブラリは、Jersey のドキュメントに従って含まれています: http://jersey.java.net/nonav/documentation/latest/user-guide.html - Chapter 7.5 Running tests outside Maven.

スタックトレースは次のとおりです。

INFO: GRIZZLY0001: Starting Grizzly Framework 1.9.45 - 01.07.12 12:11
01.07.2012 10:11:20 com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
com.acolsolutions.loyaltycard.resources
01.07.2012 10:11:20 com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
class com.acolsolutions.loyaltycard.resources.HelloResource
class com.acolsolutions.loyaltycard.resources.CardResource
01.07.2012 10:11:20 com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
01.07.2012 10:11:20 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application, version 'Jersey: 1.12 02/15/2012 04:51 PM'
com.sun.jersey.api.client.UniformInterfaceException: POST http://localhost:9998   /api/cards returned a response status of 404 Not Found
at com.sun.jersey.api.client.WebResource.voidHandle(WebResource.java:707)
at com.sun.jersey.api.client.WebResource.access$400(WebResource.java:74)
at com.sun.jersey.api.client.WebResource$Builder.post(WebResource.java:553)
at   com.acolsolutions.loyaltycard.junit.CardResourceTests.testCreate(CardResourceTests.java:55)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
at org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:31)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:263)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:69)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:48)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222)
at org.junit.runners.ParentRunner.run(ParentRunner.java:292)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
01.07.2012 10:11:21    com.sun.jersey.test.framework.spi.container.grizzly.web.GrizzlyWebTestContainerFactory$GrizzlyWebTestContainer stop
INFO: Stopping the Grizzly Web Container...

私のクラスは次のようになります。

CardResourceTests.java:

import static org.junit.Assert.assertFalse;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.google.appengine.tools.development.testing.LocalDatastoreServiceTestConfig;
import com.google.appengine.tools.development.testing.LocalServiceTestHelper;

import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.test.framework.JerseyTest; 
import com.sun.jersey.test.framework.WebAppDescriptor;

import org.codehaus.jettison.json.JSONObject;

public class CardResourceTests extends JerseyTest {
private final LocalServiceTestHelper helper = new LocalServiceTestHelper(
new LocalDatastoreServiceTestConfig()); 


public CardResourceTests() throws Exception {
super("com.acolsolutions.loyaltycard.resources");
}
/*  
@Before
public void setUp() {
helper.setUp();
}

@After
public void tearDown() {
helper.tearDown();
}
*/  
@Test
public void testCreate() {
boolean thrown = false;
WebResource webResource = resource();
JSONObject card = new JSONObject(); 

try {
card.put("id", "1")
.put("name", "Name of Card")
.put("code", "123456")
.put("codeTypeId", "1")
.put("cardProviderName", "The Card Provider")
.put("picturePath", "provider.jpg")
.put("cardProviderUrl", "http://www.provider.com")
.put("creationDate", "Sun Jun 10 08:55:14 UTC 2012")
.put("modificationDate","Sun Jun 10 08:55:14 UTC 2012");
webResource.path("api/cards").type("application/json").post(card);
} catch(Exception e) {
e.printStackTrace();
thrown = true;
}
assertFalse(thrown);        
}
}

CardRessource.java:

import java.util.List;

import javax.ws.rs.Consumes;
import javax.ws.rs.DELETE;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import com.acolsolutions.loyaltycard.dataobjects.CardDAO;
import com.acolsolutions.loyaltycard.persistence.entities.Card;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.allen_sauer.gwt.log.client.Log;

@Path("/cards")
public class CardResource {
CardDAO dao = new CardDAO();

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public Response create(Card card) {
Log.debug("Creating card");
Card c = dao.create(card);
if(c.equals(null)) {
return Response.status(400).entity("Create failed!").build();
}
return Response.status(201).entity(c).build();
}
...
}

web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5">

<display-name>loyaltycard</display-name>

<!-- Default page to serve -->
<welcome-file-list>
<welcome-file>loyaltycard.html</welcome-file>
</welcome-file-list>

<!-- 
The below lines are implementing Jersey (JAX-RS) in to the GWT application.
-->
<servlet>
<servlet-name>Jersey</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.resourceConfigClass</param-name>
<param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-value>
</init-param>       
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>com.acolsolutions.loyaltycard.resources</param-value>
</init-param>        
</servlet>

<servlet-mapping>
<servlet-name>Jersey</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>

<!--
This Guice listener hijacks all further filters and servlets. Extra
filters and servlets have to be configured in your
ServletModule#configureServlets() by calling
serve(String).with(Class<? extends HttpServlet>) and
filter(String).through(Class<? extends Filter)
-->
<listener>
<listener-class>com.acolsolutions.loyaltycard.server.guice.GuiceServletConfig</listener-class>
</listener>

<filter>
<filter-name>guiceFilter</filter-name>
<filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
</filter>

<filter-mapping>
<filter-name>guiceFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>

</web-app>

アプリケーションを Web アプリケーションとして実行すると、Curl と次のコマンドを使用したテストが機能します。

curl http://localhost:8888/api/cards -i -X POST -H "Content-Type: application/json" -d "{\"id\": \"1\", \"name\": \"Name of Card\", \"code\": \"123456\", \"codeTypeId\": \"1\", \"cardProviderName\": \"Card Provider\", \"picturePath\": \"provider.jpg\", \"cardProviderUrl\": \"http://www.provider.com\", \"creationDate\": \"Sun Jun 10 08:55:14 UTC 2012\", \"modificationDate\": \"Sun Jun 10 08:55:14 UTC 2012\" }"

私は、RawCap.exe を使用してループバック インターフェイスをスニッフィングしようとさえしました。PCAP ファイルに次のように表示されます。

POST /api/cards HTTP/1.1
Content-Type: application/json
User-Agent: Java/1.7.0
Host: localhost:9998
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
Content-Length: 254

{"id":"1","name":"Name of Card","code":"123456","codeTypeId":"1","cardProviderName":"Card Provider","picturePath":"provider.jpg","cardProviderUrl":"http:\/\/www.provider.com","creationDate":"Sun Jun 10 08:55:14 UTC 2012","modificationDate":"Sun Jun 10 08:55:14 UTC 2012"}

HTTP/1.1 404 Not Found

server: grizzly/1.9.45
Content-Type: text/plain; charset=iso-8859-1
Transfer-Encoding: chunked
Date: Sun, 01 Jul 2012 00:02:16 GMT

これは、JSON 文字列が URL に送信されているように見えますが、クラスが見つかりません。

私はここで少し立ち往生しています。コンテキストパスに何か問題があるに違いありませんが、何をすべきか、それを設定する方法がわかりません。

助けてくれてありがとう、クリス

4

1 に答える 1

5

アプリを Web アプリケーションとして実行すると、web.xml に基づいて /api/ URL で公開されます。Grizzly も軽量 HTTP サーバーも web.xml を認識しないため、コンテナ ルートで jersey を公開します。

于 2012-07-02T15:39:29.847 に答える