Servlet doGet, doPost, and Ajax [duplicate] - java

This question already has answers here:
How should I use servlets and Ajax?
(7 answers)
Closed 6 years ago.
Intro:
I am a bit of a noob to the relationship between doGet and doPost in servlets.
Scope:
I am building a tool to help me with an online auction site where:
I (the user) enter a name into a form (html page), this name will be a URL (potentially for sale ->business method determines this through an API)
the html form posts the form name in doPost and then doPost uses the form name as an argument to call a business method
after the call to business method I redirect to a results html/js page that uses Ajax to call the doGet method to get the associated output (a public class String populated in business logic method)
Problem:
The Ajax page does not seem to get the output from doGet (actually doGet does not seem to have the String to give, no errors- just blank like String="". Which it is until business logic method adds to it).
Question 1:
How can I use doPost to request the form String 'st' so that I may call the business method while also redirecting to the html/js results page AND also am able to call doGet from Ajax
Question 2:
I've been trying to solve my answer by reading SO and other sites- but would like to formally ask rather than impute: is the use of a servlet the fastest way to achieve the Scope(above)? As opposed to JSPs or any other java server side libraries/ frameworks?
hw/ sw: CentOS 6.3, 16gb ram, physical node, corei7 #3.2, container is tomcat 7
HTML
<html>
<head>
<title>URL Search Page</title>
</head>
<body>
<CENTER>
<FORM ACTION="/ResultServlet/Results" METHOD=GET>
<INPUT TYPE=TEXT NAME="st">
<INPUT TYPE=SUBMIT VALUE=Submit>
</FORM>
</CENTER>
</body>
</html>
Servlet
#WebServlet("/Results")
public class Results extends HttpServlet {
private static final long serialVersionUID = 1L;
public static String str="";
public static void businessLogic(String q){
try {
str = new compute.URL.GetAvailURI( "https://www.registerdomains.com/auctionAPI/Key:a05u3***1F2r6Z&urlSearch="+q);
/*more boring number crunching */
}
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter printWriter = response.getWriter();
printWriter.println(str);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String st = request.getParameter("st");
businessLogic(st);
response.sendRedirect("results/resultActionURL.html");
}
}

One problem you form methos is get so when you submit the form it will run the doget method in the servlet which does nothing in your case.
so first change the method to post then try running, also post the code of the html page on which you have written the ajax code.
I think so you are calling the same servlet from the ajax method but at that time the value in the str wont remain so append the needed data as query string while redirecting to
response.sendRedirect("results/resultActionURL.html?st="+ st);
This value you can get from using javascript
function getParameterByName(name) {
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
var regexS = "[\\?&]" + name + "=([^&#]*)";
var regex = new RegExp(regexS);
var results = regex.exec(window.location.search);
if (results == null)
return "";
else
return decodeURIComponent(results[1].replace(/\+/g, " "));
}
var st=getParameterByName(st);
//add your ajax call code and pass st as data there.
Hope this answers your question.

