Error 500 response is not committed - java

I am trying to send a request to my jsp page i.e manufacturer details and get the attribute via session, but it throws a 500 error.
package com.osahub.disaster.controller;
import java.io.IOException;
import static com.osahub.disaster.controller.Ofymethodadmin.ofy;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.*;
import com.osahub.disaster.controller.SendMail;
#SuppressWarnings("serial")
public class admin extends HttpServlet {
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException, ServletException {
resp.setContentType("text/plain");
resp.getWriter().println("Data Saved!");
PrintWriter out = resp.getWriter();
String name= req.getParameter("name");
String address = req.getParameter("address");
String email = req.getParameter("email");
String website = req.getParameter("website");
String topex = req.getParameter("topex");
String topdes = req.getParameter("topdes");
String topmob = req.getParameter("topmob");
String year = req.getParameter("year");
String brand = req.getParameter("brand");
String factory = req.getParameter("factory");
String sector = req.getParameter("sector");
String contactpername = req.getParameter("contactpername");
String contactperdes = req.getParameter("contactperdes");
String contactpermob = req.getParameter("contactpermob");
HttpSession currentSession=req.getSession();
currentSession.setAttribute("name", name);
req.getRequestDispatcher("ManufacturerDetails.jsp").forward(req, resp);
SendMail mail = new SendMail();
mail.send(email, "send Test mail from gae" , "this is the mail body");
ManufacturerDetails ad = new ManufacturerDetails(name,address,email,website,topex,topdes,topmob,year,brand,factory,sector,contactpername,contactperdes,contactpermob);
ofy().save().entity(ad);
ofy().clear();
List<ManufacturerDetails> li = ofy().load().type(ManufacturerDetails.class).list();
Iterator<ManufacturerDetails> iter = li.iterator();
while(iter.hasNext())
{
ManufacturerDetails ad1 = iter.next();
System.out.println(ad1.getName());
System.out.println(ad1.getAddress());
System.out.println(ad1.getEmail());
System.out.println(ad1.getWebsite());
System.out.println(ad1.getTopex());
System.out.println(ad1.getTopdes());
System.out.println(ad1.getTopmob());
System.out.println(ad1.getYear());
System.out.println(ad1.getBrand());
System.out.println(ad1.getFactory());
System.out.println(ad1.getSector());
System.out.println(ad1.getContactpername());
System.out.println(ad1.getContactpermob());
System.out.println(ad1.getContactperdes());
}
resp.sendRedirect("about.jsp");
}
}

A response with HTTP status code 500 can be caused by any exception.
However, it looks like in your case the exception is thrown because you call resp.sendRedirect("about.jsp"); after req.getRequestDispatcher("ManufacturerDetails.jsp").forward(req, resp);.
You cannot do that, because once the call to forward() completes, the response is committed. However, it does not mean that doPost() method returns control, it keeps executing. Thus, resp.sendRedirect("about.jsp"); causes java.lang.IllegalStateException exception to be thrown, since the response is already closed.
You have to review your method, and introduce a conditional statement:
if (condition) {
// do something
req.getRequestDispatcher("ManufacturerDetails.jsp").forward(req, resp);
} else {
// do something
resp.sendRedirect("about.jsp");
}
Another option is to introduce an explicit return after req.getRequestDispatcher("ManufacturerDetails.jsp").forward(req, resp);.

500 exception occurs due to the server problem . It is cause because you can write both code - getRequestDispatcher and sendRedirect for execute . And this is not possible . You can not do this because after once send the request paramater it terminate . So you can write both code in if-else condition .

Related

How to create session only once, when the server starts?

