Taking answers from @Nicola and @Victor Wing and adding a more standardized way:
import org.springframework.beans.factory.InitializingBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.http.server.ServletServerHttpResponse;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.AuthenticationEntryPoint;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class UnauthorizedErrorAuthenticationEntryPoint implements AuthenticationEntryPoint, InitializingBean {
private HttpMessageConverter messageConverter;
@SuppressWarnings("unchecked")
@Override
public void commence(HttpServletRequest request, HttpServletResponse response, AuthenticationException exception) throws IOException, ServletException {
MyGenericError error = new MyGenericError();
error.setDescription(exception.getMessage());
ServerHttpResponse outputMessage = new ServletServerHttpResponse(response);
outputMessage.setStatusCode(HttpStatus.UNAUTHORIZED);
messageConverter.write(error, null, outputMessage);
}
public void setMessageConverter(HttpMessageConverter messageConverter) {
this.messageConverter = messageConverter;
}
@Override
public void afterPropertiesSet() throws Exception {
if (messageConverter == null) {
throw new IllegalArgumentException("Property 'messageConverter' is required");
}
}
}
Now, you can inject configured Jackson, Jaxb or whatever you use to convert response bodies on your MVC annotation or XML based configuration with its serializers, deserializers and so on.