0

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

Stefan
  • 969
  • 6
  • 9

1 Answers1

2

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:

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.

Bogdan
  • 23,890
  • 3
  • 69
  • 61
  • Sorry mate, but I don't quite get it. Can I ask you to re-edit the answer and further explain this part : `And the reason is that you are not accessing the servlet you defined in web.xml, you are just accessing the JSP directly, which is another servlet behind the scene, and not the one you think you are configuring.` What **another** servlet are you talking about? JSP turns into Servlet, so it is **one** Servlet total at runtime. That detail is core of my confusion. And thanks one more time! – Stefan Jan 10 '21 at 22:31
  • 1
    I've updated my answer. Read it again and see if it's clear now. I admit my initial choice of words wasn't the best. – Bogdan Jan 11 '21 at 15:44
  • Great, I am starting to get it slowly.. Just one thing left to ask that I couldn't find. Why do I even have to map servlets? I know it would be stupid for user to go to `http://localhost:8080//com.example.MyServlet` to access a servlet (they don't care where it is). But why I can't technically do it? Why do I have to make "fake" URL that would run some jsp files or servlet classes? I mean why I can't directly navigate to some files in my application as well, but I need help from mappings every time? – Stefan Jan 13 '21 at 09:56
  • 1
    Because your browser understands URLs, HTML, HTTP, etc. Your browser doesn't know what a servlet is and doesn't care. In other languages and platforms you don't have servlets, you have something else. Should the browser know about every web implementation out there? That's how the web works, and if you want to build a web application, you have to play by the rules of the Internet. How you implement that is your own problem. Here is an analogy: when you go at a restaurant, why do you have to sit at a table and order your food? Why don't you just burge into the kitchen and start eating there? – Bogdan Jan 13 '21 at 15:48
  • Well, you are right that browser doesn't know what servlet is, nor any other web implementation. But Containers do! So should it work like this: "I make request to *com.example.MyServlet*. Server "sees" that request is dynamic and let Container do the work. Container does some logic, gives response to server that sends HTTP response to browser." That's what I thought how it works, but unfortunately it will give `not found error`". **Can't server/container know what it is, if I tell it where it is?** In your analogy: make me a burger, you can find it in top shelf at kitchen's corner. – Stefan Jan 13 '21 at 19:12
  • 1
    Well yeah, that will work as you say, **if** servlet containers would have been implemented to work like that. But they weren't. But nothing stops you from implement this behavior on your own if you really want to. But you still need to use the servlet container "as it currently works" to implement it. I do suggest however that you spend your time on more constructive things :) – Bogdan Jan 13 '21 at 19:53