I am working on a simple java serverlet. It seems as if the server is not getting the parameters. This is my doPost() code.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String a = request.getParameter("a");
String b = request.getParameter("b");
System.out.println("I started doing something " + a + " " + b);
}
This is my web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>AutoPresServerlet</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>
<description></description>
<display-name>Main</display-name>
<servlet-name>Main</servlet-name>
<servlet-class>com.altechwebdesign.java.autopres.Main</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Main</servlet-name>
<url-pattern>/Main</url-pattern>
</servlet-mapping>
</web-app>
I am using the Advanced Rest Client for Chrome to send the POST Requests.
Nothing in the evidence you have shown use explains why the parameters are null.
It seems as if the server is not getting the parameters.
I assume that means that you have evidence that your doPost method is actually being called. That points to the fact that the web.xml is correctly directing the request to your servlet code.
That implies that the reason the parameters are not showing up is that they have not been provided (correctly). But that is happening in the client code and/or the request that it is sending, and you haven't shown that to us.
(It is also possible that you don't have any evidence and your "if seems ..." is just a guess. If that is the case, you need to FIND OUT what is going on, and/or show us the evidence that you actually have.)
I also don't see why you have mentioned JSPs here. You haven't shown us any JSP code, and it is unlikely that it will be directly relevant to your problem.
you need a form or jsp page to carry html input type values and trigger a servlet.
then only your servlet can get the value
i would suggest to write form code in index.jsp and call action /Main from the form.
flow should be like
index.jsp->submitform->main servlet
Servlet can get parameter in your code if and only if your action is triggered with the following data(no matter Get or Post)
a=test_for_a&b=test_for_b
you can add some input/select/textarea with name(which would be the parameter name you use in servlet,namely a and b).
Well, ajax would be another solution, which is out of our scope, I bet.
you can test if the request & response working correctly by :
PrintWriter writer=response.getWriter();
writer.write("This is my post"); ,
you must have a html form for submitting a & b values. check there action and methods are correct,or restart the server and try again..
Related
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.
I have a Java EE site with JSPs, set up with an MVC architecture. I have servlets pointing to a model object, and I've chosen one servlet, the NewspaperServlet, to be the sole entry point for HTTP requests. From there, I call my other servlets as necessary. I want to have RESTful URLs, so http://myurl/ serves up /index.jsp, http://myurl/article/1 serves /article.jsp and the Article object with id 1, and so on.
I'm processing the path just fine, but when it comes time to actually serve my JSP pages, I'm redirecting myself right back into my code, because I try and retrieve, say, /index.jsp and because my code is the sole entry point, it then calls my code looking for how to serve /index.jsp! Should I be resorting to opening my files and outputting the contents, or is there a more sane way of doing this?
web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>wsd-newspaper</display-name>
<welcome-file-list>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>JSP Web Service</servlet-name>
<servlet-class>
merus.newspaper.NewspaperServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>JSP Web Service</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
NewspaperServlet.doGet():
public void doGet( HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String pathInfo = request.getPathInfo();
request.setCharacterEncoding("UTF-8");
response.setHeader("Content-Type", "text/html");
//index
if (pathInfo.equalsIgnoreCase("/")) {
request.setAttribute("articleList", controller.getIndex());
RequestDispatcher dp = request.getRequestDispatcher("/index.jsp");
dp.forward(request, response);
}
//article servlet redirect
if (pathInfo.startsWith("/article") ||
pathInfo.startsWith("/archive")) {
articleServlet.doGet(request, response);
return;
}
//author servlet redirect
if (pathInfo.startsWith("/author")) {
authorServlet.doGet(request, response);
return;
}
if (pathInfo.startsWith("/logout")) {
request.getSession().removeAttribute("user");
}
RequestDispatcher dp = request.getRequestDispatcher("/404.html");
dp.include(request, response);
}
Notes: because of the peculiarities of the model I'm required to work with, I want to be very careful I don't load it twice. The NewspaperServlet creates and initialises the other servlets so it can also be the only class that loads the model.
The controller is separate from the servlet. The controller is intended to be used to provide a web service, which will necessitate another endpoint in web.xml. I'm not attached to having one endpoint as much as I want RESTful URLs.
Change your url pattern to
<url-pattern>/</url-pattern>
This is the fallback pattern. If the container cannot find any other match with other mapped servlets, it will fall back to this one.
Most (if not all) servlet contains register a Servlet which handles JSP with the pattern
<url-pattern>*.jsp</url-pattern>
This will match before your /.
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>?
I am attempting to send two attributes to a JSP via a Java HttpServlet. The problem is they are both appearing as 0 (the number) in my JSP file.
Here is the doGet method in my RegisterDeveloper.java file:
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// Fill up default attributes for the template
req.setAttribute("validation-error", false);
req.setAttribute("validation-error-message", "");
// Redirect to register page
req.getRequestDispatcher("/register.jsp").forward(req, resp);
}
Very simple and when I step through the attributes are added to the request and the browser is redirected to the /register.jsp page.
Here is the problem part of the register.jsp page:
<c:if test="${validation-error}">
<div id="validationError">
<span id="errorText">
${validation-error-message}
</span>
</div>
</c:if>
For some reason the attributes I added to the request have all become '0'.
The error displayed in the browser is:
HTTP Status 500 - javax.el.ELException: Cannot convert 0 of type class java.lang.Long to class java.lang.Boolean
My web.xml incase it's relevant:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>RServer</display-name>
<welcome-file-list>
<welcome-file>homepage.html</welcome-file>
</welcome-file-list>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>RegisterDeveloper</servlet-name>
<servlet-class>com.steven.RegisterDeveloper</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RegisterDeveloper</servlet-name>
<url-pattern>/register</url-pattern>
</servlet-mapping>
</web-app>
I'm using Tomcat6. This all seems very straight forward, and I have very similar code working on other pages, so I'm really struggling to see what I've missed!
Any help, very much appreciated.
I have javax.servlet.jsp.jstl-1.2.1.jar and javax.servlet.jsp.jstl-api-1.2.1.jar in my /WEB-INF/lib/ folder..
From a specification I googled
An identifier is constrained to be a Java identifier - e.g., no -, no /, etc.
validation-error is not a Java identifier, but a subtraction operation for validation
and error. Since you have not defined those, they are null and this applies:
1.7.1 Binary operators - A {+,-,*} B ■ If A and B are null, return (Long)0
So I guess the test becomes if( (Long)0 == true ).
Try with req.setAttribute("validationError", false); ${validationError}
I've read several docs and I don't get it: I know I'm doing something wrong but I don't understand what. I've got a website that is entirely dynamically generated: there's hardly any static content at all.
So, trying to understand JSP/Servlet, I've written my own "front controller" intercepting every single query, it looks like this:
<servlet-mapping>
<servlet-name>defaultservlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
Basically I want any user request, like:
example.org
example.org/bar
example.org/foo.html
to all go through a default servlet which I've written.
The servlet then examines the URI and find to which .jsp the request must be dispatched, and then does, after having set all the attributes correctly, a:
RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/WEB-INF/jsp/index.jsp");
dispatcher.forward(req, resp);
When I'm using a url-pattern (in web.xml) like, say, *.html, everything works fine. But when I change it to /* (to really intercept everything), I enter an endless loop and it ends up with a... StackOverflow :)
When the request is dispatched, is the URI ".../WEB-INF/jsp/index.jsp" itself matched by the web.xml filter /* that I set?
EDIT apparently, no, because this is an exact mapping to index.jsp and hence it bypasses the web.xml url-pattern. So I still don't get how I can enter that endless loop.
How should I do if I want to intercept everything using a /* url-pattern and yet be able to dispatch/forward/?
I'm not asking about specs/Javadocs here: I'm really confused about the bigger picture and I'd need some explanation as to what could be going on.
Am I not supposed to intercept really everything?
If I can intercept everything, what should I be aware of regarding forwarding/dispatching?
Unfortunately, Serlvet spec doesn't allow to create a servlet mapping to match only incoming request, not forwards. However, this can be done for filter mappings (and by default filter mappings match only incoming requests).
So, the typical solution for intercepting everything with a single servlet is to use a UrlRewriteFilter:
<filter>
<filter-name>urlRewrite</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>urlRewrite</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>application</servlet-name>
<servlet-class>...</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>application</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
/WEB-INF/urlrewrite.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE urlrewrite
PUBLIC "-//tuckey.org//DTD UrlRewrite 3.0//EN"
"http://tuckey.org/res/dtds/urlrewrite3.0.dtd">
<urlrewrite default-match-type="wildcard">
<rule>
<from>/**</from>
<to>/app/$1</to>
</rule>
<outbound-rule>
<from>/app/**</from>
<to>/$1</to>
</outbound-rule>
</urlrewrite>
This way also allows you to specify exceptions from /* mapping for static files.
Try using struts in which front controller pattern is inbuilt. There you will have a action class and you can define forwards in struts-config file using which you can easily manage the forwards.
Go through the tutorial http://www.roseindia.net/struts/struts2/index.shtml. Hope this helps you.