Getting init parameter while accessing JSP file by filename - java

I'm trying to access init parameter in a JSP file.
When I enter a url-pattern from servlet mapping like this: http://localhost:8080/JEE_Learning/testingJSP
it works fine, the parameter is there.
But when I enter a JSP filename: http://localhost:8080/JEE_Learning/testing.jsp
the parameter is null.
web.xml:
<servlet>
<servlet-name>testingJSP</servlet-name>
<jsp-file>/testing.jsp</jsp-file>
<init-param>
<param-name>name</param-name>
<param-value>John</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>testingJSP</servlet-name>
<url-pattern>/testingJSP</url-pattern>
</servlet-mapping>
inside JSP file:
<%= getInitParameter("name") %>
Why is that?

If you add
<%=getServletConfig().getServletName()%>
to the JSP page you will see the output
testingJSP when calling .../testingJSP and
jsp when calling .../testing.jsp (in Tomcat).
So the first request invokes the testingJSP servlet the second the JSP servlet of the container. Accordingly the servlet init parameter is only defined in the first request.

If you want to access the name parameter from
http://localhost:8080/JEE_Learning/testingJSP and
http://localhost:8080/JEE_Learning/testing.jsp
then you should add
<url-pattern>/testing.jsp</url-pattern>
to your
<servlet-mapping>

Related

Why I get null when retrieving servlet's init parameter from JSP?

I have DD (web.xml file) with very simple code:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd" id="WebApp_ID" version="4.0">
<display-name>TestProject</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>test</servlet-name>
<jsp-file>/result.jsp</jsp-file>
<init-param>
<param-name>email</param-name>
<param-value>example#gmail.com</param-value>
</init-param>
</servlet>
<context-param>
<param-name>name</param-name>
<param-value>Max</param-value>
</context-param>
</web-app>
Notice I have two parameters (one in application, other in configuration scope). When I try to get them inside result.jsp with:
<html><body>
Name is: <%=application.getInitParameter("name") %>
<br>
Email is: <%=config.getInitParameter("email") %>
</body></html>
, I get following output:
Name is: Max
Email is: null
My question is simple: how did I get NULL for "email" parameter? Shouldn't my JSP file "see" how I configured it and return "example#gmail.com"?
Is that your entire web.xml file? And by any chance are you accessing the JSP directly in the browser? Like:
http://localhost:8080/<yourAppContext>/result.jsp
If that is the case, then you will get this response:
Name is: Max
Email is: null
It is not wrong. It is correct.
The reason you get this result is that you are not accessing the JSP through the configuration you defined in web.xml, you are just accessing the JSP directly, which behind the scene has a different implicit configuration, and it's not the one you think you are configuring.
If you want this response:
Name is: Max
Email is: example#gmail.com
Then you need to add a servlet mapping. The complete configuration is:
<servlet>
<servlet-name>test</servlet-name>
<jsp-file>/result.jsp</jsp-file>
<init-param>
<param-name>email</param-name>
<param-value>example#gmail.com</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/test</url-pattern>
</servlet-mapping>
and you need to access this URL, not the JSP path, with:
http://localhost:8080/<yourAppContext>/test
You might want to also read these:
Url Mapping For Jsp
Servlet JSP web.xml
To further drive the point home, it's important to mention that you need a mapping for one of your servlets to be useful. If you just define a servlet in web.xml, it just sits there. You need to tell the server how to use it, and for that you use the <servlet-mapping>. It's saying to the server that for a request on a path, some specific servlet needs to be called to handle the request.
You can create this mapping to point to a servlet class using <servlet-class> or to a JSP using <jsp-file>. They are basically the same thing, since a JSP eventually becomes a servlet class.
What I think is confusing you (based on the comment below) is that for JSP files you already have some implicit mapping created by the server, as described here.
When you access the JSP directly, with
http://localhost:8080/<yourAppContext>/result.jsp
you are using the implicit server mapping which contains no special configuration attached (like the email you want to send to it).
When you access the JSP with
http://localhost:8080/<yourAppContext>/test
you are accessing your mapping. And this you can configure however you want, and send it whatever parameters you want, and your JSP will now be able to read them.

