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.
Related
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¶m2=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>");
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.
There are different methods to create cookies in HttpClient, I am confused which one is the best.
I need to create,retrieve and modify cookies.
For example , I can use the following code to see a list of cookies and modify them but how to create them ?
Is this a proper method for retrieving them? I need them to be accessible in all classes.
In addition methods that I have found usually require httpresponse, httprequest objects to send the cookie to browser, but how about if I do not want to use them?
Code
import org.apache.commons.httpclient.Cookie;
import org.apache.commons.httpclient.HttpState;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
public class GetCookiePrintAndSetValue {
public static void main(String args[]) throws Exception {
HttpClient client = new HttpClient();
client.getParams().setParameter("http.useragent", "My Browser");
GetMethod method = new GetMethod("http://localhost:8080/");
try{
client.executeMethod(method);
Cookie[] cookies = client.getState().getCookies();
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
System.err.println(
"Cookie: " + cookie.getName() +
", Value: " + cookie.getValue() +
", IsPersistent?: " + cookie.isPersistent() +
", Expiry Date: " + cookie.getExpiryDate() +
", Comment: " + cookie.getComment());
cookie.setValue("My own value");
}
client.executeMethod(method);
} catch(Exception e) {
System.err.println(e);
} finally {
method.releaseConnection();
}
}
}
AND I've tried to create a cookie using following code but it does not
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.GetMethod;
....
public String execute() {
try{
System.err.println("Creating the cookie");
HttpClient httpclient = new HttpClient();
httpclient.getParams().setParameter("http.useragent", "My Browser");
GetMethod method = new GetMethod("http://localhost:8080/");
httpclient.executeMethod(method);
org.apache.commons.httpclient.Cookie cookie = new
org.apache.commons.httpclient.Cookie();
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");
cookie.setDomain("localhost");
httpclient.getState().addCookie(cookie);
httpclient.executeMethod(method);
System.err.println("cookie");
}catch(Exception e){
e.printStackTrace();
}
Output is as following but no cookie will be created.
SEVERE: Creating the cookie
SEVERE: cookie
Scenario
1)User has access to a form to search for products (example.com/Search/Products)
2)User fills up the form and submit it to class Search
3)Form will be submitted to Search class
4)Method Products of Search class returns and shows the description of product
(example.com/Search/Products)
5)User clicks on "more" button for more description about product
6)Request will be sent to Product class (example.com/Product/Description?id=4)
7)User clicks on "add to cookie" button to add the product id to the cookie
Product class is subclasse of another class. So it can not extend any more class.
In the second example, you are creating a new client-side cookie (i.e. you are impersonating a browser and are sending the cookie to the server).
This means that you need to provide all the relevant information, so that the client can decide whether to send the cookie to the server or not.
In your code you correctly set the path,name and value, but the domain information is missing.
org.apache.commons.httpclient.Cookie cookie
= new org.apache.commons.httpclient.Cookie();
cookie.setDomain("localhost");
cookie.setPath("/");
cookie.setName("Tim");
cookie.setValue("Tim");
This works if what you are trying to achieve is to send a cookie to an http server.
Your second example, though, spans from an execute method, an since you are hinting at struts2 in your tag, maybe the class containing it is meant to be a struts2 Action.
If this is the case, what you are trying to achieve is to send a new cookie to a browser.
The first approach is to get hold of a HttpServletResponse as in:
So your Action must look like:
public class SetCookieAction
implements ServletResponseAware // needed to access the
// HttpServletResponse
{
HttpServletResponse servletResponse;
public String execute() {
// Create the cookie
Cookie div = new Cookie("Tim", "Tim");
div.setMaxAge(3600); // lasts one hour
servletResponse.addCookie(div);
return "success";
}
public void setServletResponse(HttpServletResponse servletResponse) {
this.servletResponse = servletResponse;
}
}
Another approach (without HttpServletResponse) could be obtained using the CookieProviderInterceptor.
Enable it in struts.xml
<action ... >
<interceptor-ref name="defaultStack"/>
<interceptor-ref name="cookieProvider"/>
...
</action>
then implement CookieProvider as:
public class SetCookieAction
implements CookieProvider // needed to provide the coookies
{
Set<javax.servlet.http.Cookie> cookies=
new HashSet<javax.servlet.http.Cookie>();
public Set<javax.servlet.http.Cookie> getCookies()
{
return cookies;
}
public String execute() {
// Create the cookie
javax.servlet.http.Cookie div =
new javax.servlet.http.Cookie("Tim", "Tim");
div.setMaxAge(3600); // lasts one hour
cookies.put(cookie)
return "success";
}
}
(credits to #RomanC for pointing out this solution)
If you subsequently need to read it you have two options:
implement ServletRequestAware in your Action and read the cookies from the HttpServletRequest
introduce a CookieInterceptor and implement CookiesAware in your Action, the method setCookieMap allows to read the cookies.
Here you can find some relevant info:
Using cookies with Struts 2 and Struts
First of all you propably do not want to use HttpClient, which is a client (e.g. emulates a browser) and not a server (which can create cookies, that the user's browser will store).
That said, I'm first explaining what happens in your first code example:
You send a GET request to a server
The server sends you some cookies alongside it's response (the content)
You modify the cookies in your HttpClient instance
You send those cookies back to the server
What the server does with your changed cookies entirely depends on what that server is programmed to do
At the next request the server might send those changed cookies back to you or not, which as I allraedy said depends on what it is programmed to do.
As for you second example:
You create a cookie
You set some information on the cookie
You send the cookie to the server (inside your GET request)
The server now does with your cookie what it is programmed to do with it. Propably the server ignores your cookie (e.g. does not send it back to you).
On the other hand what you propably want to do is write a web application (e.g. the server side), that creates the cookie and changes it depending on the client's input (the browser).
For that you can use the Servlet API. Something along the lines:
javax.servlet.http.Cookie cookie = new
javax.servlet.http.Cookie("your cookie's name", "your cookie's value");
//response has type javax.servlet.http.HttpServletResponse
response.addCookie(cookie);
Creating a web application is way out of scope of a simple stackoverflow answer, but there are many good tutorials out there in the web.
There is no way around creating a web application if the user should use a browser to see your products. There are just different ways to create one, different frameworks. The servlet API (e.g. HttpServletResponse and HttpServletResponse) is the most basic one.
I'd say it (the servlet API) is also the easiest one you can find to solve this exact problem with java, even though it is not exactly easy to get started with web applications at all.
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...
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");