Return ModelAndView from Spring when handling exceptions - java

Dealing with exceptionhandling in spring project.
I had followed this approach to handle the exceptions.
Everything is going good, but I want to return a ModelAndView instead of writing a text/html using PrintWriter object.
Following is the approach I followed.
ExceptionHandler.java
package com.test.controller;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
/**
* Servlet implementation class ExceptionHandler
*/
#WebServlet("/ExceptionHandler")
public class ExceptionHandler extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//response.getWriter().append("Served at: ").append(request.getContextPath());
//processError(request,response);
handleException(request,response);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
//processError(request,response);
handleException(request,response);
}
//I want this ModelAndView to be returned and should display the page that was set in ModelANdView object.
private ModelAndView handleException(HttpServletRequest request,HttpServletResponse response) throws IOException {
ModelAndView model = new ModelAndView("ErrorPage");
model.addObject("errMsg", "this is Exception.class");
return model;
}
//I don't want this approach.
/*private void processError(HttpServletRequest request,
HttpServletResponse response) throws IOException {
// Analyze the servlet exception
Throwable throwable = (Throwable) request
.getAttribute("javax.servlet.error.exception");
Integer statusCode = (Integer) request
.getAttribute("javax.servlet.error.status_code");
String servletName = (String) request
.getAttribute("javax.servlet.error.servlet_name");
if (servletName == null) {
servletName = "Unknown";
}
String requestUri = (String) request
.getAttribute("javax.servlet.error.request_uri");
if (requestUri == null) {
requestUri = "Unknown";
}
// Set response content type
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.write("<html><head><title>Exception/Error Details</title></head> <body>");
if(statusCode != 500){
out.write("<h3>Error Details</h3>");
out.write("<strong>Status Code</strong>:"+statusCode+"<br>");
out.write("<strong>Requested URI</strong>:"+requestUri);
}else{
out.write("<h3>Exception Details</h3>");
out.write("<ul><li>Servlet Name:"+servletName+"</li>");
out.write("<li>Exception Name:"+throwable.getClass().getName()+"</li>");
out.write("<li>Requested URI:"+requestUri+"</li>");
out.write("<li>Exception Message:"+throwable.getMessage()+"</li>");
out.write("</ul>");
}
out.write("<br><br>");
out.write("Home Page");
out.write("</body></html>");
}*/
}
And in web.xml I had added following tag to set location for error.
<error-page>
<error-code>404</error-code>
<location>/ExceptionHandler</location>
</error-page>
EDIT: I know that void cannot return ModelAndView Object , but looking for an approach to load the ErrorPage in case of invalid URL

Related

How redirect request from jsp to a servlet

