How do I delete a cookie by its value?
In my.jsp page I am setting the cookie
String timeStamp = new SimpleDateFormat("dd:MM:yyyy_HH:mm:ss:SSS").format(Calendar.getInstance().getTime());
timeStamp = timeStamp + ":" + System.nanoTime();
String loc = "/u/poolla/workspace/FirstServlet/WebContent/WEB-INF/"+timeStamp;
Cookie cookie = new Cookie("path", loc);
Multiple users will have cookies with the same name but different loc values,
So, How do I get the cookie value in servlet.java and delete a particular loca value cookie??
Cookies are not same for each user. Generally cookies are tied to the client/user/browser which is accessing the JSP/application and each client can have a cookie value of its own.
When you delete a cookie you just delete it for the client which has made the request to your application. Rest of the clients will still have their own cookie without any effect in the value. Hence, you need not to worry about deleting a cookie may affect multiple users.
In order to delete a cookie, first get all the cookies from request and delete the cookie which has particular name/value.
public void delete(MyType instance) {
Cookie[] cookies = request.getCookies();
if (cookies != null) {
for (Cookie cookie : cookies) {
if (cookie.getName().equals("test")) {
cookie.setValue(null);
cookie.setMaxAge(0);
cookie.setPath(theSamePathAsYouUsedBeforeIfAny);
response.addCookie(cookie);
}
}
}
}
You will need to call getCookies() on the request and loop through them until you find the one you're looking for.
here is a little simple example tha might help you
//declaring a cookie
Cookie cookie = new Cookie(name, value);
//getting the cookie name
String name = cookie.getName()
//getting the cookie value
String value= cookie.getValue();
Related
I am sending cookie from a client in Rest API request and I want to read on a filter. I am using this code on the filter for retrieving the cookies.
Map<String, Cookie> cookies = requestContext.getCookies();
Cookie cookie = cookies.get("token");
String token = cookie.getValue();
But it returns null. Can anyone suggest me how can I retrive cookie on filter.
In order to retrieve your cookie, you should do the following:
for (Cookie c : requestContext.getCookies().values())
{
if (c.getName().equals("token")) {
cookie = c;
break;
}
}
Honestly, I don't know why you could not retrieve your cookie by its key, since the ContainerRequestContext documentation states that getCookies returns
a read-only map of cookie name (String) to Cookie.
In my application I have a dropdownlist and when the user clicks on an item is redirects them to a certain page. In this servlet I create a cookie with there selected item which contains the value of the drop-down list(So when they return the the previous page that item will be selected in the drop-down list)
What I want to know different values may be selected at different times it there a way to modify the cookie for that drop-down list or do I have to create a new one each time. I cant see that as being a sustainable way of doing it?
You can edit the cookie by getting it from the request and assigning the new value:
Cookie[] cookies = request.getCookies();
Cookie dropDownCookie = null;
for (Cookie cookie : cookies) {
if(cookie.getName().equals("DROP_DOWN_COOKIE")){
dropDownCookie = cookie;
}
}
if(dropDownCookie!=null){
dropDownCookie.setValue("THE NEW VALUE");
response.addCookie(dropDownCookie);
}
Consider a situation where tomcat server receives multiple cookies with name JSessionID out of which one JSessionID is valid, so tomcat will still return a session or not? If tomcat reads only first JSessionID and maps with stored sessions then it may not find valid sesison and may store null. But if tomcat reads all cookies with name JSessionID and checks for existence of session against each JSessionID then it will return valid session. Sometimes we have observed that browser sends two cookies with same name one which is recently authentication session and one some old cookie with stale value. Hence the query to know how tomcat behaves?
From the code in tomcat source, a jsessionid cookie will override a jsessionid in the query (provided the context allow to use cookie for session tracking).
If multiple jsessionid cookies are present the first one representing a valid session (for the considered context) will be taken.
see Tomcat 7.0.x CoyoteAdapter class :
/**
* Parse session id in URL.
*/
protected void parseSessionCookiesId(org.apache.coyote.Request req, Request request) {
// If session tracking via cookies has been disabled for the current
// context, don't go looking for a session ID in a cookie as a cookie
// from a parent context with a session ID may be present which would
// overwrite the valid session ID encoded in the URL
Context context = (Context) request.getMappingData().context;
if (context != null && !context.getServletContext()
.getEffectiveSessionTrackingModes().contains(
SessionTrackingMode.COOKIE)) {
return;
}
// Parse session id from cookies
Cookies serverCookies = req.getCookies();
int count = serverCookies.getCookieCount();
if (count <= 0) {
return;
}
String sessionCookieName = SessionConfig.getSessionCookieName(context);
for (int i = 0; i < count; i++) {
ServerCookie scookie = serverCookies.getCookie(i);
if (scookie.getName().equals(sessionCookieName)) {
// Override anything requested in the URL
if (!request.isRequestedSessionIdFromCookie()) {
// Accept only the first session id cookie
convertMB(scookie.getValue());
request.setRequestedSessionId
(scookie.getValue().toString());
request.setRequestedSessionCookie(true);
request.setRequestedSessionURL(false);
if (log.isDebugEnabled()) {
log.debug(" Requested cookie session id is " +
request.getRequestedSessionId());
}
} else {
if (!request.isRequestedSessionIdValid()) {
// Replace the session id until one is valid
convertMB(scookie.getValue());
request.setRequestedSessionId
(scookie.getValue().toString());
}
}
}
}
}
i am setting cookie in context A and trying to get in context B in same domain . I am writing this code ....
Cookie cook= new Cookie("Name","value");
cook.setPath("/");
cook.setDomain(".foo.com");
response.addCookie(cook);
what is wrong here ? This is how i am getting the cookie in another context ..please note that my code is working fine in same context
Cookie cookie = null;
Cookie[] cookies = null;
cookies = request.getCookies();
out.println(cookies);
for (int i = 0; i < cookies.length; i++){
cookie = cookies[i];
if("Name".equals(cookie.getName( ))){
out.println("Name : " + cookie.getName( ) + ", ");
out.println("Value: " + cookie.getValue( )+" <br/>");
}}
Try to give the cookie a lifetime.
cookie.setMaxAge(86400) // 24h
A cookie without lifetime is bound to the browsing session. You might be in a different session when browsing in a different context.
I'm trying to enable SSO under Tomcat such that users who go to http://mydomain.com and http://www.mydomain.com will have their session cookie available for requests made to http://subdomain.mydomain.com. All three of these domains go to the same webapp, so ideally I'd like to not mess with SSO at all and just set the domain on the standard JSESSIONID cookie.
However, that doesn't seem possible, so I'm trying to enable Tomcat's SSO Valve. The problem is that the Valve requires a definition of a Realm, and a Realm is supposed to specify a database of users and roles. However, I am not using container-based authentication nor role-based authorization, so I do not need or want to configure a Realm. All I want is for the session cookie(s) to be able to be shared across each of these different subdomains.
Is there any straightforward way to do this?
Edit
My current workaround for this is to have the server redirect every incoming request to the "canonical" server name. This works well enough, but obviously it is not actually solving the problem.
We were having the same problem and created a Tomcat Valve that would overwrite or set the Domain part of the session Cookie. Quite a simple thing and it already works for many years. The code goes like this:
public class CrossSubdomainSessionValve extends ValveBase {
public CrossSubdomainSessionValve() {
super();
info = "common-tomcat-CrossSubdomainSessionValve";
}
#Override
public void invoke(Request request, Response response) throws IOException, ServletException {
// cookie will only need to be changed, if this session is created by this request.
if (request.getSession(true).isNew()) {
Cookie sessionCookie = findSessionCookie(response.getCookies());
if (sessionCookie != null) {
String cookieDomainToSet = getCookieDomainToSet(request.getServerName());
if (cookieDomainToSet != null) {
// changing the cookie only does not help, because tomcat immediately sets
// a string representation of this cookie as MimeHeader, thus we also
// have to change this representation
replaceCookie(response.getCoyoteResponse().getMimeHeaders(), sessionCookie, cookieDomainToSet);
}
}
}
// process the next valve
getNext().invoke(request, response);
}
protected Cookie findSessionCookie(Cookie[] cookies) {
if (cookies != null)
for (Cookie cookie : cookies)
if (Globals.SESSION_COOKIE_NAME.equals(cookie.getName())) {
return cookie;
return null;
}
protected void replaceCookie(MimeHeaders headers, Cookie originalCookie, String domainToSet) {
// if the response has already been committed, our replacementstrategy will have no effect
// find the Set-Cookie header for the existing cookie and replace its value with new cookie
for (int i = 0, size = headers.size(); i < size; i++) {
if (headers.getName(i).equals("Set-Cookie")) {
MessageBytes value = headers.getValue(i);
if (value.indexOf(originalCookie.getName()) >= 0) {
if (originalCookie.getDomain() == null) {
StringBuilder builder = new StringBuilder(value.getString()).append("; Domain=").append(domainToSet);
value.setString(builder.toString());
} else {
String newDomain = value.getString().replaceAll("Domain=[A-Za-z0-9.-]*", "Domain=" + domainToSet);
value.setString(newDomain);
}
}
}
}
}
protected String getCookieDomainToSet(String cookieDomain) {
String[] parts = cookieDomain.split("\\.");
if (parts.length >= 3) {
return "." + parts[parts.length - 2] + "." + parts[parts.length - 1];
}
return null;
}
public String toString() {
return ("CrossSubdomainSessionValve[container=" + container.getName() + ']');
}
}
The algorithm works like this:
- Only if the session is new - find the session cookie
- Get the requested host name
- Split the host name with '.'
- If it has at least 3 parts (like www.google.de), remove first part (to .google.de)
- Reset the cookie
In your Context configuration you can apply the valve like this
<Valve className="my.package.CrossSubdomainSessionValve" httpOnlyEnabled="true" />
Caveat: In the code the Valve creates a session if no session was created before and does not care if you need a session at all...
Hope that helps... Good luck!