Jersey - Declarative Hyperlinking - In Code Configuration - java

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);
}

Related

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"});

WebClient class missing from Apache CXF?

I am current building a JAX-RS client using Apache CXF version 3.1.11. I have been looking at some simple examples online and it appears the WebClient class has gone missing.
See the example code below that I found online.
public static void main(String[] args) throws JsonParseException,
JsonMappingException, IOException {
WebClient client = WebClient
.create("http://localhost:8080/",
Collections.singletonList(new JacksonJsonProvider()))
.path("test").accept(MediaType.APPLICATION_JSON_TYPE);
Message message = client.get(Message.class);
System.out.println("Message recieved : " + message);
}
I cannot find the WebClient class anywhere in the code and im using the following maven dependencies.
cxf-rt-frontend-jaxws
cxf-rt-transports-http
cxf-rt-transports-http-jetty
Please could someone confirm if I am missing a dependency or if WebClient has been removed from version 3.1.11
If you're not sure about specific provider implementation, you can use classes which are standar parts of JAX-RS instead, which are duo Client and WebTarget. But for marshalling things, sure, you probably still need specific dependency configured, either manually or it's been already provided by the Apache CXF.
Client client = ClientBuilder.newBuilder().build();
WebTarget target = client
.target("http://localhost:8080/");
Response response = target.request().get();
Message message = client.readEntity(Message.class);
/*
// now.. process the message
for (Message message : message.get...) {.. }
*/
response.close(); // close connections.
You need to add cxf-rt-frontend-jaxrs instead of cxf-rt-frontend-jaxws

multiple servlet in jetty

I am new to Jetty and trying to understand by online example program. Here is the sample program I used:
public class EmbeddedJettyMain {
public static void main(String[] args) throws Exception {
Server server = new Server(7070);
ServletContextHandler handler = new ServletContextHandler(server, "/example");
handler.addServlet(ExampleServlet.class, "/");
server.start();
}
}
With that I can use:
http://localhost:7070/example/
Now I want to add one more servlet URI
http://localhost:7070/example2
How can I do this ?
I can see some reference such as webapp, looking for a good approach.
Server server = new Server(7070);
ServletContextHandler handler = new ServletContextHandler(server, "/");
handler.addServlet(ExampleServlet.class, "/example");
handler.addServlet(ExampleServlet.class, "/example2");
Each addServlet creates a mapping. Jetty will create an instance of the Servlet that will be a singleton for each mapping, meaning that init(ServletConfig config) will only be called once in each instance and all requests to a mapping go to the same instance.
Jetty provides a Web server and javax.servlet container.
Your servlets are stored and served via jetty's embedded container to serve when needed.

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)
);

How do you use HK2 dependency injection with Jersey 2.0?

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!

Categories

Resources