27 votes

Spring 3 - Création d'un ExceptionHandler pour NoSuchRequestHandlingMethodException

En utilisant Spring 3, j'aime créer un gestionnaire d'exception en utilisant la fonction Gestionnaire d'exceptions qui traitera "aucune page trouvée (404)" demandes. J'utilise le code suivant pour ce faire. Mais lorsque je pointe vers une URL qui n'existe pas, le gestionnaire d'exception par défaut défini par Spring est invoqué.

C'est peut-être que je manipule le NoSuchRequestHandlingMethodException exception. Si c'est le cas, alors quelle exception dois-je enregistrer ?

Pourriez-vous jeter un coup d'œil au code suivant et voir ce que je fais de mal ?

NOTE : Si je modifie l'exception dans le @ExceptionHandler à NullPointerException et créer un RequestMapping pour lancer un pointeur nul, cela fonctionnera.

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RequestMapping;

    import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

    import org.apache.commons.logging.Log;
    import org.apache.commons.logging.LogFactory;
    import org.springframework.web.servlet.ModelAndView;

    @Controller
    public class GeneralHandler {
      private final Log logger = LogFactory.getLog(getClass());

      @ExceptionHandler(NoSuchRequestHandlingMethodException.class)
      public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
        ModelAndView mav = new ModelAndView();
        logger.error("Exception found: " + ex);
        return mav;
      }
    }

40voto

skaffman Points 197885

@ExceptionHandler -Les méthodes annotées sont invoquées lorsqu'une @RequestMapping sur cette même classe lève une exception. Ainsi, lorsque vous avez ajouté le mappage qui a lancé l'exception NullPointerException Cela a fonctionné, puisque la méthode mappée et le gestionnaire d'exception se trouvaient dans la même classe.

Lorsqu'aucune correspondance n'est trouvée, Spring n'a aucun moyen d'associer l'objet de l'enquête à l'objet de l'enquête. NoSuchRequestHandlingMethodException avec votre @ExceptionHandler parce qu'il n'est pas allé jusqu'à faire correspondre la demande à une méthode de traitement. Cela n'est pas mentionné explicitement dans la documentation, mais c'est le comportement que j'ai observé.

Si vous souhaitez traiter cette exception de manière spécifique, vous devrez utiliser la fonction plus générale HandlerExceptionResolver approche plutôt que le plus spécialisé @ExceptionHandler technique.

16voto

Janning Points 2079

Dans Spring 3.2, vous pouvez utiliser @ContollerAdvice d'avoir un ExceptionHandler pour tous vos contrôleurs comme celui-ci :

@ControllerAdvice
public class GeneralHandler {

   @ExceptionHandler
   public ModelAndView handleException (NoSuchRequestHandlingMethodException ex) {
        ModelAndView mav = new ModelAndView();
        ...
        return mav;
   }
}

Vous pouvez même ajouter des annotations supplémentaires pour renvoyer du json sérialisé.

@ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public RestError resolveBindingException ( MethodArgumentNotValidException methodArgumentNotValidException, Locale locale )
    {
        BindingResult bindingResult = methodArgumentNotValidException.getBindingResult();
        return getRestError(bindingResult, locale);
    }

2voto

Sloin Points 6086

Vous pourriez aller avec ce approche, c'est une excellente idée et cela fonctionne, mais la nécessité de lancer des exceptions uniquement avec un gestionnaire particulier rend @ExceptionHandler moins utile qu'il n'y paraît.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X