Thank you for your help in advance. I am trying to get the answer from a jsp using a radio button object and after sending to a servlet which will manage the request and send to specific servlet to impact the database. I have problems in the servlet that manages the request. I am not able to resend the petition to the final servlet. The parts of the source code are the next:
PolicyManager.jsp:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h1>Change the current policy</h1>
<form action="ManageRequest" method="Post">
Which action would you like to apply?<br><br>
<input type="radio" name="policy" value="add">Add<br>
<input type="radio" name="policy" value="delete">Delete
<br><br>
<input type="submit" value="submit"/>
</form>
</body>
</html>
ManageRequest.java:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class ManageRequest
*/
#WebServlet("/ManageRequest")
public class ManageRequest extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public ManageRequest() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter printWriter = response.getWriter();
printWriter.print("doGet method");
String policy=request.getParameter("policy");
if (policy.equals("add") ) {
printWriter.println("<html><body>Redirecting to Add servlet section..."+"<br>");
RequestDispatcher dispatcher = request.getRequestDispatcher("/AddPolicy");
dispatcher.forward(request, response);
} else if (policy.equals("delete")) {
printWriter.println("<html><body>Redirectin to Delete servlet section..."+"<br>");
RequestDispatcher dispatcher = request.getRequestDispatcher("/DeletePolicy");
dispatcher.forward(request, response);
}
else{
printWriter.println("<html><body>A different option..."+"<br>");
}
printWriter.println("</body></html>");
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter printWriter = response.getWriter();
String policy=request.getParameter("policy");
printWriter.print("doPost method");
if (policy.equals("add") ) {
printWriter.println("<html><body>Redirecting to Add servlet section..."+"<br>");
RequestDispatcher dispatcher = request.getRequestDispatcher("/AddPolicy");
dispatcher.forward(request, response);
} else if (policy.equals("delete")) {
printWriter.println("<html><body>Redirectin to Delete servlet section..."+"<br>");
RequestDispatcher dispatcher = request.getRequestDispatcher("/DeletePolicy");
dispatcher.forward(request, response);
}
else{
printWriter.println("<html><body>A different option..."+"<br>");
}
printWriter.println("</body></html>");
}
}
AddPolicy.java:
package PolicyManager;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class AddPolicy
*/
#WebServlet("/AddPolicy")
public class AddPolicy extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public AddPolicy() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter printWriter = response.getWriter();
printWriter.println("<h1>Add Policy</h1>");
printWriter.println("Add Policy");
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
DeletePolicy.java:
package PolicyManager;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class DeletePolicy
*/
#WebServlet("/DeletePolicy")
public class DeletePolicy extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public DeletePolicy() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
PrintWriter printWriter = response.getWriter();
printWriter.println("<h1>Delete Policy</h1>");
printWriter.println("Delete Policy");
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
The web.xml:
<servlet>
<servlet-name>ManageRequest</servlet-name>
<servlet-class>PolicyManager</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ManageRequest</servlet-name>
<url-pattern>/PolicyManager</url-pattern>
</servlet-mapping>
The problem is that only I can get the manager servlet that has to redirect the petition to the final servlet.
Thank you for your help.
Cheers
You should try to understand the difference between RequestDispatcher.include() and RequestDispatcher.forward().
RequestDispatcher.forward() means the complete control for request processing is forwarded to another servlet. The forwarding servlet should not do anything like writing response or committing response. If the response got committed in the calling servlet before the forward, then an IllegalStateException is thrown. IF the response is not yet committed, then the response will be cleared.
Whatever, it is not valid to write something to response when you are forwarding to another servlet.
If you have a requirement to do write something to response from various servlets, you should use RequestDispatcher.include().
In your case, you are writing below thing before forward() which may be the issue.
printWriter.println("<html><body>Redirecting to Add servlet section..."+"<br>
You have to add:
response.sendRedirect("http://localhost:8080/clientLibrary/DeletePolicy");
Instead of :
RequestDispatcher dispatcher = request.getRequestDispatcher("/DeletePolicy");
dispatcher.forward(request, response);
The same for AddPolicy.
Cheers

Java ee annotations wont work

I'm trying to write annotations for the first time in my servlet. The #WebServlet is working fine. It is when I add #webInitParam that I get the red line. Also,
when I try to use the #POST annotation it gives me "POST cannot be resolved to a type".
Here's my code:
package servlets;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Servlet implementation class Calc
*/
#WebServlet (loadOnStartup = 1 , urlPatterns = { "/CoolPage" } ,
initParams = {
#WebInitParam(name="text" , value="hello" , description="simple text"),
#WebInitParam(name="times", value="10" , description="times to print")
}
)
public class Calc extends HttpServlet {
private static final long serialVersionUID = 1L;
public Calc() {
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
#POST
protected void doThePost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("Inside the POST method");
String username = request.getParameter("userName");
String password = request.getParameter("password");
request.setAttribute("userName", username);
request.setAttribute("password", password);
RequestDispatcher rd = request.getRequestDispatcher("jspGetting.jsp");
rd.forward(request, response);
}
}
Imports do not include sub-packages. Import the class from the javax.servlet.annotation package
import javax.servlet.annotation.WebInitParam;
It's hard to see how the servlet could compile without WebServlet being imported either(?).
import javax.servlet.annotation.WebServlet;
The POST annotation is located within the JAX-RS library
import javax.ws.rs.POST;

Best Way to output SoyTemplates from a Servlet

