Java.lang.IllegalStateException: не найден запрос на привязку к потоку, исключение в аспекте
Вот мой аспект:
@Configurable
@Aspect
public class TimingAspect {
@Autowired
private HttpServletRequest httpServletRequest;
// Generic performance logger for any mothod
private Object logPerfomanceInfo(ProceedingJoinPoint joinPoint, String remoteAddress) {
StringBuilder tag = new StringBuilder();
if (joinPoint.getTarget() != null) {
tag.append(joinPoint.getTarget().getClass().getName());
tag.append(".");
}
tag.append(joinPoint.getSignature().getName());
StopWatch stopWatch = new StopWatch(tag.toString());
Object result = joinPoint.proceed(); // continue on the intercepted method
stopWatch.stop();
PerformanceUtils.logInPerf4jFormat(stopWatch.getStartTime(), stopWatch.getElapsedTime(), stopWatch.getTag(), stopWatch.getMessage(), remoteAddress);
return result;
}
@Around("execution(* $$$.$$$.$$$.api.controller.*.*(..))")
public Object logAroundApis(ProceedingJoinPoint joinPoint) throws Throwable {
String remoteAddress = null;
if (httpServletRequest != null) {
remoteAddress = httpServletRequest.getRemoteAddr();
}
return logPerfomanceInfo(joinPoint, remoteAddress);
}
@Around("execution(* $$$.$$$.$$$.$$$.$$$.$$$.*(..))")
public Object logAroundService(ProceedingJoinPoint joinPoint) throws Throwable {
String remoteAddress = null;
if (httpServletRequest != null) {
remoteAddress = httpServletRequest.getRemoteAddr();
}
return logPerfomanceInfo(joinPoint, remoteAddress);
}
У меня нет ошибок времени компиляции, но я делаю следующее исключение, когда я запускаю свой сервер причала:
Вложенное исключение - это java.lang.IllegalStateException: Нет связанного с потоком запрос: вы ссылаетесь на атрибуты запроса за пределами фактический веб-запрос или обработка запроса за пределами первоначально принимающая нить? Если вы действительно работаете в веб-запросе и все еще получать это сообщение, ваш код, вероятно, работает за пределами DispatcherServlet/DispatcherPortlet: В этом случае используйте RequestContextListener или RequestContextFilter для отображения текущей запрос.
Следует отметить, что если я удалю метод logAroundService, я не получаю никаких исключений.
Ответы
Ответ 1
Вы не должны автоопределять HttpServletRequest
в своем аспекте, так как это свяжет ваш аспект только для классов, вызываемых из исполняемого HttpServletRequest
.
Вместо этого используйте RequestContextHolder
, чтобы получить запрос, когда вам это нужно.
private String getRemoteAddress() {
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (attribs instanceof NativeWebRequest) {
HttpServletRequest request = (HttpServletRequest) ((NativeWebRequest) attribs).getNativeRequest();
return request.getRemoteAddr();
}
return null;
}
Ответ 2
Как сказано в сообщении об ошибке: В этом случае используйте RequestContextListener или RequestContextFilter для отображения текущего запроса.
Чтобы исправить это, зарегистрируйте прослушиватель RequestContextListener в файле web.xml.
<web-app ...>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
</web-app>
Ответ 3
@M. Ответ на Deinum не работает для меня. Вместо этого я использую этот код
RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (RequestContextHolder.getRequestAttributes() != null) {
HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
return request.getRemoteAddr();
}
Ответ 4
С помощью выражения pointcut вы в основном проксируете каждый bean и применяете этот совет. Некоторые beans существуют и работают вне контекста HttpServletRequest
. Это означает, что он не может быть восстановлен.
Вы можете вводить HttpServletRequest
только те места, где проходит поток обработки запроса сервлетов.