How do you use HK2 dependency injection with Jersey 2.0? - java

I have searched everywhere for a basic example of how to use HK2 dependency injection in Jersey 2.0, but have come up short.
From this question, it appears you need to create a class which extends AbstractBinder. However, the rest of the example shows how to register the binder with your application by editing the web.xml file. However, I want to avoid this and would like to instead register the binder with my HttpServer instance directly.
This is what I have written for my HttpServer:
int port = config.getInt("port", 8080);
boolean useFake = config.getBoolean("fake", false);
final URI baseUri = URI.create("http://" + "localhost" + ":" + port + "/");
List<Binder> binders = Arrays.asList((Binder)new StatusModule(useFake),
(Binder)new NetworkModule(useFake));
final ApplicationHandler applicationHandler = new ApplicationHandler();
applicationHandler.registerAdditionalBinders(binders);
WebappContext webappContext = new WebappContext("Webapp context", "/resources");
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
baseUri, applicationHandler);
for(NetworkListener listener : server.getListeners()){
listener.setCompression("on");
}
server.getServerConfiguration().addHttpHandler(
new StaticHttpHandler("/jersey2app/www"), "/static");
Any help will be greatly appreciated.

Turns out I just needed to add a couple of lines of code, but I'll post it here in case anyone else has the same problem.
ResourceConfig rc = new ResourceConfig();
rc.packages("com.danny.resources");
rc.registerInstances(new StatusModule(useFake), new NetworkModule(useFake));
GrizzlyHttpContainer resourceConfigContainer = ContainerFactory
.createContainer(GrizzlyHttpContainer.class, rc);
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(baseUri);
server.getServerConfiguration().addHttpHandler(resourceConfigContainer, "/");
The ResourceConfig lets you tell the server where to find your dynamic resources, in my case "com.danny.resources". It also allows you to register hk2 binders which will be used to inject those resources into your code.
Hope this helps someone along the way, and I hope hk2/Jersey 2.0 puts out some more examples!

Related

Set up proxy data to Spring SOAP web service template

I'm working on an application where I have to consume a SOAP webservice and convert it to Rest based webservices. I followed the tutorial from Spring team and was capable to generate pojos, but when I try to make the call using the webServiceTemplate I have an error that the host is not recognized which is basically because I'm behind a proxy in our company.
The technology stack I'm using is Spring boot with web module and spring-ws-core, and I would like to know how to set up my proxy data in the webServiceTemplate.
Thanks
Try to setup the template according this answer.
Afterwards you should be able to set it within your class extending WebServiceGatewaySupport using
setWebServiceTemplate(WebServiceTemplate webServiceTemplate)
After a lot of research, I came up with a programmatic solution. Once you defined your SOAP client that will extend WebServiceGatewaySupport class, I created a configuration class (annotated with #configuration that will declare a bean of my SOAP client. In this method, I used the following code to setup my proxy information and thus I was able to consume my web service:
#Bean
public CommerceSoapClient commerceSoapClient(Jaxb2Marshaller marshaller) {
CommerceSoapClient commerceService = new CommerceSoapClient();
//Setup proxy
HttpClientBuilder builder = HttpClientBuilder.create();
builder.addInterceptorFirst(new HttpComponentsMessageSender.RemoveSoapHeadersInterceptor());
HttpHost proxy = new HttpHost("127.0.0.1", 8080);
builder.setProxy(proxy);
CloseableHttpClient httpClient = builder.build();
HttpComponentsMessageSender messageSender = new HttpComponentsMessageSender(httpClient);
WebServiceTemplate webServiceTemplate = new WebServiceTemplate();
webServiceTemplate.setMessageSender(messageSender);
webServiceTemplate.setDefaultUri("http://your webservice address path");
webServiceTemplate.setUnmarshaller(marshaller);
webServiceTemplate.setMarshaller(marshaller);
commerceService.setDefaultUri("https://your webservice address path");
commerceService.setWebServiceTemplate(webServiceTemplate);
return commerceService;
}

Jersey+Grizzly load-on-startup without web.xml

according to this (servlet response time is slow for first request) SO Question I can use the load-on-startup parameter in web.xml to create the services classes on startup and not on the first client request, which causes better first-response times for clients.
However I'm using Grizzly+Jersey, how can I configure this behaviour in grizzly, or is this completetly impossible? Then what would be alternatives to grizzly without using a full blown Java EE Application Server
EDIT: Main main method is this:
public static void main(String... args){
//Packages which contain service classes
final ResourceConfig rc = new ResourceConfig()
.packages("de.danielr1996.flamingoapi.services");
//Logging Aktivieren
rc.register(new LoggingFilter());
//Dependency Injection konfigurieren
rc.register(new DependencyBinder());
//Jackson hinzufügen
rc.register(JacksonFeature.class);
//Datenbank initialisieren
DatabaseUtil.getEntityManagerFactory();
// Server erstellen
return GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), rc);
}
Thanks in Advance
ServletAdapter adapter =new ServletAdapter();
...
adapter.setProperty( "load-on-startup", 1 );
UPDATE
I don't now how to configure instance created from Factory. I assume it does not allow you to provide complex configuration.
But you can create server manually this way :
GrizzlyWebServer ws = new GrizzlyWebServer(80);
ServletAdapter adapter = new ServletAdapter();
Then configure adapter Javadocs
adapter.setContextPath("...");
adapter.setRootFolder("...");
adapter.setHandleStaticResources(true);
adapter.setProperty("load-on-startup","1");
Add adapter to server
ws.addGrizzlyAdapter(adapter, new String[]{"/uri"});

Using rest Servlet in Camel with Guice and Undertow

