How can I set the URL for a JSP page? - java

In a servlet I would just do
#WebServlet("/myURL")
But how would I do that with a JSP page?

Just like any servlet, you can map a particular URL-pattern to a JSP.
Simply add this snippet in your deployment descriptor
<servlet>
<servlet-name>fooBar</servlet-name>
<jsp-file>/foo.jsp</jsp-file> <!-- Your JSP. Must begin with '/' -->
</servlet>
<servlet-mapping>
<servlet-name>fooBar</servlet-name>
<url-pattern>/bar</url-pattern> <!-- Any URL you want here -->
</servlet-mapping>
There is no facility to have annotations inside the JSP so if you don't want to make an entry inside the web.xml and work purely with annotations, you have a work around to make a sevlet that simply forwards the RequestDispatcher to the JSP and you can annotate this servlet with the URL that you want.
#WebServlet("/bar") //your URL pattern
public class DummyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.getRequestDispatcher("/path/to/foo.jsp").forward(request, response);
}
}

Related

404 page not found despite correct config

I have a simple web application that runs on Tomcat.
The first page opened after I run the app from IntelliJ is the page from index.html
There user click on button and is redirected to dashboard page. It looks like this in index.html:
<button id="enter" type="button"> ENTER </button>
I have a servlet:
#WebServlet("/dashboard")
public class DashboardServlet extends HttpServlet {
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("html/dashboard.html");
rd.forward(request, response);
}
}
And I have dashboard.html file located in web/html/dashboard.html
After user clicks on button on first page, he is redirected to the next page (the dashboard page) but I see only 404 instead of page.
I cannot find what is wrong here. To solve the problem I added this to my web.xml:
<servlet>
<servlet-name>DashboardServlet</servlet-name>
<servlet-class>airport.flight.control.servlet.DashboardServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DashboardServlet</servlet-name>
<url-pattern>/dashboard</url-pattern>
</servlet-mapping>
It gave me is error message from Tomcat when I opened the problematic dashboard page again:
java.lang.ClassNotFoundException: airport.flight.control.servlet.DashboardServlet
I find this exception very weird, because this is the reference to class that I've just copied...

Adding default servlet and forwarding to an HTML creates stackoverflowerror

I am using Jetty. My default servlet is making a simple forward to an HTML file in my WEB-INF folder that is causing a java.lang.StackOverFlowError error. The error is fixed if I rename the file I am forwarding from a .html to .jsp
DefaultServlet.java
public class DefaultServlet extends HttpServlet{
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException{
req.getRequestDispatcher("WEB-INF/home.html").forward(req, resp);
}
}
web.xml
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>Default</servlet-name>
<servlet-class>DefaultServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Default</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
My guess is that instead of inserting the html content in the response body, the forward is sending the browser a redirect to /WEB-INF/home.html. This again calls the DefaultServlet and gets into an infinity loop. How can I prevent this?
Thanks.
The "default servlet", which is mapped on a special URL pattern of /, is a very special servlet which is invoked when there's a request which does not match any of the servlets mapped on a more specific URL pattern such as *.jsp, /foo/*, etc.
When you forward to home.html, for which apparently no one servlet is registered, then the default servlet is invoked once again. However, the default servlet is ignorantly forwarding to the very same HTML file once again instead of actually serving the requested HTML file. It'll on the forward still find no one servlet matching the forward URL and it'll still invoke the default servlet once again. And again. Etc. When this is performed so many times that the stack cannot keep track anymore of all those in sequence invoked doGet() methods (usually around 1000), then you'll get a StackOverflowError.
That it works with a JSP file has actually a very simple reason: there's already a JspServlet registered on an URL pattern of *.jsp. So the badly designed default servlet isn't invoked.
Your default servlet should instead be obtaining the HTML file's contents via ServletContext#getResourceAsStream() and write it to the HttpServletResponse#getOutputStream().
However, it's also quite possible that you completely misunderstood the whole meaning of "default servlet" and/or the special meaning of the URL pattern / and actually merely want a servlet acting as home page. In that case, you should be mapping the servlet on a more specific URL pattern (and please rename the currently obviously quite confusing class name DefaultServlet to something else):
<servlet>
<servlet-name>home</servlet-name>
<servlet-class>com.example.HomeServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>home</servlet-name>
<url-pattern>/home</url-pattern>
</servlet-mapping>
And then register exactly that URL as welcome file:
<welcome-file-list>
<welcome-file>home</welcome-file>
</welcome-file-list>
You need kind of exclude urls ends with "html".
See for example this link explaining similar problem solution Can I exclude some concrete urls from <url-pattern> inside <filter-mapping>?

How to avoid user access to .xhtml page in JSF?