You are making your application stateful by doing this. You are storing data in server across requests.
That means your logic depends on the fact that the same servlet object is triggered, in sequence
Post request - calls business method and populates a string
Get request - tries to retrieve the string populated in last request.
First thing is this is not needed at all, you can pass the populated String to browser during redirect from doPost itself as a parameter or cookie value.
Even if you want to do this store this String in session
request.getSession().setAttribute("str", populated string)
and in doGet method retrieve that using
request.getSession().getAttribute("str"
This much better than having an instance variable in your servlet,.

Once you redirect to other page servlet will destroy request and response objects and variable values... so you can't get the old one... So try to get before redirect or save it on session object...

Related

How to do sessions if client doesn't accept cookies? Understanding response.encodeURL() inside Servlet

I am practicing maintaining sessions between client and server. For that I used simple solution with JSESSIONID stored inside cookie. So my little program works like this:
index.html:
<html><body>
<form action="testing">
<input type="text" name="animal">
<button>Go</button>
</form>
</body></html>
MyServlet.java (mapped in XML as /testing):
public class MyServlet extends HttpServlet {
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
String name = req.getParameter("animal");
PrintWriter pw = resp.getWriter();
pw.print("Welcome " + name + "<br>");
HttpSession session = req.getSession();
if (session.isNew()) {
pw.print("New session: " + session.getId() + "<br>");
} else {
pw.print("Old session: " + session.getId() + "<br>");
}
pw.print("<a href=\'index.html\'> Home </a>");
}
}
So, if I submit something from FORM more than twice, Server should "find" my JSESSIONID stored in heap. Here is a picture of how it would look when FORM is submitted (I typed 'parrot' inside input):
But then I disabled cookies in my browser. After, my server never finds user's JSESSIONID because user never actually stores it anywhere. Remember that before, JSESSIONID was stored in a cookie, but since I disabled them, it can't possibly store it there anymore. So now, I am stuck.
What can I do in this case? I came across response.encodeURL() that uses URL and appends its JSESSIONID into URL. But I have trouble understanding how to implement it and how it works internally. Can someone tell me how to fix this using encodeURL() and actually explain how does code work after made such implementation?
As per the specification, the server should support a few ways of tracking sessions: with cookies, SSL sessions, or URL rewriting.
You are asking about URL rewriting, which works like this:
URL rewriting is the lowest common denominator of session tracking. When a client will not accept a cookie, URL rewriting may be used by the server as the basis for session tracking. URL rewriting involves adding data, a session ID, to the URL path that is interpreted by the container to associate the request with a session.
The session ID must be encoded as a path parameter in the URL string. The name of the parameter must be jsessionid. Here is an example of a URL containing encoded path information:
http://www.myserver.com/catalog/index.html;jsessionid=1234
URL rewriting exposes session identifiers in logs, bookmarks, referer headers, cached HTML, and the URL bar. URL rewriting should not be used as a session tracking mechanism where cookies or SSL sessions are supported and suitable.
Notice that it's a path parameter, not a query parameter. Your query params will follow that, like this:
http://www.myserver.com/catalog/index.html;jsessionid=1234?param1=value1&param2=value2&...
This mechanism is supported automatically by the server to track sessions, but it becomes pretty obvious that you need to give the server a helping hand. And you do that by making sure that all your links include the jsessionid otherwise your server won't identify your request with a session.
You can use encodeURL in your Java code:
Encodes the specified URL by including the session ID, or, if encoding is not needed, returns the URL unchanged. The implementation of this method includes the logic to determine whether the session ID needs to be encoded in the URL. For example, if the browser supports cookies, or session tracking is turned off, URL encoding is unnecessary.
For robust session tracking, all URLs emitted by a servlet should be run through this method. Otherwise, URL rewriting cannot be used with browsers which do not support cookies.
You need to do the same inside your JSP files. That's usually done with something like <c:url> instead of writing URLs directly into the file:
[...] You can use the url tag to rewrite URLs returned from a JSP page. The tag includes the session ID in the URL only if cookies are disabled; otherwise, it returns the URL unchanged. Note that this feature requires that the URL be relative. [...]
Here is something you can do. This is used to append your JSESSIONID to a url you would retrieve to the user, so they can navigate in it and maintain the information of who they are. About understanding how it works internally is simple as you see, it just append the id to a url you pass, how the user information are stored, is your function on the server side, you will use the id given by the user in the next requests to retrieve information to them.
/**
* Almost minimal processing for a servlet.
*
* #param nextUrl The url the caller would like to go to next. If
* supplied, put an encoded url into the returned
* html page as a hyperlink.
*/
#Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
resp.setContentType("text/plain");
PrintWriter out = resp.getWriter();
out.print("OK");
String param = req.getParameter("nextUrl");
if (param!=null) {
// append an encoded url to carry the sessionids
String targetUrl = resp.encodeURL(param);
out.print(". You want to go <a href=\"");
out.print(targetUrl);
out.print("\">here next</a>.");
}
}
Edit:
You put it in this part of your code
pw.print("<a href=\'" + resp.encodeURL("index.html") + "\'>Home</a>");

How to send data from servlet to another servlet? [duplicate]

