I have seen many examples on how to configure Jetty for HTTPS SSL for Jetty but they all seem to utilize a separate Server class containing a main method for execution. I want to execute my WebServlet as a standard servlet configured via the web.xml file. I currently have:
#WebServlet
public class MonitoringServlet extends WebSocketServlet {
#Override
public void configure(WebSocketServletFactory factory) {
factory.register(MonitoringSocket.class);
}
}
Where would I place my SSL Servlet configuration code? In the configure method of this Servlet? In the init method?
I do understand that in this case there is no need for instantiating a Server object and using .start() and .join
Servlets are just a means of producing a response to a request.
Typically a request can be from HTTP/0.9, HTTP/1.0, HTTP/1.1, or HTTP/2.
Using SSL/TLS for the secure part of the protocol.
Technically speaking, HTTP isn't even required for Servlets to function.
The protocol used to submit the request is outside of the control of the Servlet you are implementing to provide a response.
In Jetty, you'll want:
a Server instance
at least 1 Connector configured for SSL/TLS
at least 1 handler assigned to the Server
Using servlets without all of the baggage of a "web application" (a "web application" typically has a WEB-INF/web.xml, WEB-INF/classes, and WEB-INF/lib/*.jar) this would be a ServletContextHandler
Using servlets with a "web application" this would be a WebAppContext
This setup can come from a configured ${jetty.base} in the jetty-distribution or via embedded-jetty use of Java to build up the server, its connectors, and its handlers.
Related
I have been using Jersey, Tomcat, and Dropwizard for quite some time. But I am still not able to get what all actions happen from the point a request reaches port 8080 of a server to the point when it hits one of the methods annotated with #Path.
It will be really helpful if someone can help me with all(or a few important) layers in the whole architecture of restful API. For simplicity assume I have an application built with glassfish-jersey and deployed as the fat war using Tomcat.
When Jersey starts up, it will introspect registered resource classes and build a model of all the resources. This model includes the resource classes, the resources methods, and the paths and content-types that map to those resources/resource methods.
Jersey itself runs as a Servlet inside a Servlet container (e.g. Tomcat, Grizzly). The entry point Servlet is the Jersey ServletContainer. So when a request comes in, if the requested URI matches the configured servlet-mapping, the Servlet container will forward the request to the Jersey Servlet. Based on the requested URI and content negotiation, Jersey will go into the model mapping and determine which resource class and method should be called, and then call that method.
I see here spring boot packages the microservice artifact as jar file . It handles the http web request through module spring-boot-starter-web.
My understanding is spring boot internally does is
Makes the web server up
creates the war file , then host the war file on server.
Then http requests are handled through servlet lying under spring-boot-starter-web
Is my understnading correct ?
Your understanding is almost correct:
Starts a embedded tomcat server
Instructs the tomcat server how to act
HTTP requests are handled by an underlaying DispatcherServlet
spring boot entry point is main method, inside the main method we are calling SpringApplication.run(<#SpringBootApplication annotated class name> ,arguments);
when we invoking main method, SpringApplication class internally start the embedded server, configuratation and deploy the application in server...
here dispatcher servlet registered in servlet context on OnCondtion checking basis, if we are added spring-boot-starter-web then it checking condtion dispatcher-servlet available or not inside the class path if available then it will in registers the dispatcher-servlet in servlet context
We have an spring-boot application deployed in embedded jetty server listening on port X. Now I am integrating Apache Camel in this existing application by defining routes. The goal is to move few rest end points to camel routes that will be proxied to some other service. I am unable to understand following
When I use "jetty:http://localhost:Y/myapp" as one of route endpoints. It worked without any error. Does that mean Camel created its own jetty instance ?
When I use "jetty:http://localhost:X/myapp" - it again worked without giving error that address X is in use
I would like to keep control of jetty server configuration as they were and let camel listen to already existing rest end points.
If you can configure a servlet mapping which matches all paths which need to be redirected (for example, paths like foo/* are always redirected), then things are pretty easy. If this doesn't work you, I will try to edit my answer later.
The relevant page from the official docs is here. The interesting example for you is the one using the servlet component, because you already have a servlet container (Jetty) configured and running.
First, need to configure the Camel servlet. It depends on how your existing servlet(s) are configured; for instance, using a web.xml file, add:
<servlet>
<servlet-name>CamelServlet</servlet-name>
<servlet-class>org.apache.camel.component.servlet.CamelHttpTransportServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>CamelServlet</servlet-name>
<url-pattern>/foo/*</url-pattern>
</servlet-mapping>
Or, if you are using spring-boot, you can just register the following bean:
#Bean
public ServletRegistrationBean servletRegistrationBean() {
CamelHttpTransportServlet servlet = new CamelHttpTransportServlet("CamelServlet");
servlet.setServletName();
return new ServletRegistrationBean(servlet,"/foo/*");
}
Anyway, once you have the Camel servlet registered with your Jetty instance, you can use the servlet component, and redirect everything:
from("servlet:foo?matchOnUriPrefix=true")
.to("http4://new.com/foo?bridgeEndpoint=true&throwExceptionOnFailure=false");
http4 is the HTTP4 component, based on Apache HTTPClient 4.x. (you can still use the HTTP component base on HTTPClient 3.x if you want).
matchOnUriPrefix=true will match wildcards
bridgeEndpoint=true means we are acting as a proxy
throwExceptionOnFailure=false means errors returned by the new server will just be relayed to the caller, without being handled by Camel.
A request to http://old.com/foo/some/crazy/path/i/just/made/up should be redirected to http://new.com/foo/some/crazy/path/i/just/made/upĀ (and likely result in a 404 error from the new.com server, which will be simply forwarded to the initial caller).
Camel does not listen to "already existing" endpoints in the way you're expecting; it creates its own using the scheme-indicated component. You've created a Jetty endpoint (i.e. "jetty:..."), so Camel spins up a Camel Jetty component to handle HTTP requests at that endpoint.
If you want to use Camel as a proxy to redirect (which might be more easily accomplished with a network load balancer), then you'd spin up Camel routes to replace the existing endpoints and route them to the new endpoints.
from("jetty:http://oldendpoint.com")
.to("jetty:http://newendpoint.com");
I have a question about Protocol.FILE usage in this example from the Restlet site
// URI of the root directory.
public static final String ROOT_URI = "file:///c:/restlet/docs/api/";
[...]
// Create a component
Component component = new Component();
component.getServers().add(Protocol.HTTP, 8182);
component.getClients().add(Protocol.FILE);
// Create an application
Application application = new Application() {
#Override
public Restlet createInboundRoot() {
return new Directory(getContext(), ROOT_URI);
}
};
// Attach the application to the component and start it
component.getDefaultHost().attach(application);
component.start();
Why it is needed to add Protocol.FILE to the list of client connectors in order to serve directory/file content?
Simply because you use this protocol within the ROOT_URI variable ;-) Regarding protocols, you need to explicitly add them when creating the Restlet component. Client connectors provide a way to use protocols to access resources (local or remote).
Here are some more details about what happens under the hood:
When adding a Restlet extension in the classpath, some elements are registered within the engine. You can have converters, server connectors, client connectors, ... You can see what is registered on the instance of the Engine itself:
List<ConnectorHelper<Client>> clientConnectors
= Engine.getInstance().getRegisteredClients();
for (ConnectorHelper<Client> clientConnector : clientConnectors) {
System.out.println(clientConnector);
}
Regarding client connectors, they correspond to entities that are able to handle particular protocol(s). For example, the Jetty extension providers a client connector to execute HTTP and HTTPS requests based on the Jetty client API.
To actually be able to use these registered client connectors, you need to enable them by specifying the protocol you want to use. For example, if you add the HTTP protocol, Restlet will find the first client connector in the list of registered one that is able to handle this protocol. For execute HTTP request, it will use this connector. If there is no available connector, it will throw an exception...
In your case, the client connector for the FILE protocol is provided by Restlet core itself so it's automatically registered. But you need to explicitly tell Restlet that you want to use this protocol.
Hope it helps you,
Thierry
I'm writing a project for academic purposes which among other irrelevant stuff, includes writing a filter which monitors servlet/jsp response times.
The thing is that the filter should work on every deployed web application in the server and not only over a specific one, I just couldn't find any information regarding applying "global" filters.
Is it even possible?
NOTE:
It's important to mention that i'm using Apache Tomcat 7 as the server of choice.
Thanks!
Mikey
You could provide the filter in Tomcat's common classpath and edit Tomcat's own /conf/web.xml to add the filter, but this does not run on non-existing webapp contexts (i.e. it does not cover all possible requests) and it is overrideable in all deployed webapps. The more robust solution depends on the servlet container used. In case of Tomcat, you need the Valve component.
Kickoff example:
import org.apache.catalina.valves.ValveBase;
public class MyValve extends ValveBase {
#Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// ...
getNext().invoke(request, response);
}
}
register it as follows in server.xml:
<Valve className="com.example.MyValve" />
Filters are configured per-web app, but Tomcat itself may have a mechanism for timing request/response processing times.
You can config the url-pattern of your filter to process any request/response that you want. Please check http://www.caucho.com/resin-3.0/config/webapp.xtp#filter-mapping