How HttpServletRequest works - servlets

i'm trying to understand how HttpServletRequest works:
in a demo application I have this code in a .class file:
HttpServletRequest req = (HttpServletRequest)
FacesContext.getCurrentInstance().getExternalContext().getRequest();
String parameter = req.getHeader("PARAMETER");
is this a JSF implementation? Does it read a parameter from the session right?
How can I retrieve the same parameter without using JSF?

Yes, this snippet is part of a JSF application.
No it doesn't read a parameter from the session, since it calls getHeader() on a HttpServletRequest object. So it reads a request header (as the javadoc of HttpServletRequest.getHeader() explains).
To retrieve the same header in a simple servlet-based application, you would use the HttpServletRequest argument passed to every servlet method:
#Override
public void doGet(HttpServletRequest request, HttpServletResponse response) {
String header = request.getHeader("PARAMETER");
...
}
It looks like you're not familiar at all with servlets. Read an introductory tutorial to grasp the basics before dving into code.

Related

How to render data from a html file using servlets? [duplicate]

How do I generate an HTML response in a Java servlet?
You normally forward the request to a JSP for display. JSP is a view technology which provides a template to write plain vanilla HTML/CSS/JS in and provides ability to interact with backend Java code/variables with help of taglibs and EL. You can control the page flow with taglibs like JSTL. You can set any backend data as an attribute in any of the request, session or application scope and use EL (the ${} things) in JSP to access/display them. You can put JSP files in /WEB-INF folder to prevent users from directly accessing them without invoking the preprocessing servlet.
Kickoff example:
#WebServlet("/hello")
public class HelloWorldServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String message = "Hello World";
request.setAttribute("message", message); // This will be available as ${message}
request.getRequestDispatcher("/WEB-INF/hello.jsp").forward(request, response);
}
}
And /WEB-INF/hello.jsp look like:
<!DOCTYPE html>
<html lang="en">
<head>
<title>SO question 2370960</title>
</head>
<body>
<p>Message: ${message}</p>
</body>
</html>
When opening http://localhost:8080/contextpath/hello this will show
Message: Hello World
in the browser.
This keeps the Java code free from HTML clutter and greatly improves maintainability. To learn and practice more with servlets, continue with below links.
Our Servlets wiki page
How do servlets work? Instantiation, sessions, shared variables and multithreading
doGet and doPost in Servlets
Calling a servlet from JSP file on page load
How to transfer data from JSP to servlet when submitting HTML form
Show JDBC ResultSet in HTML in JSP page using MVC and DAO pattern
How to use Servlets and Ajax?
Servlet returns "HTTP Status 404 The requested resource (/servlet) is not available"
Also browse the "Frequent" tab of all questions tagged [servlets] to find frequently asked questions.
You need to have a doGet method as:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException
{
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>Hola</title>");
out.println("</head>");
out.println("<body bgcolor=\"white\">");
out.println("</body>");
out.println("</html>");
}
You can see this link for a simple hello world servlet
Apart of directly writing HTML on the PrintWriter obtained from the response (which is the standard way of outputting HTML from a Servlet), you can also include an HTML fragment contained in an external file by using a RequestDispatcher:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("HTML from an external file:");
request.getRequestDispatcher("/pathToFile/fragment.html")
.include(request, response);
out.close();
}

Sending response after chain.doFilter in filters

I am new to Servlets. In the book i am reading now it is written, that we need wrappers, because it is late to do anything with response after finishing chain.doFilter() method as response is sent already.
I wrote the following Servlet and Filter:
public class MyServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
PrintWriter writer = response.getWriter();
writer.println("In Servlet");
}
}
public class MyFilter implements Filter{
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException{
PrintWriter writer = response.getWriter();
chain.doFilter(request, response);
writer.println("After chain");
}
}
And i see both strings in the browser.
My question is: Why do we need wrappers? I still can write to response even after chain.doFilter and i still see result?
Is it because response is sent in two pieces(first in the end of chain.doFilter and second in the end of Filter.doFilter)? So if i had to compress response it would work incorrectly(because first uncompressed part would be sent)?
The book is talking about response headers.
You misunderstood it as response body.
Here are some real world use cases of response wrappers so you can see why we may need them:
How to add response headers based on Content-type; getting Content-type before the response is committed
How do delete a HTTP response header?
How to read and copy the HTTP servlet response output stream content for logging
How to insert JSF page rendering time and response size into the page itself, at least partially?
How to configure Tomcat to not encode the session id into the URL when HttpServletResponse.encodeURL() is invoked
For more examples, see this search.

