Java NullPointerException on HttpServletResponse line - java

Ok I am running the JSf application and I get an error of NullPointerException on line 220 which is
response.setContentType("text/html");
not sure why would this be the issue. The full method in which the line is present is below:
public void reserveDates(String eventTitle, Date startDate,
Date endDate, String requestType, int terminals,
String lastName, String firstName, String middleInitials,
int badgeNo, String networkID, String telephoneNo,
String orgCode, String justification)
throws ServletException, IOException{
MapCreation mapCreate = new MapCreation(startDate, endDate);
newMap = mapCreate.getDatesTreeMap();
MapStorage mapStore = new MapStorage();
mapStore.storeMap(newMap);
//create instance of reservation class
rsvObj = new Reservation(eventTitle, startDate,
endDate, requestType, terminals, lastName, firstName,
middleInitials, badgeNo, networkID, telephoneNo,
orgCode, justification);
boolean possible = rsvObj.checkRange();
if(possible == true)
{
try{
HttpServletResponse response = null;
response.setContentType("text/html");
response.sendRedirect("main");
CreateTempStorage();
}catch(IOException ioe){
System.err.print(ioe);
}
}else if(possible == false){
try{
HttpServletResponse response = null;
response.setContentType("text/html");
response.sendRedirect("error");
}catch(IOException ioe){
System.err.print(ioe);
}
}
}
P.s.: The response giving the error is in the first condition where i check if(possible==true)
I am just trying to use response to redirect to the pages mentioned either "main" or "error"
I appreciate the support.
Thanks!

you initialize response to null on the line immediately before the exception is thrown

response is null at that point. You set it to that right on the line before.
You need a concrete class that implements the abstract HttpServletResponse. If you have a class called MyHttpServletResponse that implements HttpServletResponse, then your code might look like this:
MyHttpServletResponse response = new MyHttpServletResponse();
(Perhaps you mean to use HttpServletResponseWrapper or something like that?)

Where is response assigned a value?
Also, your code has "poor" style. Consider replacing this
if (possible == true) {
...
else if (possible == false) { // there is no other possibility
...
}
with
if (possible) {
...
else {
...
}

HttpServletResponse response = null;
response.setContentType("text/html");
response.sendRedirect("main");
You cannot call a method on an object after you set it to null. You shouldn't set the response to null. There should be a response object around somewhere. Pass it to your method.

Well, the best option for an answer I believe was found in FacesContext. The code that replaced the redirection in this case was:
FacesContext facesContext = FacesContext.getCurrentInstance();
ExternalContext ec = facesContext.getExternalContext();
ec.redirect("progress.xhtml");
Hope this helps others. Regards,

The thing is if you are writing this code inside the servlet then you will already have the response object otherwise if you writing this code in any method then pass the response object from servlet while calling the method. Actually we need not create an object of HttpServletResponse.
try{
response.setContentType("text/html");
if(possible){
response.sendRedirect("main");
CreateTempStorage();
}else{
response.sendRedirect("error");
}
}catch(IOException ioe){
System.err.print(ioe);
}
A small improvement in code quality.

Related

Change response based on query string in java servlet

Im having some trouble sending diffrenet response based on query string, I have 2 String that suppose to match a single param from the query names serviceType:
private static String restartQuery = "restarts";
private static String dbStatusQuery = "dbStatus";
And my doGet function needs to send response accordingly:
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException{
String requestType = request.getParameter(serviceType);
// Set response content type
response.setContentType("text/html");
if(requestType.equals(restartQuery)){
//handle response for restartQuery
PrintWriter out = response.getWriter();
out.println("response for restart ....");
}else if (requestType.equals(dbStatusQuery)){
//handle response for dbStatusQuery
PrintWriter out = response.getWriter();
out.println("response for db ....");
}
}
The problem is that I get the same response(restart...), I had check the query string from the front-end - system.println(requestType) and they are different for each request, what can I change to make it work? if there is more code needed please comment below.
I have added 2 things based on comments here:
1- added consts to my defitions:
private static final String restartQuery = "restarts";
private static final String dbStatusQuery = "dbStatus";
2- check spaces from the front-end, just use a simple prefix check.
Thanks to all the helpers.

I can not make a request and the Response to a servlet

I have a servlet. in it I form a line and when I type in the browser link, he told me that rotates the line. everything is fine. Now I want to create an array of strings, and depending on the parameter in the link rotates the particular row. how to do it?
#WebServlet("/goods")
public class GoodsServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.print("{\"name\":\"Pavel\",\"sname\":\"Petrashov\",\"age\":24,\"params\":{\"heigth\":188, \"weight\":72, \"strong\":100}}");
}
}
and I want to have
List<String> list = new ArrayList<String>();
list.add("{\"name\":\"Pavel\",\"sname\":\"Petrashov\",\"age\":24,\"params\":{\"heigth\":188, \"weight\":72, \"strong\":100}}");
list.add("{\"name\":\"Bill\",\"sname\":\"Gey\",\"age\":99,\"params\":{\"heigth\":188, \"weight\":70, \"strong\":100}}");
list.add("{\"name\":\"Uill\",\"sname\":\"Smitt\",\"age\":12,\"params\":{\"heigth\":188, \"weight\":99, \"strong\":100}}");
and to make sure that my reference http://localhost:666/sg/goodstook some parameter, depending on which will return an array element
Do you mean depending on GET parameters you want to print out one of the strings in the list? If that is what you want then
String myParameter = request.getParameter("param");
will give you the get parameter. Pass the parameter as a query string on the url like http://localhost:666/sg/goods?param=2.
Now use the parameter to get the string from your list
try{
int index = Integer.parseInt(myParameter);
out.println(list.get(index));
} catch(IndexOutOfBoundsException|NumberFormatException ex){
System.err.println("Invalid get parameter");
}

