WildFly-8.2.0.Final が何日か前に出てました。
WildFly Homepage · WildFly
WildFly-8.1.0.Final の JAX-RS(RESTEasy) で JSONP を返そうとして上手く動かず。。 ※上手く動くサンプルどっか知りません?
Jersey で JSONP は結構ブログとかに書かれているんですが、RESTEasy(WildFly) で JSONP はあまり情報が無く、サポートされる前の情報がちらほらとある感じでした。*1
java - How enable JSONP in RESTEasy? - Stack Overflow
ついカッとなって Jersey で試してみました!
とりあえず RESTEasy で動かしてから Jersey に載せかえます。
サンプルは、Text と JSON 返す JAX-RS のコード片です。Xtend では無く Java で書いてるので伝わりますよね。
@Path("api") public class MyApplication extends Application { } @RequestScoped @Path("hello") public class HelloWorldResource { @GET public Dto helloworld(@QueryParam("name") String name) { return "Hello " + name; } } @Data @AllArgsConstructor public class Dto { private int id; private String name; } @RequestScoped @Path("json") public class JsonResource { @GET @Produces({ "application/json" }) public Dto helloworld(@QueryParam("name") String name) { return new Dto(1, name); } }
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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>jaxrstest</display-name> <servlet> <servlet-name>resteasy</servlet-name> <servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>resteasy</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping> <context-param> <param-name>resteasy.scan</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>resteasy.servlet.mapping.prefix</param-name> <param-value>/api</param-value> </context-param> </web-app>
これで /api/hello?name=abc で「Hello abc」が /api/json?name=abc で「{"id":1,"name":"abc"}」が返ってきます。
こっから Jersey を載せてきます。
今回は com.sun.jersey:jersey-bundle と com.sun.jersey:jersey-json の 1.18.2 で試しました。
web.xml を Jersey 用にします。
<?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" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>jaxrstest</display-name> <servlet> <servlet-name>jersey-serlvet</servlet-name> <servlet-class> com.sun.jersey.spi.container.servlet.ServletContainer </servlet-class> <init-param> <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name> <param-value>true</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>jersey-serlvet</servlet-name> <url-pattern>/api/*</url-pattern> </servlet-mapping> </web-app>
これだけでさっきのコードが Jersey で一応動きます。
wildfly のログに jersey とか出てますね!
一応と付けたのは、text で返す方は動きますが、json 返す方は動きません。
json の方にアクセスするとこんな例外が返ります。
Context Path:/jaxrstest Servlet Path:/api Path Info:/json Query String:name=abc Stack Trace org.jboss.resteasy.spi.LoggableFailure: Unable to find contextual data of type: javax.ws.rs.ext.Providers org.jboss.resteasy.core.ContextParameterInjector$GenericDelegatingProxy.invoke(ContextParameterInjector.java:53) com.sun.proxy.$Proxy49.getContextResolver(Unknown Source) org.codehaus.jackson.jaxrs.JacksonJsonProvider.locateMapper(JacksonJsonProvider.java:633) org.codehaus.jackson.jaxrs.JacksonJsonProvider.writeTo(JacksonJsonProvider.java:500) org.codehaus.jackson.jaxrs.JacksonJaxbJsonProvider$Proxy$_$$_WeldClientProxy.writeTo(Unknown Source) com.sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.java:302) com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1510) com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1419) com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1409) com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:409) com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:558) com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:733) javax.servlet.http.HttpServlet.service(HttpServlet.java:790) io.undertow.servlet.handlers.ServletHandler.handleRequest(ServletHandler.java:85) io.undertow.servlet.handlers.security.ServletSecurityRoleHandler.handleRequest(ServletSecurityRoleHandler.java:61) io.undertow.servlet.handlers.ServletDispatchingHandler.handleRequest(ServletDispatchingHandler.java:36) org.wildfly.extension.undertow.security.SecurityContextAssociationHandler.handleRequest(SecurityContextAssociationHandler.java:78) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.servlet.handlers.security.SSLInformationAssociationHandler.handleRequest(SSLInformationAssociationHandler.java:131) io.undertow.servlet.handlers.security.ServletAuthenticationCallHandler.handleRequest(ServletAuthenticationCallHandler.java:56) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.security.handlers.AbstractConfidentialityHandler.handleRequest(AbstractConfidentialityHandler.java:45) io.undertow.servlet.handlers.security.ServletConfidentialityConstraintHandler.handleRequest(ServletConfidentialityConstraintHandler.java:63) io.undertow.security.handlers.AuthenticationMechanismsHandler.handleRequest(AuthenticationMechanismsHandler.java:58) io.undertow.servlet.handlers.security.CachedAuthenticatedSessionHandler.handleRequest(CachedAuthenticatedSessionHandler.java:70) io.undertow.security.handlers.SecurityInitialHandler.handleRequest(SecurityInitialHandler.java:76) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) org.wildfly.extension.undertow.security.jacc.JACCContextIdHandler.handleRequest(JACCContextIdHandler.java:61) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.server.handlers.PredicateHandler.handleRequest(PredicateHandler.java:43) io.undertow.servlet.handlers.ServletInitialHandler.handleFirstRequest(ServletInitialHandler.java:261) io.undertow.servlet.handlers.ServletInitialHandler.dispatchRequest(ServletInitialHandler.java:247) io.undertow.servlet.handlers.ServletInitialHandler.access$000(ServletInitialHandler.java:76) io.undertow.servlet.handlers.ServletInitialHandler$1.handleRequest(ServletInitialHandler.java:166) io.undertow.server.Connectors.executeRootHandler(Connectors.java:197) io.undertow.server.HttpServerExchange$1.run(HttpServerExchange.java:759) java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) java.lang.Thread.run(Thread.java:745)
RESTEasy から ContextResolver 取ろうとしてこけてるようです。
ここで WildFly から jaxrs のモジュールを取っ払います。
WEB-INF に jboss-deployment-structure.xml を置きます。
<?xml version='1.0' encoding='UTF-8'?> <jboss-deployment-structure> <deployment> <exclude-subsystems> <subsystem name="jaxrs" /> </exclude-subsystems> </deployment> </jboss-deployment-structure>
これで RESTEasy を取っ払えます。再度デプロイすると JSON の方もちゃんと動きます。
@RequestScoped @Path("json") public class JsonResource { @GET @Produces({ "application/javascript" }) public JSONWithPadding helloworld(@QueryParam("name") String name) { return new JSONWithPadding(new Dto(1, name)); } }
application/javascript にすると JSONP 強制らしいです。
/api/json?name=abc 叩くと「callback({"id":1,"name":"abc"})」となりました。
というわけで、RESTEasy 取っ払うと WildFly でも Jersey それなりに動きそうですね! RESTEasy で JSONP はもうちょい調べてみます。。