2013-10-31 10 views
12

Nel gestore della richiesta, desidero eseguire alcune convalide e in base all'esito del controllo di convalida restituirò una risposta diversa (esito positivo/errore). Quindi creo una classe astratta per l'oggetto risposta e creo 2 sottoclassi per caso di errore e caso riuscito. Il codice ha un aspetto simile a questo, ma non viene compilato, lamentando che errorResponse e successResponse non possono essere convertiti in AbstractResponse.Spring MVC: Come restituire un diverso tipo nel corpo ResponseEntity

Sono abbastanza nuovo per Java Generico e Spring MVC quindi non conosco un modo semplice per risolvere questo problema.

@ResponseBody ResponseEntity<AbstractResponse> createUser(@RequestBody String requestBody) { 
    if(!valid(requestBody) { 
     ErrorResponse errResponse = new ErrorResponse(); 
     //populate with error information 
     return new ResponseEntity<> (errResponse, HTTPStatus.BAD_REQUEST); 
    } 
    createUser(); 
    CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse(); 
    // populate with more info 
    return new ResponseEntity<> (successResponse, HTTPSatus.OK); 
} 
+0

'CreateUserSuccessResponse' estende' AbstractResponse'? –

+0

Sì, sia CreateUserSuccessResponse che ErrorResponse estende AbstractResponse. – dnang

risposta

18

Ci sono due problemi qui:

  • il tipo di ritorno deve essere cambiato per abbinare i due risposta sottoclassi ResponseEntity<? extends AbstractResponse>
  • quando si istanzia l'ResponseEntity non è possibile utilizzare il semplificata <> sintassi devi specificare la classe di risposta che intendi utilizzare new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST);

    @ResponseBody ResponseEntity<? extends AbstractResponse> createUser(@RequestBody String requestBody) { 
        if(!valid(requestBody) { 
         ErrorResponse errResponse = new ErrorResponse(); 
         //populate with error information 
         return new ResponseEntity<ErrorResponse> (errResponse, HTTPStatus.BAD_REQUEST); 
        } 
        createUser(); 
        CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse(); 
        // populate with more info 
        return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK); 
    } 
    
9

Un altro approccio sarebbe utilizzando gestori di errori

@ResponseBody ResponseEntity<CreateUserSuccessResponse> createUser(@RequestBody String requestBody) throws UserCreationException { 
    if(!valid(requestBody) { 
     throw new UserCreationException(/* ... */) 
    } 
    createUser(); 
    CreateUserSuccessResponse successResponse = new CreateUserSuccessResponse(); 
    // populate with more info 
    return new ResponseEntity<CreateUserSuccessResponse> (successResponse, HTTPSatus.OK); 
} 

public static class UserCreationException extends Exception { 
    // define error information here 
} 

@ExceptionHandler(UserCreationException.class) 
@ResponseStatus(HttpStatus.BAD_REQUEST) 
@ResponseBody 
public ErrorResponse handle(UserCreationException e) { 
    ErrorResponse errResponse = new ErrorResponse(); 
    //populate with error information from the exception 
    return errResponse; 
} 

Questo approccio consente la possibilità di restituire qualsiasi tipo di oggetto, quindi un super classe astratta per il caso di successo e il caso di errore (o anche casi) è non è più necessario.

+0

+1, per molti casi '@ ExceptionHandler' è la scelta più pulita. Un esempio correlato che ho messo insieme per risolvere i problemi dei miei colleghi: https://gist.github.com/jonikarppinen/6ade2554946df21db0a6 – Jonik

Problemi correlati