I'm creating a chatbot for a java application with Watson Assistant, the servlet code:
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String sessionIdOut = "";
String question = req.getParameter("message");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// Set up Assistant service.
IamOptions iamOptions = new IamOptions.Builder().apiKey("<apikey>").build();
Assistant service = new Assistant("2018-09-20", iamOptions);
service.setEndPoint("https://gateway-lon.watsonplatform.net/assistant/api/");
assistantId = "<assistantid>";
// Create session.
CreateSessionOptions createSessionOptions = new CreateSessionOptions.Builder(assistantId).build();
SessionResponse session = service.createSession(createSessionOptions).execute();
sessionId = session.getSessionId();
// Suppress log messages in stdout.
LogManager.getLogManager().reset();
// Initialize with an empty value to start the conversation.
String inputText = question;
// Send message to assistant.
MessageInput input = new MessageInput.Builder().text(inputText).build();
MessageOptions messageOptions = new MessageOptions.Builder(assistantId, sessionId)
.input(input)
.build();
MessageResponse response = service.message(messageOptions).execute();
// Print the output from the dialog if any. Assumes a single text response.
List<DialogRuntimeResponseGeneric> responseGeneric = response.getOutput().getGeneric();
if(responseGeneric.size() > 0) {
System.out.println(response.getOutput()/*.getGeneric().get(0).getText()*/);
String answer = response.getOutput().getGeneric().get(0).getText();
// set up the response
res.setContentType("text/html");
res.setHeader("Cache-Control", "no-cache");
// write out the response string
res.getWriter( ).write(answer);
}
// Prompt for next round of input.
System.out.print(">> ");
}
Currently, the servlet always creates a new session and sets up the assistant when the GET request arrives from the user interface. I want it to create a new session and set up assistant service only once when the server starts.
Tryed to solve the problem by adding init() function, and writing the session creation and assistant setup code inside that init() function like this:
#Override
public void init() throws ServletException {
// Set up Assistant service.
IamOptions iamOptions = new IamOptions.Builder().apiKey("<apikey>").build();
Assistant service = new Assistant("2018-09-20", iamOptions);
service.setEndPoint("https://gateway-lon.watsonplatform.net/assistant/api/");
assistantId = "<assistantid>";
// Create session.
CreateSessionOptions createSessionOptions = new CreateSessionOptions.Builder(assistantId).build();
SessionResponse session = service.createSession(createSessionOptions).execute();
sessionId = session.getSessionId();
super.init();
}
But it doesn't work, when I write a question in user interface, it sends me back 500 status code.
I solved the problem!
Working code looks like:
package com.jtypebot;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
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 javax.servlet.http.HttpSession;
import com.ibm.watson.developer_cloud.assistant.v2.Assistant;
import com.ibm.watson.developer_cloud.assistant.v2.model.CreateSessionOptions;
import com.ibm.watson.developer_cloud.assistant.v2.model.DeleteSessionOptions;
import com.ibm.watson.developer_cloud.assistant.v2.model.DialogRuntimeResponseGeneric;
import com.ibm.watson.developer_cloud.assistant.v2.model.MessageInput;
import com.ibm.watson.developer_cloud.assistant.v2.model.MessageOptions;
import com.ibm.watson.developer_cloud.assistant.v2.model.MessageResponse;
import com.ibm.watson.developer_cloud.assistant.v2.model.RuntimeIntent;
import com.ibm.watson.developer_cloud.assistant.v2.model.SessionResponse;
import com.ibm.watson.developer_cloud.service.security.IamOptions;
import java.util.List;
import java.util.logging.LogManager;
#WebServlet("/JtypeBot")
public class JtypeBot extends HttpServlet {
private static final long serialVersionUID = 1L;
String sessionId;
String assistantId;
Assistant service;
/**
* #see HttpServlet#HttpServlet()
*/
public JtypeBot() {
super();
}
#Override
public void init() throws ServletException {
super.init();
// Set up Assistant service.
IamOptions iamOptions = new IamOptions.Builder().apiKey("<apiKey>").build();
service = new Assistant("2018-09-20", iamOptions);
service.setEndPoint("https://gateway-lon.watsonplatform.net/assistant/api/");
assistantId = "<assistantId>"; // replace with assistant ID
// Create session.
CreateSessionOptions createSessionOptions = new CreateSessionOptions.Builder(assistantId).build();
SessionResponse session = service.createSession(createSessionOptions).execute();
sessionId = session.getSessionId();
System.out.print(sessionId);
}
/**
* #see HttpServlet#doGet(HttpServletRequest request, HttpServletResponse response)
*/
public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String sessionIdOut = "";
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String question = req.getParameter("message");
// Suppress log messages in stdout.
LogManager.getLogManager().reset();
// Initialize with empty value to start the conversation.
String inputText = question;
// Send message to assistant.
MessageInput input = new MessageInput.Builder().text(inputText).build();
MessageOptions messageOptions = new MessageOptions.Builder(assistantId, sessionId)
.input(input)
.build();
MessageResponse response = service.message(messageOptions).execute();
// Print the output from dialog, if any. Assumes a single text response.
List<DialogRuntimeResponseGeneric> responseGeneric = response.getOutput().getGeneric();
if(responseGeneric.size() > 0) {
System.out.println(response.getOutput()/*.getGeneric().get(0).getText()*/);
String answer = response.getOutput().getGeneric().get(0).getText();
// set up the response
res.setContentType("text/html");
res.setHeader("Cache-Control", "no-cache");
// write out the response string
res.getWriter( ).write(answer);
}
// Prompt for next round of input.
System.out.print(">> ");
}
}

