javax.servlet.ServletException: AS-WEB-CORE-00089 exception In servlets - java

I have a servlet called Document to which I want to redirect all requests starting with Document something like
http://localhost:8080/CollabEdit/Document/abcdwcklsclds
should be redirected to servlet Document.
So, I used an annotation like this :
#WebServlet("/Document/*")
However, for some unidentified reason, it gives an exception that says:
javax.servlet.ServletException: AS-WEB-CORE-00089
This exception is in Document.java is thrown as soon as I call
request.getRequestDispatched("main.html").forward(request, response) .
otherwise no exception.
however, With same request in other servlets, main.html gets called just fine.

A forward and a redirect are not the same thing. A redirect allows you to go to any URL, eventually on another server or with another protocol, because you ask the client to query that URL.
In a forward you ask the servlet container to pass the control to another servlet of the same application (inside same context). As you use a relative path you are actually requesting what is the servlet for : http://host.do.main/appname/Document/main.html because the relative URL is added at the end of the address of current page (it could even be .../Document/.../main.html) !
And you declared that any page under /Document should be served by the Document servlet ... so the infinite loop ...
You can fix it two ways :
if you really need to use relative paths (it is inherently dangerous but you might have reasons to do it), try ../main.html if called from /Document or ../../main.html if called from /Document/something
use an absolute path :
contextPath = request.getContextPath();
request.getRequestDispatcher(contextPath + "/main.html").forward(request, response)

The Filter looks right.
Are you using Servlets 3.0 and no older version? In older versions you would have to edit the web.xml. And in 3.0 it would have to look like in this Post
Does Document extend HttpServlet?
Could you show us some more of your Code, maybe then it would be easier to see what's going wrong.
Greetings

Related

How to prepend front controller servlet mapping to urls in jsp

I have a simple java web application running in Tomcat.
In it, FrontController.java servlet has mapping #WebServlet("/controller/*"). So, in order to fire the servlet, I need my every url to start with /controller/. I need to be able to display images on pages images are stored outside container, so that I write them to OutputStream). But if I write my src urls like ${pageContext.request.contextPath}images/picture.jpg then the resulting url will be obviously localhost:8080/rootFolder/images/picture.jpg and not the localhost:8080/rootFolder/controller/images/picture.jpg.
To load these files I can either manually prepend controller/ after every ${pageContext.request.contextPath} which is bad or I can follow the advice found here append dispathcer servlet mapping to url and add line request.setAttribute("frontControllerMapping", "controller/"); to every method which processes request and then code urls like this ${pageContext.request.contextPath}${frontControllerMapping}images/picture.jpg which is better.
My questions are how to prepend the controller mapping to every url which must be processed by servlet and how to do it right? Is the second option the correct way to do so?
Instead of adding the complete URL for each resource you can use relative URLs. If that is not an option, than you could simply map all requests to your servlet like this:
#WebServlet("/*")
Then you don't need to worry about adding the controller path to all URLs.

How to use same content for JSP and email sent by a separate process?