I am new to JSF and writing first simply jsf web app.
URL with .jsf are mapping to .xhtml files in WebContent but why I can open .xhtml in web browser with all jsf tags. How to protect this?
You could add a security constraint to your web.xml blocking all requests to *.xhtml.
<security-constraint>
<display-name>Restrict raw XHTML Documents</display-name>
<web-resource-collection>
<web-resource-name>XHTML</web-resource-name>
<url-pattern>*.xhtml</url-pattern>
</web-resource-collection>
<auth-constraint />
</security-constraint>
Apart from defining a <security-constraint> to block direct access to .xhtml files as correctly answered by Stacker on this question, you could also just change the <url-pattern> of the FacesServlet mapping from *.jsf to *.xhtml.
<servlet>
<servlet-name>facesServlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>facesServlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
In JSF 1.x this used to end up in an infinite loop, but in JSF 2.x not anymore. So you could just call/link all pages as .xhtml without fiddling with different extensions. The only disadvantage is that you won't be able to display a "plain" XHTML file without invoking the FacesServlet, but such a page should be named .html anyway :)
On GAE you need two things:
edit web.xml as described above
add in appengine-web.xml
<static-files>
<exclude path="/**.xhtml" />
</static-files>`
You can use a servlet filter
#WebFilter(filterName = "XhtmlFilter", urlPatterns = { "*.xhtml" })
public class XhtmlFilter implements Filter {
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
((HttpServletResponse) response).sendError(404);
chain.doFilter(request, response);
}
#Override
public void destroy() {
}
}
as far as i experienced it, the answer of mk761203 is definitely helpful when setting up a project for google app engine and server faces. without the exclusion of this files, the GAE automatically interpets the files with the .xhtml extension as static files which get served by dedicated servers from googles server farm. read more here: https://developers.google.com/appengine/docs/java/config/appconfig#Static_Files_and_Resource_Files

Customize <url-pattern> to link a Form to a FormAction

First, I am a newbie in Java/J2EE development. So, please be indulgent with my leak of vocabulary (but feel free to correct me ;)
Here is my first problem :
I built a first form (named form1) in a .jsp page :
<form name="form1" action="formaction1.do" method="get">
I redirect the result of my form to a FormAction1 java class :
<servlet>
<servlet-class>com.servlet.myproject.FormAction1</servlet-class>
<servlet-name>FormAction1</servlet-name>
</servlet>
<servlet-mapping>
<servlet-name>FormAction1</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Here is my FormAction1 java class :
public class FormAction1 extends HttpServlet
{
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
request.getRequestDispatcher("formaction1.jsp").forward(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException
{
doGet(request, response);
}
}
This is working fine.
Now, I'd like to create another form, named form2, and link it to FormAction2.
However, FormAction1 receives every .do request !
I tried to customize my <url-pattern> by writing :
<url-pattern>formaction1.do</url-pattern>
I guess it would've been too easy :D
Tomcat doesn't like it : I get a 404 error on every page of my project.
So, do you have any solution ?
Just a bonus question :
What's the point to use a class like FormAction1, rewrite doGet method, while I can just write :
<form name="form1" action="anotherFile.jsp" method="get">
and recover infos with a request.getParameter() in anotherFile.jsp ?
doesn't url-pattern requires a match starting from the beginning, in that case
<url-pattern>/formaction1.do</url-pattern>

how to call jsp file from java?

I have two jsp file and one java file. My constraints is if jspfile1 call java then java file call the jspfile2. Is it possible?
How to achieve this?
If by "Java file" you mean a Servlet, you can use the RequestDispatcher:
request.getRequestDispatcher("/my.jsp").include(request, response);
request.getRequestDispatcher("/my.jsp").forward(request, response);
The normal way is using a Servlet. Just extend HttpServlet and map it in web.xml with a certain url-pattern. Then just have the HTML links or forms in your JSP to point to an URL which matches the servlet's url-pattern.
E.g. page1.jsp:
<form action="servletUrl">
<input type"submit">
</form>
or
click here
The <form> without method attribute (which defaults to method="get") and the <a> links will call servlet's doGet() method.
public class MyServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// Do your Java code thing here.
String message = "hello";
request.setAttribute("message", message); // Will be available in ${message}.
// And then forward the request to a JSP file.
request.getRequestDispatcher("page2.jsp").forward(request, response);
}
}
If you have a <form method="post">, you'll have to replace doGet by doPost method.
Map this servlet in web.xml as follows:
<servlet>
<servlet-name>myServlet</servlet-name>
<servlet-class>com.example.MyServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>myServlet</servlet-name>
<url-pattern>/servletUrl</url-pattern>
</servlet-mapping>
so that it's available by http://example.com/contextname/servletUrl. The <form> and <a> URL's have to point either relatively or absolutely to exact that URL to get the servlet invoked.
Now, this servlet example has set some "result" as request attribute with the name "message" and forwards the request to page2.jsp. To display the result in page2.jsp just do access ${message}:
<p>Servlet result was: ${message}</p>
Do a http web request.
jsp files get converted to a servlet. You cannot call them directly.
EDIT : typo fixed.

Categories

Resources