2016-07-19 5 views
3

Ich benutze @ControllerAdvice alle Ausnahmen meine app zu behandeln:Order of @ExceptionHandler

@ControllerAdvice 
public class ExceptionHandlingController { 

    @ExceptionHandler({UnauthorizedException.class}) 
    public String unauthorizedException() { 
     ......... 
    } 


    @ExceptionHandler({UnauthorizedAjaxException.class}) 
    @ResponseBody 
    public void unauthorizedAjaxException() { 
     ......... 
    } 

    @ExceptionHandler({Exception.class}) 
    public String globalException(){ 
     ......... 
    } 


} 

Und irgendwo in meinem Code ich tun throw new UnauthorizedException();

@Around("@annotation(Authenticated)") 
    public Object profilingAuthentication(ProceedingJoinPoint pjp) throws Throwable { 

     HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.currentRequestAttributes()).getRequest(); 

     if(request.getSession().getAttribute("idContact") == null) { 
      if("XMLHttpRequest".equals(request.getHeader("X-Requested-With"))) 
       throw new UnauthorizedAjaxException(); 
      throw new UnauthorizedException(); 
     } 
     return pjp.proceed(); 
    } 

Aber leider Spring MVC scheint zufällig zu handeln, indem Sie der allgemeinste Fall (Exception) eher als spezifischere (UnauthorizedException zum Beispiel). Und manchmal wählt er den richtigen!

Wie funktioniert der Auftrag? und gibt es eine Möglichkeit, die Reihenfolge anzugeben?

UnauthorizedException ist eine benutzerdefinierte Ausnahme

public class UnauthorizedException extends Exception { 

    public UnauthorizedException(){ 
     super(); 
    } 

    public UnauthorizedException(String message){ 
     super(message); 
    } 
} 

UPDATE

i, dass der Auftrag es ist nicht tatsächlich die Methoden herausgefunden Rondom die UnauthorizedException Werke normalerweise werfen, aber die anderen nicht!

@Authenticated 
@RequestMapping(value="/favoris") 
public String favoris(ModelMap model, HttpServletRequest request) 
     throws UnauthorizedException { 
    .... 
} 

@Authenticated 
@RequestMapping(value="/follow") 
public String follow(ModelMap model, HttpServletRequest request) { 
    ..... 
} 

So habe ich throws UnauthorizedException manuell hinzuzufügen, oder gibt es eine andere Lösung?

Antwort

-1

Es gibt keine Reihenfolge/Priorität, solange Sie in Ihrem Projekt eine einzelne Controller-Dienstklasse haben. Wenn Sie jedoch mehrere controleradvice-Klassen haben, können Sie die Reihenfolge festlegen. In diesem Fall ist die Reihenfolge jedoch nicht anwendbar, da die beiden Ausnahmen unterschiedlich behandelt werden (d. H. UnauthorizedException und Exception).

Die gute Sache ist, Frühling wird automatisch die entsprechende benutzerdefinierte Exception-Klasse finden (falls vorhanden, sonst generische Exception) und die entsprechende Methode aufrufen.

Bitte beachten Sie für weitere Informationen zur Spring-Controller Beratung und Ausnahmebehandlung: https://spring.io/blog/2013/11/01/exception-handling-in-spring-mvc

+0

Schlägst du vor, sie sollten einen einzigen 'ExceptionHandler' für ihre Anwendung haben? –

+0

Ich schlage NICHT vor, einen einzigen ExceptionHandler zu haben. – developer

+0

Können Sie klären, wie _Sie den Auftrag_ setzen können? Ich denke, das ist es, was sie fragen. –

0

wir Exception-Handler verwenden Art und Weise in der folgenden Auftrag nie gemischt zu bekommen und es wie erwartet. So könnte es möglich sein, wenn Sie es als folgendes Beispiel verwenden werden, dann wird es Ihre Probleme

********** Handler-Klasse lösen ************** ****

@ControllerAdvice 
public class GlobalExceptionHandler { 

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) 
    @ExceptionHandler(value = Exception.class) 
    public boolean handle1(Exception exc) { 
     System.out.println("#####Global Exception###" + exc); 
     exc.printStackTrace(System.out); 
     return true; 
    } 

    @ResponseStatus(value = HttpStatus.INTERNAL_SERVER_ERROR) 
    @ExceptionHandler(value = CustomException.class) 
    public boolean handle2(CustomException exc) { 
     System.out.println("###custom exception######" + exc); 
     exc.printStackTrace(System.out); 
     return true; 
    } 
} 

*************** Controller-Klasse ************

@RestController("test") 
@RequestMapping("/test1") 
public class TestController { 

    @RequestMapping("/t1") 
    public boolean test() { 
     if (true) { 
      throw new CustomException(); 
     } 
     return true; 
    } 
} 

In obigem Beispiel Ausnahme habdler ist handle2, weil es zuerst nach übereinstimmender Ausnahme suchen wird, wenn nicht gefunden, dann gehen Sie für Parrent Handler

Wenn wir neue Nullpointer werfen(), dann wird es für passende Handler suchen, aber nicht in diesem Fall dann gehen für parrent gefunden Handle1

für mehr Sie here

beziehen Ich hoffe, es ist wird dir helfen. Danke

+0

leider hat es nicht funktioniert – Youssef