Background
I have a java.lang.Thread that runs inside an application on a web server (JBoss or WebSphere) at a specific time, without human interaction, and all it does is send out an email. The contents of the email are similar to the contents of a JSP (/jsp/Report.jsp) we use as a display in a web view.
Instead of duplicating the same work or changing the JSP to a static class both can access, I would like to grab the contents of the run of the JSP from inside the thread and place it in the email for sending.
I have the current ServletContext from using a listener in the "web.xml". My current JSP call in the thread is like:
servletContext.getRequestDispatcher("/jsp/Report.jsp").include(dummyRequest, dummyResponse);
And the request/response classes are basically created like this:
final HttpServletRequest dummyRequest = new HttpServletRequest() { .... }
final HttpServletResponse dummyResponse = new HttpServletResponse() { .... }
I was going to set additional attributes (Classes) to the JSP via the dummyRequest like "dummyRequest.setAttribute(name, value)".
Whenever I make the call, I get exceptions because the dummy request/response is an anonymous class of HttpServletResponse/HttpServletRequest.
WebSphere Application Server 7.0.0.17:
java.lang.RuntimeException: SRV.8.2: RequestWrapper objects must extend ServletRequestWrapper or HttpServletRequestWrapper
JBoss AS 7.1.1:
java.lang.ClassCastException: my.test.thread$1$2 incompatible with javax.servlet.ServletRequestWrapper
And I can't create a HttpServletResponseWrapper/HttpServletRequestWrapper without an original request/response.
Question
So.... Is it possible to grab the contents of a JSP from inside a Thread on a web application using the context?
If so, how do I go about doing it?
Update
Here is the code I am using for my test: link
Research
I've now started diving into the server's source code to try and get a clue what is going on.
JBoss
In ApplicationDispatcher, "forward" does nothing since the "DISPATCHER_TYPE" attribute isn't set in the request (seen in the method processRequest). This isn't required for "include".
The problem I get with "incude" about the incompatible type is inside "ApplicationFilterFactory.createFilterChain". The Request object isn't the right class it is looking for, which in JBoss' case is either "org.apache.catalina.connector.Request" or "org.apache.catalina.connector.RequestFacade". It won't continue at all unless the request matches one of these types.
So when I use the following request:
final HttpServletRequest dummyRequest = new org.apache.catalina.connector.RequestFacade(new org.apache.catalina.connector.Request() { ... });
It successfully runs and returns the results of the JSP from inside the thread.
Websphere
I have not been able to produce the same results on Websphere.
Websphere requires an instance of "com.ibm.ws.webcontainer.srt.SRTConnectionContextImpl" and then manipulating the ServletContext to its original class "com.ibm.wsspi.webcontainer.facade.ServletContextFacade", but then I get stuck on an "access$200" null pointer exception inside "com.ibm.ws.webcontainer.srt.SRTServletRequest$SRTServletRequestHelper", which makes it seem like I am breaking Java somehow.
java.lang.NullPointerException at com.ibm.ws.webcontainer.srt.SRTServletRequest$SRTServletRequestHelper.access$200(SRTServletRequest.java:2629)
This is my current code:
SRTConnectionContext n = new SRTConnectionContextImpl();
(((SRTServletRequest) (n.getRequest())).getRequestContext())
.setCurrWebAppBoundary((WebApp) ((ServletContextFacade) context)
.getIServletContext());
servletContext.getRequestDispatcher("/jsp/Report.jsp").include(n.getRequest(), n.getResponse());
The End
Hopefully someone can find a way to accomplish this on Websphere.
From my viewing of the source, unless there is a side method I am missing, you cannot run a include/forward without the server's own specific class files for the request. Even request wrappers are unwrapped to their base classes, and that is why I was always getting the Class Cast Exception with and without a wrapper.
If there isn't a cleaner, not server specific with server classes, method of getting the results of a JSP from inside a thread, than this may be the answer to my original question, regardless of how messy it seems.
because the dummy request/response is an anonymous class of
HttpServletResponse/HttpServletRequest.
No. you get classcast exception b/c they are different container expects wrapper.. your code is providing request/response.
It is not very clear to us where exactly you are making call to create dummy HttpServletRequest/Response.. looks like from where you are calling... you actually need to instantiate ServletRequestWrapper/responseWapper object, set you request on it if you have a handle, and work with it.
May be this can help
http://hc.apache.org/ to read the html out of your jsp/response and create email out of it.

Playframework routes question

I have this in my applcation routes file:
GET /new Tweets.create
POST /new Tweets.save
And in my view I'm creating a form like this:
#{form #save()}
...
#{/form}
But once is submit the form it's sending me to /tweets/save and not to /new. Any ideas how I can fix this? Thanks!
If you have already tried the route below (which is the correct way to use routes)
#{form #Tweets.save()}
and this did not work, I think you may have put your route in the wrong place. Make sure it is at the top of the routes file, and not after the catch-all route. The routes file is processed in order, so if the catch-all is found, this is used first and your other route is ignored. The catch-all looks like
* /{controller}/{action} {controller}.{action}
Try using
#{form #Tweets.save()}
I think it is suggested to use class names with method names.
EDIT:
The way the play framework routing works is you define some route as
GET /clients Clients.index
If a request encountered with URI /clients then it will be intercepted to Clients.index(). If you have another routing such that
GET /clients Clients.save
Then the framework ignores this routing because /clients aready has a mapping. (Most probably it is giving some error in the console or logging stream, check your logs.)
Therefore you can't make it work like that. I see, you request a reverse mapping that will return the same URI for different methods. However the framework aims to intercept requests so that it will simply ignore your second routing.
Try to separate pages. Most probably what you want is to render the same views for two functions. You can do that without redirecting them to the same URI.
I think (if I did not misread) that the issue is you expecting the wrong behavior.
As I understand you expect that the submit will go to Tweet.save() (POST method) and then back to Tweet.create() (GET method) as both share the same path (/new).
In reality Play is calling Tweet.save() and it expects a render at the end of Tweet.save() to display some result. If you want to redirect to Tweet.create() you can do a call to that method at the end of the implementation of Tweet.save(), with either:
create(<params>);
or
render("#create", <params>);
and that should redirect (via 302) to the GET version.

