Expand my Community achievements bar.

SOLVED

slingHttpServletResponse.addCookie() throwing me illegalStateException with a message staying "Response is committed".

Avatar

Level 4

I'm using AEM 6.5.7 with HTL code in my component.

And I get the illegalStateException when I try to invoke the addCookie for my slingHttpServletResponse in the doPost method of my servlet.

Please find the below code snippet for the same;

 

slingHttpServletResponse.addCookie(util.updateCookie(cookieName, URLEncoder.encode(userName, "utf-8"), domainName, slingHttpServletRequest));


slingHttpServletResponse.addCookie(util.updateCookie("ssname", URLEncoder.encode(businessName, "utf-8"), domainName, slingHttpServletRequest));

 

  • updateCookie method is as follows which is returning me the cookie value without any problem in my logs.

public static final Cookie updateCookie(String cookieName, String value, String domain,
SlingHttpServletRequest request) {
Cookie cookie;
if (null == request.getCookie(cookieName)) {
LOGGER.info("Creating new cookie.");
cookie = new Cookie(cookieName, value);
} else {
LOGGER.info("Updating existing cookie.");
cookie = request.getCookie(cookieName);
}

if (null != cookie) {
LOGGER.info("cookie is not null");
cookie.setPath("/");
cookie.setDomain(domain);
}
LOGGER.info("final cookie set:::"+cookie);
return cookie;
}

Kindly help me to resolve the problem

1 Accepted Solution

Avatar

Correct answer by
Employee Advisor

This is caused by the fact, that writing a response is not an atomic operation, as one might think.

 

The servlet API (as well as the whole HTTP API) is built around streaming. It does not mandate that the server must keep the whole response in memory before the response processing is completed. This is not a problem in 99,999% of all cases, because typically you start rendering your response from the top and end at the bottom. And in the meanwhile the server already starts sending the written output back to the requester. This is efficient in terms of memory usage (the server doesn't need to buffer the complete response) and responsiveness (the response is already sent even if the rendering has not yet completed).

 

Why is it a problem here? A cookie is a value, which is added to the HTTP header. That means that at the point where you add a cookie the HTTP header (which is actually at the very beginning of response) must not have been sent yet. 

 

So you need to add your cookie as early as possible to the response. How early? Typically Servlet engines buffer 8k or 16k before they start to stream the response. If you have control of the whole response processing, you should invoke updateCookie at the top of the doPost method.

View solution in original post

4 Replies

Avatar

Community Advisor

Hi @samsundar23,

Could you please let know the high level flow of when this line - slingHttpServletResponse.addCookie is called in doPost method. 

Avatar

Level 4

Thanks to all the responses.
The problem seems to be with domain parameter in the updateCookie method which was causing all sorts of errors during addCookie.

Avatar

Community Advisor

Hi,

 

Is it possible to add the error stack and the position where the addCookie is attempted in the code (as  soon as the servlet is called or at the end.)? We can see by debugging in the servlet to find at what stage the response is going to a committed state. Starting from the doPost in the servlet the response should be in an uncommitted state. You can do a response.isCommitted()  check to avoid this error before addCookie() to start with. But you can also use same while debugging to see at what point the response is getting committed (undesirably).


Also see https://experienceleague.adobe.com/docs/experience-cloud-kcs/kbarticles/KA-16459.html?lang=es-ES if it is relevant..

Avatar

Correct answer by
Employee Advisor

This is caused by the fact, that writing a response is not an atomic operation, as one might think.

 

The servlet API (as well as the whole HTTP API) is built around streaming. It does not mandate that the server must keep the whole response in memory before the response processing is completed. This is not a problem in 99,999% of all cases, because typically you start rendering your response from the top and end at the bottom. And in the meanwhile the server already starts sending the written output back to the requester. This is efficient in terms of memory usage (the server doesn't need to buffer the complete response) and responsiveness (the response is already sent even if the rendering has not yet completed).

 

Why is it a problem here? A cookie is a value, which is added to the HTTP header. That means that at the point where you add a cookie the HTTP header (which is actually at the very beginning of response) must not have been sent yet. 

 

So you need to add your cookie as early as possible to the response. How early? Typically Servlet engines buffer 8k or 16k before they start to stream the response. If you have control of the whole response processing, you should invoke updateCookie at the top of the doPost method.