2018年5月8日 星期二

[Java] running JAX-RS with gretty

開一個專案叫 jersey,然後按下面加入代碼:

// build.gradle
plugins {
    id 'war'
    //id 'org.gretty' version '2.1.0'
    id 'org.akhikhl.gretty' version '2.0.0'
}
// 'jetty7', 'jetty8', 'jetty9', 'jetty9.3', 'jetty9.4', 'tomcat7', 'tomcat8'
//gretty.servletContainer='jetty9'
repositories {
    jcenter()
}
dependencies {
    compile 'org.glassfish.jersey.containers:jersey-container-servlet:2.26'
    compile 'org.glassfish.jersey.inject:jersey-hk2:2.27'
}
// src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://java.sun.com/xml/ns/javaee"
   xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
   xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
   id="WebApp_ID"
   version="3.0">
   <display-name>My JAX-RS</display-name>
   <servlet>
      <servlet-name>jersey-servlet</servlet-name>
      <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
      <init-param>
         <param-name>jersey.config.server.provider.packages</param-name>
         <param-value>demo</param-value>
      </init-param>
   </servlet>
   <servlet-mapping>
      <servlet-name>jersey-servlet</servlet-name>
      <url-pattern>/*</url-pattern>
   </servlet-mapping>
</web-app>
// src/main/java/demo/Hello.java
package demo;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Response;

@Path("/hello")
public class Hello {
    @GET()
    public String hello() {
        return "hello";
    }

    @GET
    @Path("/{name}")
    public Response getMessage(@PathParam("name") String name) {
        String outMsg = "Hello " + name + "!";
        return Response.status(200).entity(outMsg).build();
    }
}

接下來執行 gradle appRun

$ gradle appRun
:prepareInplaceWebAppFolder UP-TO-DATE
:createInplaceWebAppFolder UP-TO-DATE
:compileJava
:processResources NO-SOURCE
:classes
:prepareInplaceWebAppClasses
:prepareInplaceWebApp
:appRun
19:46:58 INFO  Jetty 9.2.24.v20180105 started and listening on port 8080
19:46:58 INFO  JAX-RS Application Demo runs at:
19:46:58 INFO    http://localhost:8080/jersey

> Task :appRun
Press any key to stop the server.
<===========--> 87% EXECUTING [17s]
> :appRun

然後就可以測試了:

  • http://localhost:8080/jersey/hello
  • http://localhost:8080/jersey/hello/John

備註:

  • web.xml 的 "param-value" 必須跟套件名一樣,jersey 才會作用。
  • 用 gretty 試跑的時候,URL 是帶上專案名稱,像這裡是 "/jersey"。放在 Servlet 上面跑的時候則是看檔案名稱,例如 "jersey.war";如果不想要這個路徑,可以改成 "ROOT.war"。
  • web.xml 預設路徑是 src/main/webapp/WEB-INF,但是可以在 Gradle 的 war plugin 設定。

備註2:Servlet 3 之後可以不寫 web.xml,改成繼承 ResourceConfig。

// src/main/java/demo/MyApplication.java
package demo;

import javax.ws.rs.ApplicationPath;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("/")
public class MyApplication extends ResourceConfig {
    public MyApplication() {
        packages("demo");
    }
}

備註3:如果 gretty 發生 Java9 相容問題,

Caused by: java.lang.RuntimeException: Error scanning entry META-INF/versions/9/module-info.class from jar file: .gradle/caches/modules-2/files-2.1/...

Caused by: java.lang.RuntimeException: Error scanning entry module-info.class from jar file: .gradle/caches/modules-2/files-2.1/...
可以設定參數 gretty.servletContainer 為 "jetty9.4" 或是 "tomcat8" 測試。

參考資料:

沒有留言:

張貼留言

[Java] Invalid HTTP method: PATCH

最近系統需要使用 Netty4,所以把衝突的 Netty3 拆掉,然後就出現了例外。 pom.xml <dependency> <groupId>com.ning</groupId> <artifactId>as...