-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add, RESTEasy ClientHttpEngine customize example
- Loading branch information
1 parent
d065d76
commit 5512c2d
Showing
9 changed files
with
339 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
name := "resteasy-customize-http-engine" | ||
|
||
organization := "org.littlewings" | ||
|
||
version := "0.0.1-SNAPSHOT" | ||
|
||
scalaVersion := "2.12.3" | ||
|
||
updateOptions := updateOptions.value.withCachedResolution(true) | ||
|
||
scalacOptions ++= Seq("-Xlint", "-deprecation", "-unchecked", "-feature") | ||
|
||
libraryDependencies ++= Seq( | ||
// for RESTEasy Client | ||
"org.jboss.resteasy" % "resteasy-client" % "3.1.4.Final" % Compile exclude("junit", "junit"), | ||
"org.jboss.resteasy" % "resteasy-jackson2-provider" % "3.1.4.Final" % Compile, | ||
"com.fasterxml.jackson.module" %% "jackson-module-scala" % "2.8.9" % Compile, | ||
|
||
// dependency retrieve | ||
"org.jboss.resteasy" % "resteasy-jaxrs" % "3.1.4.Final" % Compile, | ||
"org.jboss.logging" % "jboss-logging" % "3.3.0.Final" % Compile, | ||
"org.jboss.logging" % "jboss-logging-annotations" % "2.0.1.Final" % Compile, | ||
"org.jboss.logging" % "jboss-logging-processor" % "2.0.1.Final" % Compile, | ||
"org.apache.httpcomponents" % "httpclient" % "4.5.2" % Compile, | ||
"com.fasterxml.jackson.core" % "jackson-core" % "2.8.9" % Compile, | ||
"com.fasterxml.jackson.core" % "jackson-annotations" % "2.8.9" % Compile, | ||
"com.fasterxml.jackson.core" % "jackson-databind" % "2.8.9" % Compile, | ||
"com.fasterxml.jackson.jaxrs" % "jackson-jaxrs-json-provider" % "2.8.9" % Compile, | ||
"javax.activation" % "activation" % "1.1.1" % Compile, | ||
"org.jboss.spec.javax.servlet" % "jboss-servlet-api_3.1_spec" % "1.0.0.Final" % Compile, | ||
"org.jboss.spec.javax.annotation" % "jboss-annotations-api_1.2_spec" % "1.0.0.Final" % Compile, | ||
"org.jboss.spec.javax.ws.rs" % "jboss-jaxrs-api_2.0_spec" % "1.0.1.Beta1" % Compile, | ||
"commons-io" % "commons-io" % "2.5" % Compile, | ||
"net.jcip" % "jcip-annotations" % "1.0" % Compile, | ||
|
||
// for Customize HttpEngine | ||
"com.squareup.okhttp3" % "okhttp" % "3.9.0" % Compile, | ||
|
||
// for test | ||
"org.jboss.resteasy" % "resteasy-netty4" % "3.1.4.Final" % Test, | ||
"io.netty" % "netty-all" % "4.1.15.Final" % Test, | ||
"org.scalatest" %% "scalatest" % "3.0.4" % Test | ||
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
sbt.version = 1.0.1 |
Empty file.
75 changes: 75 additions & 0 deletions
75
...-customize-http-engine/src/main/scala/org/littlewings/javaee7/resteasy/OkHttpEngine.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
package org.littlewings.javaee7.resteasy | ||
|
||
import java.io.{ByteArrayOutputStream, InputStream} | ||
import javax.net.ssl.{HostnameVerifier, SSLContext} | ||
import javax.ws.rs.core.MultivaluedMap | ||
|
||
import okhttp3.{MediaType, OkHttpClient, Request, RequestBody} | ||
import org.jboss.resteasy.client.jaxrs.ClientHttpEngine | ||
import org.jboss.resteasy.client.jaxrs.internal.{ClientInvocation, ClientResponse} | ||
import org.jboss.resteasy.util.CaseInsensitiveMap | ||
|
||
import scala.beans.BeanProperty | ||
|
||
class OkHttpEngine extends ClientHttpEngine { | ||
val okHttpClient: OkHttpClient = new OkHttpClient | ||
|
||
@BeanProperty | ||
var sslContext: SSLContext = _ | ||
|
||
@BeanProperty | ||
var hostnameVerifier: HostnameVerifier = _ | ||
|
||
override def invoke(request: ClientInvocation): ClientResponse = { | ||
val okHttpRequestBuilder = | ||
new Request.Builder() | ||
.url(request.getUri.toURL) | ||
|
||
val body = Option(request.getEntity).map { _ => | ||
val baos = new ByteArrayOutputStream | ||
request.getDelegatingOutputStream.setDelegate(baos) | ||
request.writeRequestBody(baos) | ||
baos.close() | ||
baos.toByteArray | ||
} | ||
|
||
val headers = request.getHeaders.asMap | ||
headers.entrySet.forEach(header => header.getValue.forEach(okHttpRequestBuilder.addHeader(header.getKey, _))) | ||
|
||
okHttpRequestBuilder.method( | ||
request.getMethod, | ||
body.map(RequestBody.create(MediaType.parse(request.getHeaders.getMediaType.toString), _)).getOrElse(null) | ||
) | ||
|
||
val okHttpRequest = okHttpRequestBuilder.build | ||
|
||
val okHttpResponse = okHttpClient.newCall(okHttpRequest).execute() | ||
|
||
val response = new ClientResponse(request.getClientConfiguration) { | ||
var inputStream: InputStream = _ | ||
|
||
override def releaseConnection(): Unit = okHttpResponse.close() | ||
|
||
override def setInputStream(is: InputStream): Unit = inputStream = is | ||
|
||
override def getInputStream = { | ||
if (inputStream == null) { | ||
inputStream = okHttpResponse.body().byteStream() | ||
} | ||
|
||
inputStream | ||
} | ||
} | ||
|
||
response.setStatus(okHttpResponse.code()) | ||
|
||
val responseHeaders: MultivaluedMap[String, String] = new CaseInsensitiveMap | ||
val headerNames = okHttpResponse.headers.names | ||
headerNames.forEach(name => okHttpResponse.headers(name).forEach(value => responseHeaders.add(name, value))) | ||
|
||
response.setHeaders(responseHeaders) | ||
response | ||
} | ||
|
||
override def close(): Unit = () | ||
} |
1 change: 1 addition & 0 deletions
1
...easy-customize-http-engine/src/test/resources/META-INF/services/javax.ws.rs.ext.Providers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
org.littlewings.javaee7.resteasy.ScalaObjectMapperProvider |
3 changes: 3 additions & 0 deletions
3
resteasy-customize-http-engine/src/test/scala/org/littlewings/javaee7/resteasy/Book.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
package org.littlewings.javaee7.resteasy | ||
|
||
case class Book(isbn: String, title: String, price: Int) |
146 changes: 146 additions & 0 deletions
146
...-http-engine/src/test/scala/org/littlewings/javaee7/resteasy/RestEasyHttpEngineSpec.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
package org.littlewings.javaee7.resteasy | ||
|
||
import javax.ws.rs.client.{ClientBuilder, Entity} | ||
import javax.ws.rs.core.Response | ||
|
||
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder | ||
import org.jboss.resteasy.client.jaxrs.engines.URLConnectionEngine | ||
import org.scalatest.{FunSuite, Matchers} | ||
|
||
class RestEasyHttpEngineSpec extends FunSuite with Matchers { | ||
test("use standard engine") { | ||
TestRestServer.withServer { | ||
val client = ClientBuilder.newBuilder.build | ||
|
||
try { | ||
val response = | ||
client | ||
.target("http://localhost:8080/test/get") | ||
.request | ||
.get() | ||
|
||
response.getStatus should be(Response.Status.OK.getStatusCode) | ||
response.readEntity(classOf[Book]) should be( | ||
Book("978-4798140926", "Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築", 4104) | ||
) | ||
|
||
response.close() | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
} | ||
|
||
test("use java.net.HttpConnection engine") { | ||
TestRestServer.withServer { | ||
val client = new ResteasyClientBuilder().httpEngine(new URLConnectionEngine).build() | ||
|
||
try { | ||
val response = | ||
client | ||
.target("http://localhost:8080/test/get") | ||
.request | ||
.get() | ||
|
||
response.getStatus should be(Response.Status.OK.getStatusCode) | ||
response.readEntity(classOf[Book]) should be( | ||
Book("978-4798140926", "Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築", 4104) | ||
) | ||
|
||
response.close() | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
} | ||
|
||
test("use OkHttp engine") { | ||
TestRestServer.withServer { | ||
val client = new ResteasyClientBuilder().httpEngine(new OkHttpEngine).build() | ||
|
||
try { | ||
val response = | ||
client | ||
.target("http://localhost:8080/test/get") | ||
.request | ||
.get() | ||
|
||
response.getStatus should be(Response.Status.OK.getStatusCode) | ||
response.readEntity(classOf[Book]) should be( | ||
Book("978-4798140926", "Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築", 4104) | ||
) | ||
|
||
response.close() | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
} | ||
|
||
test("use OkHttp engine, post") { | ||
TestRestServer.withServer { | ||
val client = new ResteasyClientBuilder().httpEngine(new OkHttpEngine).build() | ||
|
||
try { | ||
val response = | ||
client | ||
.target("http://localhost:8080/test/post") | ||
.request | ||
.post(Entity.json(Book("978-4774183169", "パーフェクト Java EE", 3456))) | ||
|
||
response.getStatus should be(Response.Status.OK.getStatusCode) | ||
response.readEntity(classOf[Book]) should be( | ||
Book("978-4774183169", "パーフェクト Java EE", 6912) | ||
) | ||
|
||
response.close() | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
} | ||
|
||
test("use OkHttp engine, put") { | ||
TestRestServer.withServer { | ||
val client = new ResteasyClientBuilder().httpEngine(new OkHttpEngine).build() | ||
|
||
try { | ||
val response = | ||
client | ||
.target("http://localhost:8080/test/put") | ||
.request | ||
.put(Entity.json(Book("978-4774183169", "パーフェクト Java EE", 3456))) | ||
|
||
response.getStatus should be(Response.Status.OK.getStatusCode) | ||
response.readEntity(classOf[Book]) should be( | ||
Book("978-4774183169", "パーフェクト Java EE", 6912) | ||
) | ||
|
||
response.close() | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
} | ||
|
||
test("use OkHttp engine, delete") { | ||
TestRestServer.withServer { | ||
val client = new ResteasyClientBuilder().httpEngine(new OkHttpEngine).build() | ||
|
||
try { | ||
val response = | ||
client | ||
.target("http://localhost:8080/test/delete") | ||
.request | ||
.method("DELETE", Entity.json(Book("978-4774183169", "パーフェクト Java EE", 3456))) | ||
|
||
response.getStatus should be(Response.Status.NO_CONTENT.getStatusCode) | ||
response.getEntity should be(null) | ||
|
||
response.close() | ||
} finally { | ||
client.close() | ||
} | ||
} | ||
} | ||
} |
19 changes: 19 additions & 0 deletions
19
...tp-engine/src/test/scala/org/littlewings/javaee7/resteasy/ScalaObjectMapperProvider.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package org.littlewings.javaee7.resteasy | ||
|
||
import javax.ws.rs.{Consumes, Produces} | ||
import javax.ws.rs.core.MediaType | ||
import javax.ws.rs.ext.{ContextResolver, Provider} | ||
|
||
import com.fasterxml.jackson.databind.ObjectMapper | ||
import com.fasterxml.jackson.module.scala.DefaultScalaModule | ||
|
||
@Provider | ||
@Consumes(Array(MediaType.APPLICATION_JSON)) | ||
@Produces(Array(MediaType.APPLICATION_JSON)) | ||
class ScalaObjectMapperProvider extends ContextResolver[ObjectMapper] { | ||
override def getContext(typ: Class[_]): ObjectMapper = { | ||
val objectMapper = new ObjectMapper | ||
objectMapper.registerModule(DefaultScalaModule) | ||
objectMapper | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
...ustomize-http-engine/src/test/scala/org/littlewings/javaee7/resteasy/TestRestServer.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package org.littlewings.javaee7.resteasy | ||
|
||
import javax.ws.rs.core.MediaType | ||
import javax.ws.rs._ | ||
|
||
import org.jboss.resteasy.plugins.server.netty.NettyJaxrsServer | ||
|
||
object TestRestServer { | ||
def withServer(fun: => Unit): Unit = { | ||
val netty = new NettyJaxrsServer | ||
val deployment = netty.getDeployment | ||
deployment.setResourceClasses(java.util.Arrays.asList(classOf[TestResource].getName)) | ||
netty.setRootResourcePath("") | ||
netty.setPort(8080) | ||
netty.setDeployment(deployment) | ||
netty.start() | ||
|
||
try { | ||
fun | ||
} finally { | ||
netty.stop() | ||
} | ||
} | ||
} | ||
|
||
@Path("test") | ||
class TestResource { | ||
@GET | ||
@Path("get") | ||
@Produces(Array(MediaType.APPLICATION_JSON)) | ||
def get: Book = | ||
Book("978-4798140926", "Java EE 7徹底入門 標準Javaフレームワークによる高信頼性Webシステムの構築", 4104) | ||
|
||
@POST | ||
@Path("post") | ||
@Consumes(Array(MediaType.APPLICATION_JSON)) | ||
@Produces(Array(MediaType.APPLICATION_JSON)) | ||
def post(book: Book): Book = book.copy(price = book.price * 2) | ||
|
||
@PUT | ||
@Path("put") | ||
@Consumes(Array(MediaType.APPLICATION_JSON)) | ||
@Produces(Array(MediaType.APPLICATION_JSON)) | ||
def put(book: Book): Book = book.copy(price = book.price * 2) | ||
|
||
@DELETE | ||
@Path("delete") | ||
@Consumes(Array(MediaType.APPLICATION_JSON)) | ||
@Produces(Array(MediaType.APPLICATION_JSON)) | ||
def delete(book: Book): Unit = () | ||
} |