How to add a cookie using doTag method in custom tag?

I have developed a custom tag library in Java which I use in my web application.
I am not sure why but my doTag() is not setting up cookie at all. I have cleared my cache and restarted my computer as well. Here is the code:
public class UserVersionOfSite extends EvenSimplerTagSupport {
private static final Log logger = LogFactory.getLog(UserVersionOfSite.class);
private StringWriter sw = new StringWriter();
#Override
public void doTag() throws IOException, JspException {
getJspBody().invoke(sw); //get the tag body and put it in StringWriter object
//get request object to get cookie value
PageContext ctx = (PageContext)getJspContext();
HttpServletRequest httpServletRequest = (HttpServletRequest) ctx.getRequest();
HttpServletResponse httpServletResponse = (HttpServletResponse) ctx.getResponse();
if(httpServletRequest.getParameterMap().containsKey("show_full_site")) {
logger.debug("show_full_site ");
if(!checkIfCookieExists(httpServletRequest)){
Cookie cookie = new Cookie("SHOW_FULL_SITE",httpServletRequest.getParameter("show_full_site"));
cookie.setMaxAge(86400);
httpServletResponse.addCookie(cookie);
//write the tag output
if(!httpServletRequest.getParameter("show_full_site").equalsIgnoreCase("true")){
//write the response
getJspContext().getOut().println(sw.toString());
}
}else{
String cookieValueString = getCookieValue(httpServletRequest.getCookies(),"SHOW_FULL_SITE","false");
if(!cookieValueString.equalsIgnoreCase("true")){
//write the response
getJspContext().getOut().println(sw.toString());
}
}
}
}
#Override
public String getResult() throws IOException {
return "User version of site";
}
public String getCookieValue(Cookie[] cookies,
String cookieName,
String defaultValue) {
for(int i=0; i<cookies.length; i++) {
Cookie cookie = cookies[i];
if (cookieName.equals(cookie.getName()))
return(cookie.getValue());
}
return(defaultValue);
}
public boolean checkIfCookieExists(HttpServletRequest httpServletRequest){
logger.debug("inside checkIfCookieExists()");
boolean cookiePresent = Arrays.asList(httpServletRequest.getCookies()).contains( "SHOW_FULL_SITE" );
return cookiePresent;
}
}
Even I tried adding the code without using if else statements but still no success. Is there any thing critical I am missing?
Any ideas guys??!!! I have checked the browser's setting as well, but there is nothing there which is blocking a creation of cookie!
I realise the horse has probably bolted by the time I'm posting this but, for the benefit of others stumbling across it, I think the problem may be related to the feature of RequestDispatcher highlighted in this question: unable to add a cookie included in JSP via jsp:include
your following line inside checkIfCookieExists() method is wrong:
Arrays.asList(httpServletRequest.getCookies()).contains( "SHOW_FULL_SITE" );
HttpServletRequest.getCookies() returns Cookie[]. You are wrapping it inside a List and checking for a string "SHOW_FULL_SITE" inside this.
Coming back to your question- how do you know cookie is not being set in the HTTP headers? Try using browser plugins like firebug to see the HTTP response headers coming from server. Also set the path of cookie before adding it to response e.g.
Cookie cookie = new Cookie("SHOW_FULL_SITE",httpServletRequest.getParameter("show_full_site"));
cookie.setMaxAge(86400);
cookie.setPath("/");