This question already has answers here:
How to pass a String value from one servlet to another servlet? [duplicate]
(3 answers)
Closed 4 years ago.
This is my simple code in servlet 1. I want to use this data in other servlet. How can I do that?
String nic = request.getParameter("nic");
String name = request.getParameter("name");
String mobile = request.getParameter("mobile");
List<String> ab = new ArrayList<>();
ab.add(nic);
ab.add(name);
ab.add(mobile);
for (String data : ab) {
allData += data + "<br>";
}
If you want to use it immediately (in the same HttpServletRequest)
If the other servlet's doGet or doPost methods are accessible, use...
request.setAttribute(String name, Object o);
add everything to the request object and call it like this,
new servlet2().doPost(request, response);
Else if the other servlet's doGet or doPost methods are inaccessible
Use the RequestDispatcher
RequestDispatcher rd = request.getRequestDispatcher("servlet2");
rd.forward(request, response);
Defines an object that receives requests from the client and sends them to any resource (such as a servlet, HTML file, or JSP file) on the server. The servlet container creates the RequestDispatcher object, which is used as a wrapper around a server resource located at a particular path or given by a particular name. ~ RequestDispatcher (Java EE 6 ), Java doc
If you want to use it in multiple HttpServletRequests,
Add the data into a HttpSession
request.getSession().setAttribute(String name, Object o);
this will remain until the user session is being destroyed.

Send array from one servlet to another servlet and print it?