Null value From request.getParameter

Login Controller:
package test;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import com.webappmvc.mvc.controller.Controller;
public class Login implements Controller{
public void doProcess(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
System.out.println("UserName Parameter Value: " + request.getParameter("username"));
if(request.getParameter("login") != null && request.getParameter("userName") != null && request.getParameter("password") != null){
if(!request.getParameter("userName").equals("") && !request.getParameter("password").equals("") && request.getParameter("login").equals("Login")){
ArrayList<String> data = (ArrayList<String>) request.getAttribute("model");
for(int i=0; i<data.size(); i+=2){
System.out.println("Username from DB: " + data.get(i) + "\nPassword: " + data.get(i+1));
// if(request.getParameter("username").toString().equals(data.get(i))){
// if(request.getParameter("password").toString().equals(data.get(i+1).toString())){
// session.setAttribute("loggedUser", data.get(i).toString());
// response.sendRedirect("home");
// return;
// }
// request.setAttribute("errorMsg", "Invalid Login");
// }
}
}
}
System.out.println("Result view is: " + request.getAttribute("view"));
request.getRequestDispatcher(request.getAttribute("view").toString()).forward(request, response);
}
public String addMapping() {
return "/login";
}
}
Here, Every request going through WebappController class defined in com.webappmvc.mvc.controller.Controller, com.webappmvc.mvc.controller.Controller#doGet method select controller, model, view on runtime, then forward it to com.webappmvc.mvc.controller.ResponseController#doGet
Then, In response Controller, some code like this which forward request, response client project Controller#doProcess method.
Controller controller = (Controller) request.getAttribute("controller");
controller.doProcess(request, response);
With these, when i tried to acces /login, LoginController getting called, But
getParameter() returning null each and every time. I also tried to acces this URL
Requested URL:
http://localhost:8080/FreameworkTest/controller/login?userName=test&password=test&login=Login
I'm Getting Output in console like these.
Console Output:
All request passing through WebApp Controller //From WebAppController
----- From Response Controller //From WebAppResponseController
UserName Parameter Value: null //From LoginController
Username from DB: jitu
Password: 12345
Result view is: /WEB-INF/views/Login.jsp
You are using send :
userName=test
And get the attribute with
request.getParameter("username");
You made a typo. Use instead
request.getParameter("userName");
Error you didn't do in the second part.
NOTE:
I suggest you define constant value for those instead of use a String literal
private final statis String USER_NAME = "userName";
And use it each time you need
request.getParameter(USER_NAME);

ArrayList issue in HTTP Servlet