Setting the response content-type without using HttpServletResponse

How can I get HttpServletResponse object in a method in my spring controller so that my application remains loosely coupled with Http API?
Thanks...
Edit: Actually what i want is to set the ContentType of the HttpServletResponse object in my controller.Does spring provides any way for this without getting HttpServletResponse object as argument in the method of controller?
I can see two options:
If the content-type that you want is static, then you can add it to #RequestMapping, e.g.
#RequestMapping(value="...", produces="text/plain")
This will only work if the HTTP request contains the same content-type in its Accept header, though. See 16.3.2.5 Producible Media Types.
Alternatively, use ResponseEntity, e.g.
#RequestMapping("/something")
public ResponseEntity<String> handle() {
HttpHeaders responseHeaders = new HttpHeaders();
responseHeaders.setContentType(new MediaType("text", "plain"));
return new ResponseEntity<String>("Hello World", responseHeaders, HttpStatus.CREATED);
}
MediaType also has a handful of common mime types defined as constants, e.g. MediaType.TEXT_PLAIN.
See 16.3.3.6 Using HttpEntity<?>
Just pass it as an argument, e.g.
#RequestMapping( value="/test", method = RequestMethod.GET )
public void test( HttpServletResponse response ) { ... }
I think the best way to handle this is to use a specific View-Implementation, since here to response-rendering should take place.

Servlet doFilter setAttributes not available in Servlet

I'm trying to add an Attribute to the request via doFilter before passing it to the Servlet, so that a value in JSTL will be set. I simply do req.setAttribute("b", "blah") in the filter, but it doesn't seem to get set in the JSTL file. How would I do this?
It's hard to pinpoint the root cause without seeing the code. There are several possible causes.
You're sending a redirect after setting the attribute instead of continuing with the same request.
You're accessing the attribute with the wrong name (case sensitive!).
You're accessing the attribute the wrong way.
The attribute is been overridden somewhere further down in the request processing.
There's a page scoped attribute with the same name which has no value.
You're misinterpreting the results.
Etc.
By the way, there's no such thing as a "JSTL file". Perhaps you meant "JSP file".
The problem is that the doFilter method uses ServletRequest instead of HttpServletRequest which is the one that has the setAttribute method. Most of my filters are something like this:
public void doFilter(ServletRequest servletRequest,
ServletResponse servletResponse,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
// do what you must...
chain.doFilter(servletRequest, servletResponse);
}

How do I execute multiple servlets in sequence?

I am just beginning with Servlets and managed to have some servlets that act as individual URLs for populating a database for some dummy testing. Something of the form:
public class Populate_ServletName extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
//Insert records
//Print confirmation
}
}
I have about 6 such servlets which I want to execute in a sequence. I was thinking of using setLocation to set the next page to be redirected but was not sure if this is the right approach because the redirects should happen after the records have been inserted. Specifically, I am looking for something like this:
public class Populate_ALL extends HttpServlet {
public void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
resp.setContentType("text/plain");
//Call Populate_1
//Call Populate_2
//Call Populate_3
//...
}
}
Any suggestions?
Use RequestDispatcher#include() on an URL matching the url-pattern of the Servlet.
public class Populate_ALL extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/plain");
request.getRequestDispatcher("/populateServlet1").include(request, response);
request.getRequestDispatcher("/populateServlet2").include(request, response);
request.getRequestDispatcher("/populateServlet3").include(request, response);
//...
}
}
Note: if those servlets cannot be used independently, then this is the wrong approach and you should be using standalone Java classes for this which does not extend HttpServlet. In your specific case, I think the Builder Pattern may be of interest.
The RequestDispatcher#forward() is not suitable here since it throws IllegalStateException when the response headers are already committed. This will be undoubtely the case when you pass the request/response through multiple servlets which each writes to the response.
The HttpServletResponse#sendRedirect() is absolutely not suitable here since it implicitly creates a brand new request and response, hereby trashing the original ones.
See also:
How do I call a second JSP servlet while in the first JSP servlet?
RequestDispatcher.forward() vs HttpServletResponse.sendRedirect()
communication between remote servlets
It looks like what you may need is a service that each of the servlets can use to perform some work. Then the servlets are not depending one and another, but rather all using the service.
However, here is an explanation of forwarding or redirecting requests.

Resources