I'm setting up and application using Undertow, I've set up a ResourceHandler for static files, and Servlet to be used by apache-camel to expose rest services.
I've done this using spring and servlet3.0 in an app container.
In a class extending org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
#Override
public void onStartup(ServletContext servletContext) throws ServletException
{
super.onStartup(servletContext);
ServletRegistration.Dynamic servlet = servletContext.addServlet("RestServlet", new CamelHttpTransportServlet());
servlet.setLoadOnStartup(1);
servlet.addMapping("/rest/*");
}
And in camel route
restConfiguration()
.component("RestServlet")
.bindingMode(RestBindingMode.json)
.dataFormatProperty("prettyPrint", "true");
Pretty close to whats described in http://camel.apache.org/servlet.html
But if I do this in Undertow as an embedded I get org.apache.camel.NoSuchBeanException: No bean could be found in the registry for: RestServlet of type: org.apache.camel.spi.RestConsumerFactory as I guess Guice never finds the servlets created by Undertow. I tried to manually expose the CamelHttpTransportServlet as a Guice Binding but that doesn't seem to change things.
ClassLoader classLoader = getClass().getClassLoader();
ResourceHandler staticHandler = new ResourceHandler(new ClassPathResourceManager(classLoader, STATIC_RESOURCE_ROOT))
.addWelcomeFiles(INDEX_HTML);
DeploymentInfo deploymentInfo = Servlets.deployment()
.setClassLoader(classLoader)
.setContextPath(ROOT_MAPPING)
.setDeploymentName(DEPLOYMENT_NAME)
.addServlet(
Servlets.servlet("RestServlet", CamelHttpTransportServlet.class)
.addMapping(REST_MAPPING)
.setLoadOnStartup(1)
);
DeploymentManager manager = Servlets.defaultContainer().addDeployment(deploymentInfo);
manager.deploy();
PathHandler path = Handlers.path()
.addPrefixPath(REST_MAPPING, manager.start())
.addPrefixPath(ROOT_MAPPING, staticHandler);
undertow = Undertow.builder()
.addHttpListener(port, LOCALHOST)
.setHandler(path)
.build();
undertow.start();
The static resource work as expected, and it also seems the rest servlet is running and getting the responses but CamelContext won't start up.
I can't use restlet or anything in camel as then the port will be in use so I need to use different port for static files and rest.
Is there any way to have camel identify the Servlet initiated by Undertow?
Ok I finally found out where it went wrong.
I suspect I always used .component("servlet") and not .component("RestServlet"), but Camel wouldn't link this automatically before.
I changed this section to
restConfiguration()
.bindingMode(RestBindingMode.json)
.component("servlet")
.dataFormatProperty("prettyPrint", "true")
.endpointProperty("servletName", "RestServlet);
And the deployment I changed the servlets mapping to /* or else request.getPathInfo() would return null inside CamelHttpTransportServlet.
NB I encountered a problem beause I initially set contextPath to /rest/* which messed up sessions and cookies
DeploymentInfo deploymentInfo = Servlets.deployment()
.setClassLoader(classLoader)
.setContextPath("/rest/")
.setDeploymentName(DEPLOYMENT_NAME)
.addServlet(
Servlets.servlet("RestServlet", CamelHttpTransportServlet.class)
.addMapping("/*")
.setLoadOnStartup(1)
);

Grizzly Server with static content and REST resource

I have a Jersey REST 2.5.1 service which is served through a Grizzly server. Everything works fine so far. I want to add some static content, which is also served through Grizzly and provided from my JAR file. Therefore I use CLStaticHttpHandler. When I access static resources, such as my index.html explicitly (e.g. http://localhost:8080/index.html), everything works fine. However, when I try to access the root http://localhost:8080, I get a 404. The code looks like this:
ObjectMapper mapper = new ObjectMapper();
// some configuration stuff here
JacksonJaxbJsonProvider provider = new JacksonJaxbJsonProvider();
provider.setMapper(mapper);
ResourceConfig resourceConfig = new ResourceConfig()
.packages("my.restapi.package")
.register(provider);
HttpServer httpServer = GrizzlyHttpServerFactory.createHttpServer(URI.create(BASE_URI), resourceConfig);
HttpHandler httpHandler = new CLStaticHttpHandler(HttpServer.class.getClassLoader(), "/static/");
httpServer.getServerConfiguration().addHttpHandler(httpHandler, "/");
As far as I can tell from debugging, org.glassfish.grizzly.http.server.CLStaticHttpHandler.handle(String, Request, Response) never gets called. Any hints, how I can make the index.html accessible as default page?
After some wasted hours, I feel a bit stupid now, but the simple solution was, to specify a path in BASE_URI (http://localhost:8080/api/ instead of http://localhost:8080/). Now, when accessing /, I get the index.html and the REST methods are under /api.

Jersey - Declarative Hyperlinking - In Code Configuration

Hi I'm going through the Jersey Getting Started Guide.
In Chapter 6 they use the #Ref annotation to inject the URI of a resource. I've followed the example, but my uri is always null.
How can I add the com.sun.jersey.server.linking.LinkFilter to com.sun.jersey.spi.container.ContainerResponseFilters programatically? I've already seen a bunch of examples using web.xml.
Thanks!
I ended up retrieving the ResponseFilters from the ResourceConfig and then adding an instance of LinkFilter to it.
private static HttpServer startServer() throws IOException {
LOG.info("Starting server...");
ResourceConfig rc = new PackagesResourceConfig("com.mycomp.resources");
rc.getContainerResponseFilters().add(new com.sun.jersey.server.linking.LinkFilter());
return GrizzlyServerFactory.createHttpServer(BASE_URI, rc);
}

Categories

Resources