List servlets in a java webapp (running in tomcat) - java

I am trying to re-package a relatively big java webapp which I did not code and for which the project configuration was lost.
I setup a first packaging, and deployed it in tomcat. Now to understand it, I'd like to get a list of the servlets that started successfully or failed, with corresponding access url.
Is there a way to get that list (from some startup log maybe)?
Some details: the webapp uses gwt (which I don't master), I use tomcat7 on ubuntu. I am not against a solution using another servlet container, if practical.

I would write a simple JSP or ServletContextListener to read all the ServletRegistratioins from the servlet context and display them.
So your JSP/ServletContextListener would read the data from
servletContext.getServletRegistrations();
and just display it.
Edit
#WebServlet(urlPatterns = "/mappings")
public class TestServlet extends HttpServlet {
private static final long serialVersionUID = -7256602549310759826L;
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
Map<String, ? extends ServletRegistration> registrations = req
.getServletContext().getServletRegistrations();
for (String key : registrations.keySet()) {
ServletRegistration registration = registrations.get(key);
writer.write("Name: " + registration.getName());
writer.write("<br>Mappings:");
for (String mapping : registration.getMappings()) {
writer.write(mapping);
}
}
// of course you can write that to log or console also depending on your
// requirement.
}
}

You can see started modules and paths in Tomcat by double click at Tomcat and see Modules tab.

Related

Change Tomcat Webapp directory from code

I have a Webapp running on Tomcat. This app has an entry Servlet which receives a certain parameter. It looks like this:
https://localhost:8443/myapp/entryservlet?param=app1
This parameter param indicates which webapp should be loaded.
In my Webapp directory I have a structure like this:
-WebApp
-- App1
-- App2
-- App3
...
Depending on the parameter, I have to tell Tomcat which webapp should be loaded
Obviously, you're not passing in the entire URL as a parameter, but here's a sample redirecting to another url. You can also look at forwarding.
public class EntryServlet extends HttpServlet {
public final void doGet(HttpServletRequest request, HttpServletResponse response
) throws ServletException, IOException {
String forwardURL = request.getParameter("param");
response.sendRedirect( forwardURL );
}
}

Eclipse: Thrift inside Tomcat Servlet, ClassNotFoundException TException