Make all requests to mysite.com/user/specified/path run the same JSP

I want to allow users to create groups in my application and access them via URL. For example, if you made a group called "sweethatclub," you could access it at http://mysite.com/sweethatclub. Of course, the same code will run for /sweethatclub and /drillteam and even /students/yearbook
I'm running in a Java servlet environment, and can't quite get the paths to align for this. I can write a filter that intercepts all requests and adds information to the request by parsing the URL, but then I want to run the code of an index.jsp. I don't want to map index.jsp to all URLs, because, for example, /images/smiley.jpg still needs to respond the with appropriate file instead of index.jsp.
Is there a way to send all requests to a servlet, unless the request is matched by a plain-old file? Or, is there some other way to accomplish what I want here?
Please let me know if I need to supply more information. I'm new to this environment.
The URL patterns in the web.xml are not supposed to be smart enough to figure out target URL's nature. If you can tolerate it, the easiest way would be to place all the user specified paths under a a well known root... someplace separate from the static files. So you end up with user specified paths like http://mysite.com/sites/sweethatclub.
Alternatively, you can move all your static content under http://mysite.com/static/, and set up the servlet mappings or filters to treat anything starting with 'static' different from the dynamic URL space.
If you are in a Unix invironment, you could just create all the "group sites" as virtual directories that just point to your default one.
Map the servlet on a specific URL pattern
<url-pattern>/groups/*</url-pattern>
Put all static content in a common folder, e.g. /static and fix all URLs in the pages to point to that URL instead.
Create a filter which is mapped on
<url-pattern>/*</url-pattern>
and does the following job in doFilter() method
String uri = ((HttpServletRequest) request).getRequestURI();
if (uri.startsWith("/static/")) {
chain.doFilter(request, response); // Goes to default servlet.
} else {
request.getRequestDispatcher("/groups" + uri).forward(request, response);
}
No, this does not end up with /groups in browser address bar URL. It's fully transparent. You can if necessary make "/static" and/or "/groups" an <init-param> of the filter so that it's externally configureable.

A servlet or filter that dynamically maps /xxx/yyy/zzz to class XxxYyyZzz.java

I want to write a servlet or filter that automatically maps the url /xxx/yyy/zzz to class XxxYyyZzz.java.
For example the following URLs will map to the following java classes:
/comment/add --> CommentAdd.java
/comment/delete --> CommentDelete.java
/comment/view --> CommentView.java
/search --> Search.java
/viewposts --> Viewposts.java
In addition the servlet or filter must comply with two extra requirements:
The servlet or filter should have a servlet mapping of "/*", I dont want a prefix with several servlets "/comment/*", "/search", etc.
Maybe difficult, but having a servlet mapping of /* should not allow it to override the JSP processing. Meaning, if a class is not found, it should check if a jsp page exists and run it.
I want to know how can this be done using the Servlet API. Please don't refer me to any framework that does the job. Just show me the code.
The classes that are mapped to will follow the command pattern or could be a subclass of the HttpServlet. In both cases, a method should exist like "execute(HttpServletRequest request, and HttpServletResponse response)". This method will be automatically executed once the URL is accessed and the java class is figured out possibly using a single servlet or filter.
I'm not sure, if I got what you mean. In case I did:
You need nothing special, write a single Servlet mapped to "/", so it gets everything. Parse the PATH_INFO (don't know now how it gets called in Java), use Class.forName (or use a pre-filled Map), and call its method execute.
Here is a http://www.tuckey.org/urlrewrite/ filter implementation that might help you. Check it out. I have not used it myself though.
You can use Stripes framework with its default NameBasedActionResolver config.

Categories

Resources