Here is my test code, but it is not working (the cookie is not being saved).
Can someone please point what am i doing wrong and if this is the standard way to deal with cookies?
PS: If i move the part where the cookie is saved to the “init()” method, the cookie is saved, but it is not valid for me, because i need to save the cookie after the button is pressed.
Regards,
Fabiano
import javax.servlet.http.Cookie;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinServletRequest;
import com.vaadin.server.VaadinServletResponse;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
/**
* The Application's "main" class
*/
@SuppressWarnings("serial")
public class MyVaadinUI extends UI {
@Override
protected void init(VaadinRequest request) {
// Read the cookie
String test = "Cookie not found";
Cookie[] cookies = ((VaadinServletRequest) VaadinService.getCurrentRequest()).getCookies();
for (Cookie cookie : cookies)
if (cookie.getName().equals("test"))
test = cookie.getValue();
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
Button button = new Button(test);
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
layout.addComponent(new Label("Thank you for clicking"));
// Save the cookie
VaadinServletResponse response = ((VaadinServletResponse) VaadinService
.getCurrentResponse());
response.addCookie(new Cookie("test", "Cookie found"));
}
});
layout.addComponent(button);
}
}
Well, i was unable to write a cookie outside “UI.init()” method (for example, to save the “username” and the “remember me” component values when a user clicks the “login” button).
I don´t know if i’m missing something or if it is a Vaadin limitation, but i tried many solutions proposed in the forums without success.
Anyway, i found a workaround which i will post here, because it seems there are other people having the same issue.
The solution was to create a unique identifier for each client, save this identifier in a cookie in the UI.init() method and retrieve it in the next sessions, and then i can store/retrieve any sort of information using other means (for example, java Preferences, text files, etc…) using this unique identifier.
package br.com.personalsoft.TestVaadin;
import java.util.UUID;
import java.util.prefs.Preferences;
import javax.servlet.http.Cookie;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinService;
import com.vaadin.server.VaadinServletRequest;
import com.vaadin.server.VaadinServletResponse;
import com.vaadin.ui.Button;
import com.vaadin.ui.Button.ClickEvent;
import com.vaadin.ui.Label;
import com.vaadin.ui.UI;
import com.vaadin.ui.VerticalLayout;
/**
* The Application's "main" class
*/
@SuppressWarnings("serial")
public class MyVaadinUI extends UI {
private String clientId;
@Override
protected void init(VaadinRequest request) {
// Read the clientId cookie
clientId = UUID.randomUUID().toString();
Cookie[] cookies = ((VaadinServletRequest) VaadinService.getCurrentRequest()).getCookies();
for (Cookie cookie : cookies)
if (cookie.getName().equals("clientId"))
clientId = cookie.getValue();
// Write the clientId cookie
VaadinServletResponse response = ((VaadinServletResponse) VaadinService.getCurrentResponse());
response.addCookie(new Cookie("clientId", clientId));
final VerticalLayout layout = new VerticalLayout();
layout.setMargin(true);
setContent(layout);
String userName = Preferences.userRoot().node(clientId).get("userName", "admin");
boolean rememberMe = Preferences.userRoot().node(clientId).getBoolean("rememberMe", true);
Button button = new Button("Click me");
button.addClickListener(new Button.ClickListener() {
public void buttonClick(ClickEvent event) {
layout.addComponent(new Label("Thank you for clicking"));
Preferences.userRoot().node(clientId).put("userName", "otherUser");
Preferences.userRoot().node(clientId).putBoolean("rememberMe", false);
}
});
layout.addComponent(button);
}
}
Works for me perfectly. Which version of Vaadin 7 are you using? I tried that with the RC-1 on a Button.ClickEvent. Therefor I don’t need to do it in the init-Method.
I don’t know how efficient this is, I also just started using Vaadin yesterday so I definitely don’t know what I am doing. Those things aside, this works inside a Button.ClickListener.
if code in to method - public void init(VaadinRequest request) {
VaadinService.getCurrentResponse().addCookie(new Cookie(“qqqq”, “qqqq”));
}
all works !!!
but if -
public void init(VaadinRequest request) {
new Button().addClickListener(new Button.ClickListener() { @Override
public void buttonClick(Button.ClickEvent event) {
Cookie cookie= new Cookie(“www”, “www”)
cookie.setPath(VaadinService.getCurrentRequest().getContextPath());
VaadinService.getCurrentResponse().addCookie(cookie);
}
});
}
This is not working
None of the above is working for me, not including the clever-yet-horrible workaround above, which I have not been qutie desperate enough to try yet.
The use case is fairly simple:
In a Button’s ClickListener, set a cookie.
Then in UI.init(), try to read this cookie.
Like this:
final Button loginButton = new Button("Login", new ClickListener() {
@Override
public void buttonClick(final ClickEvent event) {
// …
final Cookie cookie = new Cookie(“username”, username);
cookie.setPath(VaadinService.getCurrentRequest().getContextPath());
VaadinService.getCurrentResponse().addCookie(cookie);
}
At this point, I do indeed see a cookie in my browser, but its path is “/UIDL/”. I understand that this is due to the fact that it is set from an AJAX request.
Note that it matters not a lick what argument I give to “cookie.setPath()” above, or even if I call it at all. The path will always be “/UIDL/”.
Now… I try to read the cookie from inside my UI subclass:
Viritin add-on has BrowserCookie class that should help you. It its based on similar JS haxies that you used, but at least they are hidden behind a Java API. It also allows you to read the value.
The expiration time support was added only for master and available in V8 compatible 2.0.beta2 release. Would you need a backport? I guess there is no other changes currently in queue for 7.X comptible series and would also need a different kind of code (Java 7 compatible). Maybe you could adapt the solution directly from github to your case? Or provide a pull request to V7 compatible branch with Java 7 code.