I'm trying to make a Java servlet that can make Apache Thrift calls, but I'm having trouble starting the servlet.
I have a thrift client, a Java class for making calls to the thrift server
public class ThriftClient {
static TTransport transport;
static TProtocol protocol;
static MyService.Client client;
static long xtk_pointer;
public static void openSocket() throws TException {
transport = new TSocket("localhost", 9090);
transport.open();
protocol = new TBinaryProtocol(transport);
client = new MyService.Client(protocol);
}
and I have a java servlet which opens a socket through the thrift client
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
out.println("Hello World");
}
void startThrift(String [] args) {
try {
ThriftClient.openSocket();
However, when I try to run this servlet (using eclipse and a tomcat server), I get an error like
SEVERE: A child container failed during start
and a ClassNotFoundException for org.apache.thrift.TException
EDIT: All I had to do was include the thrift jars into the Tomcat Server's classpath. See my answer below
I have used the thrift client already without any ClassNotFoundExceptions, and the servlet works on its own as well. However, once I add ThriftClient.openSocket(); into the servlet, it breaks, so I have a feeling Thrift and Tomcat are clashing somehow. Any ideas?
Edit: The weird part is that I never call the method startThrift() but I still get the error.
While you included the thrift jars into your project, you also have to add them to the Tomcat library as well
First make sure your external jars are in your project Java Build Path...
right click your project, click Properties
Under Deployment Assembly, click Add...
Double click Java Build Path Entries... and select the jars/libraries you want to include

How to Add robots.txt to a Vaadin 7 Application with CDI-Integration?

how can I add a robots.txt file to a Vaadin application?
I found nearly nothing related, but what I found states that there is no support for such a file.
I'm using Vaadin 7.1.1 with JBoss 7.1.1 and Vaadin-CDI-Integration.
My workaround approach is: By adding RobotsUI to the project, the URL http://localhost:8080/App/robots.txt becomes accessible.
#CDIUI(value="robots.txt")
public class RobotsUI extends UI {
#Override
protected void init(VaadinRequest request) {
// Send a response with mimetype
// `text/plain` with self defined content.
}
}
My problem is: How can I deliver a self-edited, text/plain response?
Thanks for any help :-)
I successfully published text/plain by adding a common HttpServlet to the project:
#WebServlet("/robots.txt")
public class RobotsServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.getWriter().write("Text...\n");
}
}
Do it outside of Vaadin, register a filter before vaadin servlet and in case of robots.txt uri return your robots file. Or add some static resource serving servlet registered lets say to /static/* and bind your /robots.txt redirect with UrlRewrite.

The requested resource is not available for servlet 3.0 and tomcat 7.0

My dynamic web module version is 3.0 and tomcat my tomcat version is 7.0.
I don't know why it can't see my servlet XD when I navigate to the page localhost:8080/SimpleProject.
When I navigate to localhost:8080/SimpleProject/firstservlet, I get the error message that says the requested resource is not available!
Here's my servlet:
#WebServlet(description = "the first servlet", urlPatterns = { "/firstservlet" })
public class FirstServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// response.setContentType("text/html");
PrintWriter writer = response.getWriter();
writer.println("<h1>Why can't See<h1>");
}
I didn't do anything on my web.xml because what I know is in 3.0 version the url mapping is in the servlet.
this is my file arrangement :)
Have you check the log files to see if some exception is being thrown when loading/executing your servlet FirstServlet?
Did you check the content of your war file to make sure it is packaged properly and the servlet class is in it (you can open a war file like you would a zip file).

Wrap the default servlet but override the default webapp path

I have a folder of static html,imgs,flash content that lives outside of the webapp folder. Right now I'm using a symbolic link to map that folder into my webapp directory. The problem i have is when I undeploy my application it follows the symbolic link and deletes all these files.
One of the solutions I'm trying to implement is a special servlet that wraps the default servlet but uses a different relative path. I'm having trouble finding out how to wrap the default servlet in a way that overrides the default servlet path.
Here is what I'm working with:
public void doGet(final HttpServletRequest req, final HttpServletResponse resp)
throws ServletException, IOException {
final RequestDispatcher rd = getServletContext().getNamedDispatcher("default");
final HttpServletRequest wrapped = new HttpServletRequestWrapper(req) {
#Override
public String getServletPath() {
return "/usr/depot/repository";
}
};
rd.forward(wrapped, resp);
}
You can override DefaultServlet with your own implementation. You can perfectly subclass it, it's a public class. Here are the functional specifications of the DefaultServlet, you need to adhere it.
On the other hand you can ignore DefaultServlet and go for your own solution, an example can be found here.
You can either write your own servlet to serve static content (which is not that hard) or try to extend rather than wrap the DefaultServlet. Either way, your resulting servlet will have be configured in place of default in your web.xml (using "default" as servlet-name).
That said, DefaultServlet will only serve static content from under your webapp context; in order to change that you'll have to create / bind to JNDI your own ProxyDirContext instance pointing to the outside folder and I'm not sure whether that will work; its configuration process is rather involved.
Trying to override servlet path will not get you anywhere.
We have a similar problem that we need to share some files generated by CMS among several applications. Symlink is the easiest way to do this if you are not using Windows.
We setup 2 accounts for CMS and Tomcat. The files are read-only to Tomcat so it can't delete them.
You can also write a small Tomcat extension so it can look for files in multiple places. See this web site,
http://blog.bazoud.com/post/2009/05/12/Multiples-docbases-avec-tomcat
Your current approach won't work. Tomcat needs to load up all the resources in a cache on deploy for it to be available. It's too late to change that in request processing. This extension allows Tomcat load resources from multiple directories. The drawback of this approach is that you have to put a small JAR in server/lib.
That's not a good idea.
Web containers or application servers can be deployed behind Web servers or you can simply use a Web server in conjunction with your container. Just put your static files under that and refer to them by absolute path.
There's really no need for this kind of hack (sorry but that's what it is).
Either that or simply deploy them with the Web app.
You can change to a different path within your webapp context. Here's an example which does differential serving depending on whether the client's User-Agent supports ES6:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
RequestDispatcher rd = getServletContext().getNamedDispatcher("default");
HttpServletRequest wrapped = new HttpServletRequestWrapper(req) {
#Override
public String getServletPath() {
String prefix = supportsES6(req) ? "/es6" : "/es5";
String newPath = prefix + req.getServletPath();
if (newPath.endsWith("/")) newPath += "index.html";
return newPath;
}
};
rd.forward(wrapped, resp);
}
However, "es5" and "es6", even though we use the initial slash, are subdirectories of the webapp's ordinary context. It's not possible to break outside of the context directory using this method.
I have open-sourced a custom servlet that serves files from an arbitrary base path. Additionally, it supports file browsing inside nested compressed archives.
It's available here: https://bitbucket.org/teslamotors/zip-listing/overview

Categories