I have a servlet that looks like this:
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
validateInput(param1, param2, request, response);
//if nothing's wrong with the input, do this and that
}
private void validateInput(String param1, String param2, HttpServletRequest request, HttpServletResponse response) throws IOException{
boolean fail = false;
//validate input blah blah blah
if (fail){
PrintWriter out = response.getWriter();
out.write("invalid input");
//end process or servlet
}
}
The idea is that I want to pass param1 and param2 to function validateInput() to validate whether or not the input is valid. If input is invalid, write a message back and then end the process. My question is how to end the process? I'm aware of that calling return; in doPost() will end the process but I'm trying to avoid returning any value from validateInput() to doPost() just for the sake of ending the process. I personally feel that it's more readable this way rather than returning true or false to doPost() and call return; there. Is there a way to do it? Or is it simply impossible?
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
if(!isValidInput(param1, param2)){
PrintWriter out = response.getWriter();
out.write("invalid input");
return;
}
//if nothing's wrong with the input, do this and that
}
private boolean isValidInput(String param1, String param2){
boolean fail = false;
//validate input and return true/false
}
Control will always return to doPost after validateInput runs unless you throw an exception (either an unchecked exception or IOException in this case).
So if you do not return ANY value from validateInput to doPost, even if you commit the response, doPost will still go on to do whatever it is supposed to do. (Of course, if the response is commited, the browser will be entirely unaware of any further activity on the server side).
You will need to return a value, throw an exception (which doPost may catch) or set a global value that doPost checks (which is just messy).
More sophisticated way would be .
validate and setAttributes to request if error found and forward request to jsp
on jsp check for the error attribute if any present display them
See Also
our Servlet wiki page, it explains it very well with example
What are you calling "the process"? That single request? If yes, then sending a message back DOES end the servlet's responsibility. HTTP is a request/response protocol.
If you mean stopping the servlet, that's not right. The servlet runs in the container, which is still going. It waits for the next request.
I don't see anything that merits stopping. Validation and routing back with errors is common.
Try this:
I changed your validate to return a boolean, so you can run an if statement on it in the doPost method. I also made it return a success instead of failure, just so the check makes more sense once you've returned.
response.sendError will allow you to do a generic error page (See this: http://blogs.atlassian.com/2007/07/responsesenderror_vs_responses/) instead of your output. If you want that you'll want setStatus (again, see the link).
The return should terminate execution and prevent the rest from happening, but it won't shut down the servlet like a system.exit(0) would.
public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException{
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
if (! validateInput(param1, param2, request, response)){
response.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
//Or you can use this instead...
//response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
//PrintWriter out = response.getWriter();
//out.write("invalid input");
return;
}
//if nothing's wrong with the input, do this and that
}
private boolean validateInput(String param1, String param2, HttpServletRequest request, HttpServletResponse response) throws IOException{
boolean success = false;
//validate input blah blah blah
return success;
}
It sounds like you want to get a reference to the OutputStream to write HTML back to the client?
You can make use of response.getOutputStream() that would return a ServletOutputStream.
Once you have written to this stream, you need to finish. You will have to close() and flush() once you are done.
Whatever you write to this stream will be sent to the browser. Also remember to call the
response.setContentType("text/html"); so the browser knows its dealing with HTML.
have you tried with either one of the following
response.sendRedirect("some view.jsp");
(or)
System.exit(0); // which exits from the program
Related
I want to understand why don't print statements work when I use forward method.I know in forward method we are redirecting to another servlet but should'nt my print statements before the redirection get printed/shown in the browser.These statements also don't work when I use sendredirect() method but work when I use include() method
public class RdServlet extends HttpServlet
{
public void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
res.setContentType("text/html");
PrintWriter out = res.getWriter();
out.println("<html><body>");
String name=req.getParameter("name");
String pass=req.getParameter("pass");
try
{
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection c = DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","system","mca6");
Statement s = c.createStatement();
String s1="select * from emp101 where name='"+name+"' and pass='"+pass+"'";
ResultSet rs=s.executeQuery(s1);
out.println("before dispatcher");
out.println("<br>");
if(rs.next())
{
RequestDispatcher rd=req.getRequestDispatcher("/wel");
//rd.include(req,res);
rd.forward(req,res);
}
else
{
RequestDispatcher rd=req.getRequestDispatcher("/err");
//rd.include(req,res);
rd.forward(req,res);
}
}catch(Exception e){out.println(e);}
out.println("<br>");
out.println("after requestDispatcher");
out.println("</body></html>");
}
}
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.
If you want to include response from two servlet, use RequestDispatcher.include.
References:
How redirect request from jsp to a servlet
I have a working servlet wich originates back from this template:
http://www.objectdb.com/tutorial/jpa/eclipse/web/servlet
So the basic rountrip works.
I added a new feature where I POST data to the servlet, construct a call/request out of the data to a remote http server, retrieve the response-html-string (the content of the website I requested) and want to show this HTML String now as response to my original POST call.
I tried it like this:
#Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException,
IOException {
boolean showDetails = Boolean.valueOf(request.getParameter("showDetails"));
if (showDetails) {
String details = detailsLoader.loadDetails(String.valueOf(request.getParameter("value1")),
String.valueOf(request.getParameter("value2")));
response.getWriter().println(details);
response.getWriter().flush();
response.getWriter().close();
return; // <----------------- if showDetails then this is the end of doPost
}
// Display the list of guests:
doGet(request, response);
}
When I press the link that creates the POST event I see in the logfile, that "loadDetails" has succesfully loaded the content from the remote server, but the browser window does not refresh. Why?
PS: a simple redirect to the other side is not possible for technical reasons.
Try making a ajax request to your servlet which gives to html content as string sent it back to ajax call and set it to innerHTML of a div element.
I changed to use GET instead of POST and I used a separate Servlet for this kind of call. This solved my problem.
#Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String details = detailsLoader.loadDetails(String.valueOf(request.getParameter("value1")),
String.valueOf(request.getParameter("value2")));
response.getWriter().println(details);
response.getWriter().flush();
response.getWriter().close();
}
I m trying to use aspectJ to intercept HttpServlet.do*(request, response) and get the HTML text ( need to extract the title and maybe store the html to a file).
What is the best way to access the response body (html text) once I have a reference to the HttpServletResponse?
Here is my staring code.
public aspect HttpRequestHandlerAspect {
pointcut getRequest(HttpServletRequest request, HttpServletResponse response)
: execution(protected * javax.servlet.http.HttpServlet.*(HttpServletRequest, HttpServletResponse))
&& args(request, response);
Object around(HttpServletRequest request, HttpServletResponse response) : getRequest(request, response) {
Object ret = proceed(request, response);
// now how do I access the HTML response text ( and get the title of the page) in here?
}
}
This might not be the precise answer for your question, but try extracting the response as suggested here: How can I read an HttpServletReponses output stream?
You don't have to create a filter, only an HttpServletResponseWrapper which you pass to
proceed(request, wrapper).
Object around(HttpServletRequest request, HttpServletResponse response): getRequest(request, response) {
MyHttpServletResponseWrapper wrapper = new MyHttpServletResponseWrapper(response);
Object ret = proceed(request, wrapper);
// The MyHttpServletReponseWrapper class captures everything and doesn't forward to the original stream, so we have to do this
response.getWriter().write(wrapper.toString());
// use wrapper.toString() to access response
}
I have an input in my jsf page like this
<html:inputText id="ResponseOK" value="#{bean.ResponseOK}" binding="#{bean.ResponseOKInput}" />
I want to get the value in a servlet (by request.getParameter ("ResponseOK")) when i click on a command button
<html:commandButton value="Valider" action="#{bean.callServlet}"/>
which call a function
public void callServlet()
{
String url = "http://localhost:8080/TestOne/Timers"; //servlet
FacesContext context = FacesContext.getCurrentInstance();
try {
context.getExternalContext().redirect(url);
}catch (Exception e) {
e.printStackTrace();
}
finally{
context.responseComplete();
}
}
Unfortunately, in my servlet the variable Ok , return only null
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
String Ok = request.getParameter("ResponseOK");// return null
System.out.println(timerOk);
}
thank you very much
In order for you to be able to get a property from the request, the input must have the name attribute:
<html:inputText id="ResponseOK" value="#{bean.ResponseOK}" binding="#{bean.ResponseOKInput}" name="ResponseOK"/>
UPDATE:
I'm not too familiar with the JSF framework but i think your problem is the action button.
This button is not a submit button so the value of the input is not being sent to the request.
When calling a GET request, you need to pass the parameter in URL itself, so you need the url to look like:
http://localhost:8080/TestOne/Timers?ResponseOK=value
So you need to transfer the value of the ResponseOK input to the callServlet method.
Hope that helps.
In ATG, the Switch droplet will go to the default oparam if none of the other conditions are met.
I have a droplet that I want to behave similarly. You call it on your page and put code inside of oparam conditions. If you don't have an case for the oparam that is returned from your droplet, it should just go to the default.
droplet.java
public void service(DynamoHttpServletRequest request, DynamoHttpServletResponse response)
throws ServletException, IOException
{
String b = (String) request.getParameter("a");
if(b != null && b.equals("c")){
request.serviceLocalParameter("d", request, response);
}else{
request.serviceLocalParameter("e", request, response);
}
}
droplet.jsp
<dsp:droplet name="Droplet">
<dsp:oparam name="d">
<!-- d param was set -->
</dsp:oparam>
<dsp:oparam name="default">
<!-- e, or some other param was set -->
</dsp:oparam>
</dsp:droplet>
I'm somewhat new to ATG, so I might be going about this the wrong way...
If you try and service a non-existent local parameter, the serviceLocalParameter will return false. So all you have to do is check the value returned by serviceLocalParameter(), if it is false, you can service any number of different arbitrary local parameters. In the example below, I service the arbitrary parameter "default" (NOTE: default is ARBITRARY, it could be called anything. If I had an oparam "foo" and an oparam "bar" and an oparam "beh" I could try and service foo, if that failed, I could try and service bar and if that failed I could try and service beh...)
So, applied to your example, the following would do what you want:
droplet.java
public void service(DynamoHttpServletRequest request, DynamoHttpServletResponse response)
throws ServletException, IOException
{
boolean handled = false;
String b = (String) request.getParameter("a");
if(b != null && b.equals("c")){
handled = request.serviceLocalParameter("d", request, response);
}else{
handled = request.serviceLocalParameter("e", request, response);
}
/*
* Did not find a valid parameter, try servicing the
* parameter named "default" instead
*/
if (!handled) {
request.serviceLocalParameter("default", request, response);
}
}
A more simplified version of this for illustrative purposes (with only the code relevant to serving default):
boolean handled = false;
handled = request.serviceLocalParameter("nondefault", request, response);
if (!handled) {
handled = request.serviceLocalParameter("default", request, response);
}