I'm using Floodlight REST API in order to monitor a created virtual network in mininet. My goal is to display an arraylist of all the switches, hosts and statistics for the switches on a web browser using Apache Tomcat web server and HTTP Servlet. The application successfully displays all the switches and hosts, but fails when I'm adding the statistics for the switches.
When I'm mapping JSON string to java objects, the server returns the error in this line:
ArrayList<Switch> queues = mapper.readValue(queueJson, new TypeReference<ArrayList<Switch>>() {
});
The error is:
HTTP status 500 - can not deserialize instance of java.util.arraylist out of start_object token
I have testet it without the switch statistics (Queues) part (with only hosts and devices) and everything works fine, but when I'm adding the queues ArrayList, it returns the above mentioned error.
How can I solve this issue ?. My code is shown below. Thanks in advance
package core;
import java.io.IOException;
import java.io.StringWriter;
import java.util.ArrayList;
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.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.type.TypeReference;
import org.restlet.data.MediaType;
import org.restlet.resource.ClientResource;
import org.restlet.resource.ResourceException;
import pojos.Device;
import pojos.Switch;
#WebServlet("/PrintInfo")
public class PrintInfo extends HttpServlet {
private static final long serialVersionUID = 1L;
public PrintInfo() {
super();
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// create ClientResource object
// List at the switches in the network
ClientResource cResourceSwitches = new ClientResource("http://127.0.0.1:8080/wm/core/controller/switches/json");
StringWriter sWriterSwitches = new StringWriter();
// List all the devices (hosts) in the network
ClientResource cResourceDevices = new ClientResource("http://127.0.0.1:8080/wm/device/");
StringWriter sWriterDevices = new StringWriter();
// List the statistics of the switches in the network
ClientResource cResourceQueues = new ClientResource("http://127.0.0.1:8080/wm/core/switch/all/queue/json");
StringWriter sWriterQueues = new StringWriter();
// get JSON data about switches; the data is put in a string writer
try {
// Getting data from Floodlight as a JSON string
cResourceSwitches.get(MediaType.APPLICATION_JSON).write(sWriterSwitches);
cResourceDevices.get(MediaType.APPLICATION_JSON).write(sWriterDevices);
cResourceQueues.get(MediaType.APPLICATION_JSON).write(sWriterQueues);
} catch (ResourceException e) {
request.setAttribute("error", "Connection with FLoodLight failed!");
request.getRequestDispatcher("WEB-INF/connectionError.jsp").forward(request, response);
return;
}
// put data from string writer into a string object
String switchesJson = sWriterSwitches.toString();
String devicesJson = sWriterDevices.toString();
String queueJson = sWriterQueues.toString();
// map JSON data to Java objects
// ObjectMapper converts between JSON - Java
ObjectMapper mapper = new ObjectMapper();
ArrayList<Switch> switches = mapper.readValue(switchesJson, new TypeReference<ArrayList<Switch>>() {
});
ArrayList<Device> devices = mapper.readValue(devicesJson, new TypeReference<ArrayList<Device>>() {
});
ArrayList<Switch> queues = mapper.readValue(queueJson, new TypeReference<ArrayList<Switch>>() {
});
// put objects in the request so we can use them later in the JSP
request.setAttribute("switches", switches);
request.setAttribute("devices", devices);
request.setAttribute("queues", queues);
// redirect to the jsp
request.getRequestDispatcher("WEB-INF/showInfo.jsp").forward(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
}
}
Solved. The Switch class in "ArrayList" can't be used for switch statistics. A new class has to be implemented, which returns the values in
http://127.0.0.1:8080/wm/core/switch/all/queue/json
URI.

Get parameter sent via jquery ajax in Java Servlet [duplicate]

This question already has answers here:
How should I use servlets and Ajax?
(7 answers)
Closed 5 years ago.
I search this topic on web but I can't get a example that worked.
I will be gladed with someone could give me a help.
this is what I testing.
$.ajax({
url: 'GetJson',
type: 'POST',
dataType: 'json',
contentType: 'application/json',
data: {id: 'idTest'},
success: function(data) {
console.log(data);
}
});
in Sevlet
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String id = request.getParameter("id");
String id2[] = request.getParameterValues("id");
String id3 = request.getHeader("id");
}
I'm getting null in everything.
I had the same issue with getParameter("foo") returning null in the servlet. Found a simple solution which might be useful to people here. Use the default value
contentType='application/x-www-form-urlencoded; charset=UTF-8'
or leave it out. This will automatically encode the request with the data in parameters.
Hope this helps...
The sort answer is that this data is hidden in the request InputStream.
The following servlet is a demo of how you can use this (I am running it on a JBoss 7.1.1):
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
#WebServlet(name="fooServlet", urlPatterns="/foo")
public class FooServlet extends HttpServlet
{
#Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = req.getInputStream();
ByteArrayOutputStream os = new ByteArrayOutputStream();
byte[] buf = new byte[32];
int r=0;
while( r >= 0 ) {
r = is.read(buf);
if( r >= 0 ) os.write(buf, 0, r);
}
String s = new String(os.toByteArray(), "UTF-8");
String decoded = URLDecoder.decode(s, "UTF-8");
System.err.println(">>>>>>>>>>>>> DECODED: " + decoded);
System.err.println("================================");
Enumeration<String> e = req.getParameterNames();
while( e.hasMoreElements() ) {
String ss = (String) e.nextElement();
System.err.println(" >>>>>>>>> " + ss);
}
System.err.println("================================");
Map<String,String> map = makeQueryMap(s);
System.err.println(map);
//////////////////////////////////////////////////////////////////
//// HERE YOU CAN DO map.get("id") AND THE SENT VALUE WILL BE ////
//// RETURNED AS EXPECTED WITH request.getParameter("id") ////
//////////////////////////////////////////////////////////////////
System.err.println("================================");
resp.setContentType("application/json; charset=UTF-8");
resp.getWriter().println("{'result':true}");
}
// Based on code from: http://www.coderanch.com/t/383310/java/java/parse-url-query-string-parameter
private static Map<String, String> makeQueryMap(String query) throws UnsupportedEncodingException {
String[] params = query.split("&");
Map<String, String> map = new HashMap<String, String>();
for( String param : params ) {
String[] split = param.split("=");
map.put(URLDecoder.decode(split[0], "UTF-8"), URLDecoder.decode(split[1], "UTF-8"));
}
return map;
}
}
With the request:
$.post("foo",{id:5,name:"Nikos",address:{city:"Athens"}})
The output is:
>>>>>>>>>>>>> DECODED: id=5&name=Nikos&address[city]=Athens
================================
================================
{address[city]=Athens, id=5, name=Nikos}
================================
(NOTE: req.getParameterNames() does not work. The map printed in the 4th line contains all the data normally accessible using request.getParameter(). Note also the nested object notation, {address:{city:"Athens"}} → address[city]=Athens)
Slightly unrelated to your question, but for the sake of completeness:
If you want to use a server-side JSON parser, you should use JSON.stringify for the data:
$.post("foo",JSON.stringify({id:5,name:"Nikos",address:{city:"Athens"}}))
In my opinion the best way to communicate JSON with the server is using JAX-RS (or the Spring equivalent). It is dead simple on modern servers and solves these problems.