First of all, I want to send parameters from html to Servlet and it works.
Then I create an array from parameters and I want to send that array to another servlet. and just print it in Servlet2.
Here is my code:
public void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
//System.out.println("XML servlet called!");
response.setContentType("text/html");
response.getWriter();
//read value from selection
String videoname = request.getParameter("video");
String videoformat = request.getParameter("format");
String videoquality = request.getParameter("quality");
//System.out.println("Name" + videoname);
//System.out.println("format" + videoformat);
//System.out.println("quality" + videoquality);
String [] chain1 = {"v1","f1","q1"};
String [] chain2 = {"v1","f1","q2"};
if (videoname.equals(chain1[0]) && (videoformat.equals(chain1[1])) && (videoquality.equals(chain1[2])) ){
request.setAttribute("chain",chain1);
}
}else if (videoname.equals(chain2[0]) && (videoformat.equals(chain2[1])) && (videoquality.equals(chain2[2])) ){
request.setAttribute("chain",chain2);}
RequestDispatcher dispatch = request.getRequestDispatcher("/Servlet2");
dispatch.forward(request, response);
And in Second Servlet , my code is :
String value = (String)request.getAttribute("chain");
System.out.println("Chain is" + value);
My problem is this is doesn`t work. I have 2 problems. 1) how to send attribiute 2) is that possible to see the result in servlet2 in the same mashin? becuse I just create another class wich name is Servlet2 on the same project and define the name and the path in web.xml. Is that right approch?
How to send attribute?
What you are doing to send the attribute (using request.setAttribute and then using dispatch.forward is correct.
Assuming you have just created one new servlet named Servlet2 within the same project and have configured it correctly in web.xml, you should be able to get the attribute in that servlet's GET or POST method.
I believe that you are running into issues because you are modifying the response, which should be done by Servlet2 and not Servlet1. Remove the following lines from your code
response.setContentType("text/html");
response.getWriter();
,since you are not handling the response in Servlet1. This should work, if not, modify your question and include the complete stack trace of the error that you get when you try to compile/run this.
Servlets are created to handle requests sent by clients. I assume that your servlet2 class does a such service. If you declare a public static variable in a servlet, it is accessible by any class. Therefore you don't need to send your data to client from servlet1 and get the client sent them back to servlet2. If you have common variables to all servlets in a web server, you can use static variable. If the sole purpose of servlet2 is printing your data, it shouldn't be a servlet, just a java class would be fine.
Remember that only 1 servlet instance will be created for all requests. Therefore don't use instance variables to store client specific data. Try to use sessions.
This should help you.

Search Variables in HTML from Java?

Whilst working on our coursework for Computer Science, we have had to change from Java to JavaScript in HTML due to a server in-capability. Therefore, I have spent all my research into Java and have a fully working computer program in Java but with this new problem, my whole project needs to be made into JavaScript (or better, HTML)... I have had a brief working with HTML & Dreamweaver so I know how the UI etc. but I need help making a Search Bar that has variables. Previously, it was coded as
(search bar here)
if search == example:
System.out.println("You have chosen example")
etc
but now we have had to convert everything to HTML and I have no clue on how to make the if statements in this new language...
Any help is welcomed!
In your case you need to consider Java Servlet technology.
You will need to have a servlet on the server (servlet-container), and an HTML page, with JavaScript code, that makes a GET request with parameters to this servlet.
Note, that you need to encode the search string, before passing it to the server.
This servlet receives request from the client (HTML page), does the search, and prints results to the output stream.
Your JavaScript code receives server response and modifies HTML page to show the search results.
To implement client/server interaction via asynchronous requests (AJAX) consider jQuery.
Here is an example, how to make a GET request to the server: https://api.jquery.com/jquery.get/
plain sample:
$.get( "ajax/test.html", function( data ) {
$( ".result" ).html( data );
alert( "Load was performed." );
});
And there is an example, how to read GET request params in the servlet:
protected void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
String param1 = request.getParameter("param1");
String param2 = request.getParameter("param2");
}

Can we somehow change the url in addressbar after dispatching request from servlet to jsp

I am having a weird problem here, and I am really stuck, need to get this work badly.
so i have a page say index.jsp with a link say "a href=servlet?id=10". when I click on this link it will go to doGet() on my servlet and here is the code in my servlet.
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String action = request.getParameter("id");
// search database and create an arraylist
if(//user logged in)
address = "s/results.jsp";
else
address = "results.jsp";
// set arraylist in session object
RequestDispatcher dispatcher = request.getRequestDispatcher(address);
dispatcher.forward(request,response);
}
So the above code works fine but after request forwarding, my browser shows the url as
http://localhost/project/servlet?id=10.
I don't want the above url as i am forwarding to two different jsp's based on the user login status one is in 's' folder and other is outside of that.
if user is logged in then i forward to 's/results.jsp' and if user is not logged in i am forwarding to 'results.jsp'.
in case of s/results.jsp i am accessing resources like images and scripts from outside of 's' folder by using ../ in the results.jsp.
as url is not changing to s/results.jsp , i am unable to access the resources with '../'
and as i am using jsp pagination , when i click next the url is changing to s/results.jsp
and in that case i am able to access resources using ../
one solution in my mind is to copy all resources in s folder , but that would increase
redundancy.
one other solution in my mind is to create two different servlets for two jsp's
but i don't know where to put the servlet so that it can access resources outside of s folder with ../
is their any other good way i can do the task..
I have tried to find information about this but haven't been able to figure it out.
Any help will be very much appreciated.
You have basically instructed your webbrowser to send a request to exactly that URL. The forward does not change the URL. It is entirely server side. Apart from using response.sendRedirect() instead -which would trash the current request, including all of its attributes, and create a brand new request on the given URL-, you could also just change your link to <a href="results?id=10">, or when the user is logged in, to <a href="s/results?id=10">.
<a href="${user.loggedin ? 's/' : ''}results?id=10">
Finally alter the servlet mapping accordingly so that it get invoked on those URLs.
<url-pattern>/results</url-pattern>
<url-pattern>/s/results</url-pattern>
You'll only miss the JSP extension. But JSPs which are to be used by a dispatcher belong in /WEB-INF folder anyway so that they cannot be viewed by the enduser directly without invoking the servlet first. You also end up with nicer URLs.
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String action = request.getParameter("id");
// search database and create an arraylist
if(//user logged in)
address = "s/results.jsp";
else
address = "results.jsp";
// set arraylist in session object
RequestDispatcher dispatcher = request.getRequestDispatcher(address);
dispatcher.forward(request,response);
}
in the above code instead of using request dispatcher,
RequestDispatcher dispatcher = request.getRequestDispatcher(address);
dispatcher.forward(request,response);
we can try with
response.sendRedirect(request.getContextPath()+"/address");

Categories

Resources