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

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();
}

Related

#WebFilter seems to ignore included Javascript files

( this is regarding Java EE / Servlets WebFilters)
I am currently trying to write a WebFilter which catches every request made to the web application.
However, I noticed that the WebFilter does not see requests made within <script> tags.
The HTML-Page which is being served contains a stylesheet...
<link rel="stylesheet" href="/webjars/bootstrap/4.1.0/css/bootstrap.min.css">
...and three Javascript-includes...
<script src="/webjars/jquery/3.0.0/jquery.min.js"></script>
<script src="/webjars/popper.js/1.14.1/popper.min.js"></script>
<script src="/webjars/bootstrap/4.1.0/js/bootstrap.min.js"></script>
The #WebFilter, however, only sees requests to the root page (GET /) and to the stylesheet, shown in the logs created by the filter below.
12:04:51,909 INFO Init
12:04:51,909 INFO doFilter
12:04:51,909 INFO ServletRequest: HttpServletRequestImpl [ GET / ]
12:04:51,959 INFO doFilter
12:04:51,959 INFO ServletRequest: HttpServletRequestImpl [ GET /webjars/bootstrap/4.1.0/css/bootstrap.min.css ]
The Implementation of the WebFilter looks like this:
#WebFilter(filterName = "webjarFilter", urlPatterns = "/*")
public class WebJarFilter implements Filter {
private Logger logger = LoggerFactory.getLogger(getClass());
public void init(FilterConfig filterConfig) throws ServletException {
logger.info("Init");
}
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
logger.info("doFilter");
logger.info("ServletRequest: {}", servletRequest);
filterChain.doFilter(servletRequest, servletResponse);
}
public void destroy() {
logger.info("destroy");
}
}
The web.xml file contains following mapping:
<filter-mapping>
<filter-name>webjarFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
My question now is:
Can somebody tell me why the filter does not catch the requests which should be generated from the <script> tags?
Observations and additional Info:
I am testing on Wildfly 12 with the Java EE 7
Directly opening the Javascript-Files will trigger the filter
When Javascript files with a wrong path are referenced, the filter sees the requests. Only inclusions of Javascript-files with the correct path are not seen by the filter
Looks like I figured it out myself.
This is actually a result of Firefox behavior.
When calling the same server from Chrome, the filter sees all requests.
Apparently there is some caching mechanism involved within Firefox which applies to scripts.

New window from servlet method doGet()

Im invoking doGet method "download" servlet in myproject. what i want is,one new window should come out with static content? any idea my googling capacity have no luck
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("static content");
}
You can't do that from the servlet. That needs to be done by whatever sends the client to the servlet. It can be done with a Javascript popup window obviously, where the url is set to the servlet url, but there are two other options also:
Adding target='_blank' to a link:
link
Adding target='_blank' to a form:
<form action="serlvet" method="get" target="_blank">

How HttpServletRequest works

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.

<error-page> tag in web.xml doesn't catch java.lang.Throwable Exceptions

I have a web-app developed with servlet & JSP. I configured my app to throw an IllegalArgumentException if I insert bad parameters.
Then I configured my web.xml file in this way:
<error-page>
<error-code>404</error-code>
<location>/error.jsp</location>
</error-page>
<error-page>
<exception-type>java.lang.Throwable</exception-type>
<location>/error.jsp</location>
</error-page>
When I rise a 404 error, then it works and calls error.jsp, but when I rise a java.lang.IllegalArgumentException, then it does not work and I've a blank page instead of error.jsp. Why?
The server is Glassfish, and logs show really IllegalArgumentException rised.
You should not catch and suppress it, but just let it go.
I.e. do not do:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
doSomethingWhichMayThrowException();
} catch (IllegalArgumentException e) {
e.printStackTrace(); // Or something else which totally suppresses the exception.
}
}
But rather just let it go:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doSomethingWhichMayThrowException();
}
Or, if you actually intented to catch it for logging or so (I'd rather use a filter for that, but ala), then rethrow it:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
doSomethingWhichMayThrowException();
} catch (IllegalArgumentException e) {
e.printStackTrace();
throw e;
}
}
Or, if it's not an runtime exception, then rethrow it wrapped in ServletException, it will be automatically unwrapped by the container:
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
doSomethingWhichMayThrowException();
} catch (NotARuntimeException e) {
throw new ServletException(e);
}
}
See also:
How does server prioritize which type of web.xml error page to use?
Submitting form to Servlet which interacts with database results in blank page
Another (simplified) approach is not to declare multiple handlers for various <error-code> and <exception-type> situations but rather have one, sort of catch-all sink, e.g.
<error-page>
<location>/error-page.jsp</location>
</error-page>
Inside your error-page.jsp you can determine the cause, be it a return status code or an exception as described here: https://www.tutorialspoint.com/servlets/servlets-exception-handling.htm These constants are a part of the standard Servlet 3.0 API.
For instance a primitive error-page.jsp response handler placed into the root of your webapp can look like this:
Server encountered a situation
Status code: <%=(Integer) request.getAttribute(javax.servlet.RequestDispatcher.ERROR_STATUS_CODE)%>
<br>
Exception: <%=(Throwable) request.getAttribute(javax.servlet.RequestDispatcher.ERROR_EXCEPTION)%>
For security reasons I wouldn't recommend sending the exact exception type to the client; this is just an example of how to handle different types of errors and response statuses inside a JSP handler; a servlet can be used instead of JSP.
One common catch-all handler vs one per status code is certainly dependent on the situation and requirements.
I have today the same issue. (JavaEE 7 and Glassfish 4.0)
The problem seems that the framework check it as String instead with the Class.
String based check (the hypothesis)
When a Exception is twrown, e.getClass() is compared with <exception-type> as string.
So you can't use inheritance.
Note that nested classes must be pointed as '$' instead '.' (same as getClass() method).
Class based check
The framework create an instance of the class, and <exception-type> text refer to it, and the class.isInstance() is used to check.
This will need reflection and policy file could break it.
I hope that this response solves future issues.

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