I have a spring web app. Whenever in the app, there is an error, I put the error in the error context (code given below). Then, I retrieve the error in the Exception handler and return a message. Now, say for input A, if the error message is "Person is not there" Now, for the first call to the spring web app, I get the right output: "Person is not there" however, for the second call: I get the output : "Person is not there" , "Person is not there" Thus, it is remembers my last request even though I am using a ThreadLocal. Can someone please help
My ErrorContext code:
public class ErrorContext {
private static ThreadLocal<ErrorContext> thisObj = new ThreadLocal<ErrorContext>();
/**
* List of errors.
*/
private ArrayList<ApplicationError> errorList;
/**
* Default private constructor.
*/
private ErrorContext() {
errorList = new ArrayList<ApplicationError>();
}
/**
* Initialize the ThreadLocal variable.
*/
public static void initialize() {
if (thisObj.get() == null)
thisObj.set(new ErrorContext());
else {
ErrorContext errorContext = (ErrorContext) thisObj.get();
if (errorContext.getErrors() != null)
errorContext.getErrors().clear();
}
}
/**
* Returns a new instance of the class.
*
* @return {@link ErrorContext}.
*/
public static ErrorContext getInstance() {
if (thisObj.get() == null) {
thisObj.set(new ErrorContext());
}
return (ErrorContext) thisObj.get();
}
/**
* Add the error code to the List.
*
* @param errorCode
* errorCode obtained.
*/
public void addError(final ApplicationError error) {
errorList.add(error);
}
/**
* Return the List of errorCodes.
*
* @return List of error codes.
*/
public List<ApplicationError> getErrors() {
return errorList;
}
/**
* @author anbapri resets the context.
*/
public static void resetContext() {
thisObj.set(new ErrorContext());
ErrorContext errorContext = (ErrorContext) thisObj.get();
if (errorContext.getErrors() != null)
errorContext.getErrors().clear();
}
/**
* Returns true if ErrorContext has error, otherwise false.
*
* @return
*/
public boolean hasError() {
return !errorList.isEmpty();
}
}
My Response handler
{
package com.db.wscis.core.web.handler;
import java.util.ArrayList; import java.util.List; import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus;
import com.db.wscis.core.util.exception.ApplicationError; import com.db.wscis.core.util.exception.ApplicationException; import com.db.wscis.core.util.exception.ErrorContext; import com.db.wscis.core.web.model.ApplicationErrorRes; import com.db.wscis.core.web.model.BaseResponse; import com.db.wscis.core.web.model.ResponseObject;
@ControllerAdvice public class RestExceptionProcessor {
private static final Log logger = LogFactory
.getLog(RestExceptionProcessor.class);
@Autowired
private MessageSource messageSource;
@ExceptionHandler(Exception.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND)
@ResponseBody
public ResponseObject handleException(HttpServletRequest req, Exception excpt) {
logger.error("",excpt);
// Locale locale = LocaleContextHolder.getLocale();
ResponseObject res = new ResponseObject();
// String errorMessageDesc;
res.setResultMessage("failure");
//Business validation exception
if (excpt instanceof ApplicationException) {
List<ApplicationError> errorMessages = ErrorContext.getInstance()
.getErrors();
List<ApplicationErrorRes> errorMessageRes=new ArrayList<ApplicationErrorRes>();
for(int i=0;i<errorMessages.size();i++){
ApplicationErrorRes appErrorRes= mapApplicationErrorToApplicationErrorRes(errorMessages.get(i));
errorMessageRes.add(appErrorRes);
}
res.setApplicationErrors(errorMessageRes);
}
//Other generic exception
else {
ArrayList<Exception> exceptionList=new ArrayList<Exception>();
exceptionList.add(excpt);
res.setExceptionList(exceptionList);
}
return res;
}
private ApplicationErrorRes mapApplicationErrorToApplicationErrorRes(ApplicationError appError){
ApplicationErrorRes res=new ApplicationErrorRes();
res.setErrorCode(appError.getErrorCode());
res.setErrorLevel(appError.getErrorLevel());
res.setErrorMessage(appError.getErrorMessage());
return res;
}
} }
The way to fix this is to do ErrorContext.resetContext() after the end of the exception handler.