Issue
I have a CookieFilter class that overrides doFilter method to set a Cookie before my Rest service is invoked:
import javax.servlet.*;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.UUID;
public class CookieFilter implements Filter {
@Override
public void init(FilterConfig config) throws ServletException {}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletResponse httpResponse = (HttpServletResponse) response;
if (notPresent("TEST")) {
String uuid = UUID.randomUUID().toString();
httpResponse.addCookie(new Cookie("TEST", uuid));
}
chain.doFilter(request, response);
}
@Override
public void destroy() {}
private boolean notPresent(String cookieName) {
// here are the checks
}
}
Rest service method:
void myRestServiceMethod(@Context HttpServletRequest request) {
Cookie[] cookies = request.getCookies(); // has my cookie inside after second call
// other logic bellow
}
myRestServiceMethod is called after doFilter but Cookie is not present.
However, I am able to read the cookie (using JAX-RS @Context to retrieve HttpServletRequest object) in second client call to myRestServiceMethod where Cookie (set in a first call) is sent from the client and passed to the server.
My question is: is there a way read the Cookie in a first call to myRestServiceMethod after its set in doFilter?
Solution
is there a way read the Cookie in a first call to myRestServiceMethod after its set in doFilter?
No.
There are 2 solutions:
Refresh the request after adding cookie.
if (notPresent("TEST")) { String uuid = UUID.randomUUID().toString(); httpResponse.addCookie(new Cookie("TEST", uuid)); httpRequest.sendRedirect(httpRequest.getRequestURI()); // NOTE: you might want to add query string if necessary. } else { chain.doFilter(request, response); }
Or, better, store it as request attribute.
String uuid = getCookieValue("TEST"); if (uuid == null) { uuid = UUID.randomUUID().toString(); httpResponse.addCookie(new Cookie("TEST", uuid)); } request.setAttribute("TEST", uuid); chain.doFilter(request, response);
So that you can simply do this.
String uuid = (String) request.getAttribute("TEST");
If CDI is available in the environment, you could populate a
@RequestScoped
bean instead.
That said, it's strange to have a JAX-RS service to (indirectly) deal with cookies. REST is never intented to be stateful.
Answered By - BalusC
Answer Checked By - Terry (JavaFixing Volunteer)