web.xml URL pattern

Can anyone give me the information regarding rules in setting URL pattern and if I am using / as my index page and also I need to use request.getRequestDispatcher("/html/file.html").forward(request,response).
File file.html is in the html folder which is under war folder, html folder is in the same folder of WEB-INF
Can any one give me suggestion?
Thank you
You can define a servlet in your web.xml as below and then use request.getRequestDispatcher("file").forward(request,response), essentially what will happen is that you would be dispatching your request to a servlet whose mapping is /file and that servlet would point you to your resource /html/file.html. Please note that even though the element name is jsp-file but you can point a HTML from it.
<servlet>
<servlet-name>FileServlet</servlet-name>
<jsp-file>/html/file.html</jsp-file>
</servlet>
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/file</url-pattern>
</servlet-mapping>
As an add-on - coming to how URL patterns matches the serlvet mapping present in web.xml file, below are servlet mapping rules in web.xml (sources of this are - Servlet specs and #BalusC answer):
1. Path mapping:
If you want to create a path mapping then start the mapping with / and end it will /*. For example:
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/foo/bar/*</url-pattern> <!-- http://localhost:7001/MyTestingApp/foo/bar/index.html would map this servlet -->
</servlet-mapping>
2. Extension mapping:
If you want to create an extension mapping then have servlet mapping *.. For example:
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>*.html</url-pattern> <!-- http://localhost:7001/MyTestingApp/index.html would map this servlet. Also, please note that this servlet mapping would also be selected even if the request is `http://localhost:7001/MyTestingApp/foo/index.html` unless you have another servlet mapping as `/foo/*`. -->
</servlet-mapping>
3. Default servlet mapping:
Suppose you want to define that if a mapping doesn't match any of the servelt mapping then it should be mapped to the default servlet then have servlet mapping as /. For example:
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/</url-pattern> <!-- Suppose you have mapping defined as in above 2 example as well, and request comes for `http://localhost:7001/MyTestingApp/catalog/index.jsp` then it would mapped with servlet -->
</servlet-mapping>
4. Exact match mapping:
Suppose you want to define exact match mapping then do not use any wild card character or something, and define the exact match, like /catalog. For example:
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/catalog</url-pattern> <!-- Only requests with http://localhost:7001/MyTestingApp/catalog will match this servlet -->
</servlet-mapping>
5. Application context root mapping:
The empty string "" is a special URL pattern that exactly maps to the
application's context root. i.e., requests of the form http://localhost:7001/MyTestingApp/.
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern></url-pattern> <!-- Only requests with http://localhost:7001/MyTestingApp/ will match this servlet Please note that if request is http://localhost:7001/MyTestingApp/abc then it will not match this mapping -->
</servlet-mapping>
6. Match all mapping:
If you want to match all requests to one mapping or override all other servlet mapping then create a mapping as /*.
<servlet-mapping>
<servlet-name>FileServlet</servlet-name>
<url-pattern>/*</url-pattern> <!-- This will override all mappings including the default servlet mapping -->
</servlet-mapping>
Below is the summary diagram from JMS specification:

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>?

create servlet url-pattern with "/"

I've created servlet named MainContent. and I have such mapping
<servlet>
<display-name>MainContent</display-name>
<servlet-name>MainContent</servlet-name>
<servlet-class>ge.test.servlet.MainContent</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>MainContent</servlet-name>
<url-pattern>/main</url-pattern>
</servlet-mapping>
so, when I go to the link:
//localhost:8080/MyAppl/main I enter into the servlets doGet() method. Then I create RequestDispatcher forward to the index.jsp.
everything works!
RequestDispatcher rd = context.getRequestDispatcher("/index.jsp?language="+ lang);
rd.forward(request, response);
everything works!
Question:
Now I need to change url-pattern. I need something like that-:when I enter to the localhost:8080/MyAppl/ I need to be redirected to my servlet.
So I create something like that:
<url-pattern>/</url-pattern>
ok, it works! I'm redirected to the servlet. but something wrong happend here. when Servlet created RequestDispatcher forward , there was no images and css in my index.jsp.
when I see in the firebug console, I've seen that errors:
Resource interpreted as Stylesheet but transferred with MIME type text/html: "http://localhost:8080/MyApp/font/font_big.css". localhost/:15
Resource interpreted as Image but transferred with MIME type text/html: "http://localhost:8080/MyApp/IMG/company.gif".
How can I fix that?
Yes, like #DwB pointed, '/' context is problematic URL pattern and it causes your problem.
Use
<servlet-mapping>
<servlet-name>MainServlet</servlet-name>
<url-pattern></url-pattern>
</servlet-mapping>
instead. It is "the servlet 3.0 way" to do this.
Sources
[1] http://www.coderanch.com/t/366340/Servlets/java/servlet-mapping-url-pattern
[2] How can I map a "root" Servlet so that other scripts are still runnable?

Relay servlet (servlet calls another servlet)

Hello i have a question about servlet calling another servlet
I have a main servlet called Relay which is going to be responsible to control the other servlets
the user will click on and will be forwarded to Relay servlet
<li>Check the available animals </li>
inside Relay servlet will get the value of the parameter to determine which servlet is going to run
String selectAnimal = request.getParameter("selectAnimal");
if (selectAnimal.equals("SelectAnimalServlet")){
getServletContext().getNamedDispatcher("/SelectAnimalServlet")
.forward(request, response);
//for testing
System.out.println("Request forwarded to " + selectAnimal + " servlet");
}
SelectAnimalServlet code:
try
{
HttpSession session = request.getSession(true);
session.getAttribute("currentSessionUser");
List<AnimalSelectBean> beans = DAO.getAnimalList();
request.setAttribute("beans", beans);
request.getRequestDispatcher("CheckAnimal.jsp").forward(request, response);
}
Now when i run that it's not working for some reason, if i change the link to SelectAnimalServlet directly the code works any idea how to solve this ?
Edit:
Here is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:javaee="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>content.LoginServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>UpdateAnimalServlet</servlet-name>
<servlet-class>content.UpdateAnimalServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>SelectAnimalServlet</servlet-name>
<servlet-class>content.SelectAnimalServlet</servlet-class>
</servlet>
<servlet>
<servlet-name>Relay</servlet-name>
<servlet-class>content.Relay</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SelectAnimalServlet</servlet-name>
<url-pattern>/SelectAnimalServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>UpdateAnimalServlet</servlet-name>
<url-pattern>/UpdateAnimalServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/LoginServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>Relay</servlet-name>
<url-pattern>/Relay</url-pattern>
</servlet-mapping>
</web-app>
also I changed:
getServletContext().getNamedDispatcher("/SelectAnimalServlet")
.forward(request, response);
to:
response.sendRedirect(response.encodeRedirectURL(selectAnimal));
and still the same thing blank webpage with http://localhost:8080/oosd/Relay?selectAnimal=SelectAnimalServlet link
getNamedDispatcher expects a servlet name; you're providing it with a servlet URL.
Either use the name, or use getRequestDispatcher with the URL.
Since you're forwarding, the URL will not change--there is no redirect response sent back to the browser on a forward. The contents of the forward are written directly to the original response.
Now that you're forwarding, you need to redirect to the URL, not just the name of the servlet.
What does the servlet you redirect to do for output?
I don't believe your parameter naming convention makes any sense. The parameter shouldn't be named the same as a servlet name; the parameter should be something like "command" or "select". You would then use the command parameter value to look up the URL of the servlet. Or, in your case, just prepend a /, and you're done. There's no need to do any if/else comparisons.

Categories

Resources