What is the best waya to render or output Soy Templates from closure-templates to a browser?
Currently i have the following:
package de.envisia.erp.web.servlet;
import java.io.File;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.google.template.soy.SoyFileSet;
import com.google.template.soy.tofu.SoyTofu;
/**
* Servlet implementation class EntryPoint
*/
#WebServlet("/EntryPoint")
public class EntryPoint extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public EntryPoint() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String pathContext = servletContext.getRealPath("/WEB-INF/");
//response.getWriter().println(pathContext);
SoyFileSet sfs = new SoyFileSet.Builder().add(new File(pathContext + "\\templates\\hello.soy")).build();
SoyTofu tofu = sfs.compileToTofu();
String out = tofu.newRenderer("hello.world").render();
response.getWriter().println(out);
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
}
But i don't think it is a good practice to use the println or even print() method of the response object, are there any better ways?
Take a look at https://github.com/codedance/silken.
The basic idea is to make a special servlet and forward requests to it:
RequestDispatcher rd = getServletContext().getRequestDispatcher("/soy/products.boat.sailingBoatView");
rd.forward(req, resp);

Using <a href> to link to servlet

I have a anchor which i want it to be linked to a LogoutServlet so that it will destroy the sessions and redirect it back to a login page.
LogoutServlet.java
package pkg;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet implementation class LogoutServlet
*/
public class LogoutServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
/**
* #see HttpServlet#HttpServlet()
*/
public LogoutServlet() {
super();
// TODO Auto-generated constructor stub
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
}
/**
* #see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response)
*/
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO Auto-generated method stub
response.setHeader("Cache-Control", "no-cache, no-store");
response.setHeader("Pragma", "no-cache");
request.getSession().invalidate();
RequestDispatcher rd = request.getRequestDispatcher("Login.html");
rd.forward(request, response);
}
}
tag
Logout
Is this the right way to implement it?? I used this but it did not redirect me to Login.html .
That will hit the doGet method not the doPost method. An anchor link like that is a HTTP GET request.
If you wish to make a POST request, you will need to submit a form to the servlet using method POST.
Move your code to doGetinstead of doPost and try that.
Use doGet method. a href will use GET method.

HTTP Status 405 - HTTP method POST is not supported by this URL

I am getting the error HTTP Status 405 - HTTP method POST is not supported by this URL when I use the following code(below) ... the line causing the trouble (apparently) is getServletContext().getRequestDispatcher("/EditObject?id="+objId).forward(request, response);
package web.objects;
import java.io.IOException;
import java.sql.SQLException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import dao.ObjDetailsDao;
#SuppressWarnings("serial")
public class EditObjectText extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
int objId = Integer.parseInt(request.getParameter("objId"));
String text = (String)request.getParameter("description");
ObjDetailsDao oddao = new ObjDetailsDao();
try {
oddao.modifyText(text, objId);
/////////////
getServletContext().getRequestDispatcher("/EditObject?id="+objId).forward(request, response);
////////////
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ServletException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
EDIT: I added the throws ServletException, IOException as suggested, but this did not change the error.
EDIT: the EditObject servlet looks like this
#SuppressWarnings("serial")
public class EditObject extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
int objId = Integer.parseInt(request.getParameter("id"));
dispPage(objId, request, response);
}
private void dispPage(int objId, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
// ... lots of code in here
getServletContext().getRequestDispatcher("/jsp/objectPageEdit.jsp").forward(request, response);
}
}
ANOTHER EDIT: So basically I can't do what I am doing. What I need is this, the user submits a post request and then I refer him/her back to a servlet which uses the Get method instead of Post. How can I do this referral without getting the error? Thanks in advance.
(sorry about the wrong answer I posted before, I deleted it).
Apparently the URL /EditObject is mapped on another servlet which doesn't have doPost() method overriden. It would be called on RequestDispatcher#forward() as well because the method of currently running HTTP request is POST. The default HttpServlet#doPost() implementation will return HTTP 405. If your actual intent is to fire a GET request on it so that the doGet() method will be invoked, then you should rather use HttpServletResponse#sendRedirect() instead.
response.sendRedirect("/EditObject?id="+objId);
Add a doPost() to your EditObject class:
#SuppressWarnings("serial")
public class EditObject extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
process(request, response);
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
process(request, response);
}
public void process(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
int objId = Integer.parseInt(request.getParameter("id"));
dispPage(objId, request, response);
}
private void dispPage(int objId, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
// ... lots of code in here
getServletContext().getRequestDispatcher("/jsp/objectPageEdit.jsp").forward(request, response);
}
}

Categories

Resources