Redirecting a request using servlets and the "setHeader" method not working

I am new to servlet development, and I was reading an ebook, and found that I can redirect to a different web page using
setHeader("Location", "http://www.google.com")
But this is not working, as I have written this code as:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ModHelloWorld extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
// response.addHeader("Location", "http://www.google.com");
response.setHeader("Location", "http://www.google.com");
response.setContentType("text/html");
PrintWriter pw = response.getWriter();
pw.println("<html><head><title>Modified Hello World</title></head><body>");
pw.println("<h1>");
//getInitParameter function reads the contents ot init-param elements.
pw.println(getInitParameter("message"));
pw.println("</h1>");
pw.println("</body></html>");
pw.close();
}
}
i have checked the headers using my program to get the headers of the webpage which is as under:
import java.net.*;
import java.io.*;
class getHeaders{
public static void main(String args[]){
URL url = null;
URLConnection urc = null;
try {
url = new URL(args[0]);
urc = url.openConnection();
for(int i=0 ; ; i++) {
String name = urc.getHeaderFieldKey(i);
String value = urc.getHeaderField(i);
if(name == null && value == null)//both null so end of header
break;
else if(name == null){//first line of header{
System.out.println("Server HTTP version, Response code: ");
System.out.println(value);
System.out.println("ENd of first header field");
} else {
System.out.println("name of header is: " + name + " and its value is : " + value);
}
}
} catch(MalformedURLException e){
System.out.println("Malformed URL " + e.getMessage());
} catch(IOException e){
e.printStackTrace();
}
}
}
And i am getting the output as:
Server HTTP version, Response code:
HTTP/1.1 200 OK
ENd of first header field
name of header is: Server and its value is : Apache-Coyote/1.1
name of header is: Location and its value is : http://www.google.com
name of header is: Content-Type and its value is : text/html
name of header is: Content-Length and its value is : 101
name of header is: Date and its value is : Sat, 05 Mar 2011 15:27:29 GMT
But I was not redirected to google's page from my browser.
Thanks in advance:)
Oh no no! That's not how you redirect. It's far more simpler:
public class ModHelloWorld extends HttpServlet{
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException{
response.sendRedirect("http://www.google.com");
}
}
Also, it's a bad practice to write HTML code within a servlet. You should consider putting all that markup into a JSP and invoking the JSP using:
response.sendRedirect("/path/to/mynewpage.jsp");
As you can see, the response is still HTTP/1.1 200 OK. To indicate a redirect, you need to send back a 302 status code:
response.setStatus(HttpServletResponse.SC_FOUND); // SC_FOUND = 302
Alternatively, you could try the following,
resp.setStatus(301);
resp.setHeader("Location", "index.jsp");
resp.setHeader("Connection", "close");
Another way of doing this if you want to redirect to any url source after the specified point of time
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
public class MyServlet extends HttpServlet
{
public void doGet(HttpServletRequest request,HttpServletResponse response) throws IOException
{
response.setContentType("text/html");
PrintWriter pw=response.getWriter();
pw.println("<b><centre>Redirecting to Google<br>");
response.setHeader("refresh,"5;https://www.google.com/"); // redirects to url after 5 seconds
pw.close();
}
}

Categories

Resources