Servlet mixes header and content and writing twice same in output?

I have implemented servlet which behaves not stable, sometimes it mixes header in content and writing same twice.
and sometimes it is returning file which contains response header mixed by content like this:
Server: Apache-Coyote/1.1
: W/"43-1353687036000"
DatCCoonntenntt--DDiissppoosittiioonn: : atatatacehnmte;n tf;i lfenlaemnea=m20=12201112211127325421_4W1_Wirnkgi_nSgc_Seern.xnlsx
sx
Content-Typ-eT: ype: applaipcatciaoti/on/toctestt-rstare
am
ConCtoententy-pTeype: appalicatcion/oon/octet-setarm
m
CCoonntent-Lnegtht h: 4199
Date: te: FriF,r i2,3 2No vNo2v0 120162: 215:25 :G4M2T
....
File content bytes ...
And again same header and content
UPDATE
*This situation happens on Tomcat7*
I have tested also on Tomcat6 and Jetty, in both cases there is no injection of HTTP-Header to response content but HTTP-Header is wrong and returns wrong file name, the file content is correct file. I have noticed that wrong return from servlet happens when
returns transfer-encoding is chunked.
When I am removing header stuff, and second part of bytes, it is valid file.
Is it possible that is synchronization issue ?
UPDATE
Here is full source of servlet :
public class ExcelDownloadServlet extends HttpServlet
{
private static final long serialVersionUID = 1L;
private static final Logger LOG = Logger
.getLogger (ExcelDownloadServlet.class);
#Override
protected void doGet (HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException
{
try
{
TransactionId transactionId = getTransactionId (request);
String fileName =
request.getParameter (GlobalConstants.EXCEL_FILE);
ExcelDownloadType downloadType =
ExcelDownloadType
.valueOf (request
.getParameter (GlobalConstants.EXCEL_DOWNLOAD_TYPE));
ActionContextFactory actionContextFactory =
ApplicationContext.getContext ()
.getActionContextFactory ();
//suppress warning. HttpServletRequest.getLocales does not support generics
#SuppressWarnings("unchecked")
ActionContext actionContext =
actionContextFactory.create (request.getSession ()
.getId (), Collections.<Locale> list (request
.getLocales ()));
GetExcelDataResponse dataResponse =
new GetExcelData (transactionId, fileName, downloadType)
.execute (actionContext);
writeToResponse (response, dataResponse.getFileName (),
dataResponse.getData ());
}
catch (InvalidSessionException e)
{
LOG.error ("Invalid session in Excel download", e);
throw new ServletException (e);
}
catch (ActionException e)
{
LOG.error ("Could not download into excel.", e);
throw new ServletException (e);
}
}
protected TransactionId getTransactionId (HttpServletRequest request)
{
return RequestParameterDeserializer.<TransactionId> deserialize (
request, GlobalConstants.TRANSACTION_ID);
}
protected void writeToResponse (HttpServletResponse response,
String rawFileName, byte[] data) throws IOException
{
ServletOutputStream sout = null;
try
{
response.setContentType ("application/octet-stream");
response.setContentLength (data.length);
// removing blanks from the file name, since FF cuts file names
// otherwise.
String fileNameWithTime = rawFileName.replaceAll (" ", "_");
response.setHeader ("Content-Disposition", "attachment; filename="
+ fileNameWithTime);
sout = response.getOutputStream ();
sout.write (data, 0, data.length);
}
finally
{
if (sout != null)
{
sout.close ();
}
}
}
UPDATE
*The call comes from GWT application when is generating the URL of servlet with required parameters and sets in IFrame, then servlet calls and file is downloading. Are there any suggestions ?*
I had a similar issue a long time ago.
It turned out that closing the ServletOutputStream triggered an unexpected behaviour on the request flow.
Servlets are not supposed to close the container provided OutputStream.
Another issue could be manually setting the content length, it is responsibility of the container producing the correct value.
To summarize, try removing out.close() and response.setContentLength()

Need help with creating custom HttpServletResponse

Suddenly stuck on generating custom servlet response. I want to replace servlet response with predefined one:
public class MyCustomResponse extends HttpServletResponseWrapper {
private String customOutput;
public MyCustomResponse(String customOutput, HttpServletResponse response) {
super(response);
// PrintWriter and Outputstream should stream this variable as output
this.customOutput = customOutput;
}
//
// Below I need to override something
//
}
and filter code snipped as follows:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
//
//
MyCustomResponse customResponse = new MyCustomResponse("Hello world!", (HttpServletResponse) response);
chain.doFilter(request, customResponse);
}
Shame on me, but i'm really stuck on coding this simple task :(
Any help would be appreciated.
UPDATE:
All I want is to implement custom response wrapper which, once it's put into filter chain, would always respond with some predefined text. I know how to write custom data from within doFilter() method, but I want MyCustomResponse to be responsible for that - just instantiate and put in chain. Any well-reasoned responses "You cant do that because..." are also welcome.
As quoted in one of your comments :
"I want my custom response to return a
string in response to getWriter or
getOutputStream method invocation"
For that, you have to provide your own implementation for getWriter() & getOutputStream() by overriding them.
//---
private PrintWriter printWriter = null;
private ServletOutputStream outputStream = null;
public PrintWriter getWriter( ) throws IOException {
if (this.outputStream != null) {
throw new IllegalStateException(
"Cannot call getWriter( ) after getOutputStream( )");
}
if (this.printWriter == null) {
// initialize printWriter
}
return this.printWriter;
}
public ServletOutputStream getOutputStream( ) throws IOException {
if (this.printWriter != null) {
throw new IllegalStateException(
"Cannot call getOutputStream( ) after getWriter( )");
}
if (this.outputStream == null) {
// initialize outputStream
}
return this.outputStream;
}
//---
I am sorry, but
it is not clear what is your
problem. You code is written, so? It
does not work? what exactly does not work?
Why do you want to do this? The "right" solution is to pass information as session attribute.
I do not believe this can work. Really, you do not call directly the next filter in chain. You are kindly asking the app. server to do this. And you are not expected to replace the servlet request/response by your own. Use method explained above (#2)
Your response wrapper is useless as is, since it only stores a string in the Java object used to model the actual HTTP response.
The actual HTTP response that the client receives is the stream of bytes (resp. characters) sent via the output stream (resp. writer) of the HttpServletResponse object (and the headers, cookies, etc. stored in the HttpServletResponse object).
If you want to send a custom output string to the client, just use response.getWriter().print("Hello worlds!").
Passing the response to the rest of the filter chain is questionable, since the rest of the chain will probably want to add its own data to the response stream.
If you want to hard-code the response to send to the client to your custom output, but be able to still pass the response to the chain and ignore whatever the rest of the chain puts in the response, you could try to add the following to your wrapper :
private ServletOutputStream fakeOutputStream =
new ServletOutputStream() {
#Override
public void write(int b) throws IOException {
// do nothing. Everything written to this stream is ignored
}
}
private PrintWriter fakeWriter = new PrintWriter(fakeOutputStream);
public MyCustomResponse(String customOutput, HttpServletResponse response) {
super(response);
response.getWriter().print(customOutput);
}
#Override
public ServletOutputStream getOutputStream() {
return fakeOutputStream;
}
#Override
public PrintWriter getWriter() {
return fakeWriter;
}
I don't see the reason of what you want to do, but if you want to use your wrapper, my suggestion would be:
Create your own servlet that uses your wrapper and register it in web.xml, in something like this:
Extend javax.servlet.GenericServlet and override the service(ServletRequest, ServletResponse) method. Then you use the Template Method pattern to create a service(ServletRequest, ServletResponseWrapper). OR
Extend javax.servlet.HttpServlet and override service(HttpServletRequest, HttpServletResponse) method. Use the Template Method pattern to create a service(HttpServletRequest, HttpServletResponseWrapper). This will require that you don't use the doGet, doPost, doPut, doTrace methods already provided by HttpServlet but, instead create your own that uses your wrapper.
Hope this helps.

Categories

Resources