web-dev-qa-db-fra.com

java.lang.IllegalStateException: aucune demande liée à un thread n'a été trouvée, exception dans l'aspect

Voici mon aspect:

    @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);
        }

Je ne reçois aucune erreur de compilation mais je fais exception suivante au démarrage de mon serveur Jetty:

l'exception imbriquée est Java.lang.IllegalStateException: aucune thread liée request found: Faites-vous référence à des attributs de requête extérieurs à un demande Web réelle, ou traitement d'une demande en dehors de l'origine recevoir le fil? Si vous opérez réellement dans une requête Web et toujours recevoir ce message, votre code est probablement en cours d'exécution à l'extérieur of DispatcherServlet/DispatcherPortlet: Dans ce cas, utilisez RequestContextListener ou RequestContextFilter pour exposer le fichier .__ actuel. demande.

Une chose à noter ici, si je supprime la méthode "logAroundService", je n’obtiens aucune exception.

12
riship89

Vous ne devez pas autoriser automatiquement une HttpServletRequest dans votre aspect, car cela liera votre aspect pour qu'il ne puisse être exécuté que pour les classes appelées depuis une HttpServletRequest en cours d'exécution. 

Utilisez plutôt la RequestContextHolder pour obtenir la demande lorsque vous en avez besoin.

private String getRemoteAddress() {
    RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
    if (attribs instanceof NativeWebRequest) {
        HttpServletRequest request = (HttpServletRequest) ((NativeWebRequest) attribs).getNativeRequest();
        return request.getRemoteAddr();
    }
    return null;
}
13
M. Deinum

@M. La réponse Deinum ne fonctionne pas pour moi. J'utilise ces codes à la place 

RequestAttributes attribs = RequestContextHolder.getRequestAttributes();
if (RequestContextHolder.getRequestAttributes() != null) {
    HttpServletRequest request = ((ServletRequestAttributes) attributes).getRequest();
    return request.getRemoteAddr();
}
5
user1686407

Comme le message d'erreur le disait: Dans ce cas, utilisez RequestContextListener ou RequestContextFilter pour exposer la demande en cours.

Pour résoudre ce problème, enregistrez un écouteur RequestContextListener dans le fichier web.xml.

<web-app ...>
   <listener>
    <listener-class>
        org.springframework.web.context.request.RequestContextListener
    </listener-class>
   </listener>
</web-app>
4
Nicholas Lu

Avec votre expression en points coupés, vous analysez fondamentalement chaque grain et appliquez ce conseil. Certains haricots existent et fonctionnent en dehors du contexte d'une HttpServletRequest. Cela signifie qu'il ne peut pas être récupéré. 

Vous pouvez uniquement injecter la HttpServletRequest aux endroits où un thread de traitement de demande de conteneur Servlet passera.

0