[Spring Batch] Implementare Spring Retry su un Controller

Rispondi
Roberto
Amministratore
Messaggi: 160
Iscritto il: 19/12/2009, 19:30

[Spring Batch] Implementare Spring Retry su un Controller

Messaggio da Roberto »

Puo' capitare a volte durante l'utilizzo di un servizio web che un server possa non rispondere per un qualunque motivo, e si vuole fare in modo che un applicativo di fronte all'impossibilita' di effettuare un'operazione riprovi a effettuarla per un numero "n" di volte prima di fallire definitivamente.

A tal proposito ci viene in aiuto Spring Retry e mostriamo di seguito un semplicissimo controller rest implementato utilizzando Spring, che non fa altro che richiamare piu' volte lo stesso metodo di fronte al generarsi di un'eccezione.

Controller:

Codice: Seleziona tutto

@RestController
public class Controller {
	
	@RequestMapping(value = "/", method = RequestMethod.GET)
	@Retryable(value = {NumberFormatException.class, NullPointerException.class}, maxAttempts = 5)
	public String myApp() {
		System.out.println("My App is calling...");
		Integer.parseInt("");
		/*
		 * String str = null;
                 * str.length();
		 */
		return "SUCCESS";
	}
	
	@Recover
	public String recover(NumberFormatException ex) {
		System.out.println("Recover method: NumberFormatException");
		return "Recover method: NumberFormatException";
	}

	@Recover
	public String recover(NullPointerException ex) {
		System.out.println("Recover method: NullPointerException");
		return "Recover method: NullPointerException";
	}

}
Main:

Codice: Seleziona tutto

@SpringBootApplication
@EnableRetry
public class AppRetry {

	public static void main(String[] args) {
		 SpringApplication.run(AppRetry.class, args);
	}

}
Come potete vedere e' tutto molto semplice e i passi degli di nota sono i seguenti:

- nel Main inseriamo l'annotazione @EnableRetry per abilitare la funzione di Retry nella nostra applicazione
- la classe Controller sara' formata da un metodo annotato come @Retryable in cui inseriamo le eccezioni che vogliamo gestire per effettuare il Retry e il numero di volte che vogliamo effettuarlo "maxAttempts"
- la classe Controller sara' formata da altri due metodi annotati con @Recover che servono per gestire per ogni eccezione, l'operazione finale da effettuare in caso si arriva al numero massimo di tentativi
- le righe di codice "Integer.parseInt("");" e "str.length();" ci servono all'occorrenza per generare una o l'altra eccezione

La dipendenza da aggiungere nel pom e' la seguente:

Codice: Seleziona tutto

	<dependency>
	    <groupId>org.springframework.retry</groupId>
	    <artifactId>spring-retry</artifactId>
	</dependency>
Allo stato attuale la versione e':

Codice: Seleziona tutto

<version>1.2.4.RELEASE</version>
Roberto
Amministratore
Messaggi: 160
Iscritto il: 19/12/2009, 19:30

[Spring Batch] Implementare Spring Retry su un Service

Messaggio da Roberto »

Riprendo l'esempio visto in precedenza ma questa volta implemento il tutto su una classe annotata Service.

Main:

Codice: Seleziona tutto

@SpringBootApplication
@EnableRetry
public class AppRetry {
	
	public static ApplicationContext ctx = null;
	
	@Autowired
	private Servizio servizio;

	public static void main(String[] args) {
		ctx = SpringApplication.run(AppRetry.class, args);
		AppRetry ar = ctx.getBean(AppRetry.class);
		ar.run(args);
	}
	
	private void run(String[] args) {
		servizio.myApp();
	}

}
Servizio:

Codice: Seleziona tutto

@Service
public class Servizio {
	
	@Retryable(value = {NumberFormatException.class, NullPointerException.class}, maxAttempts = 5)
	public void myApp() throws NumberFormatException, NullPointerException {
		System.out.println("My App is calling...");
		/* Integer.parseInt(""); */
		/*
		 * String str = null; str.length();
		 */
		throw new NumberFormatException();
		//return "SUCCESS";
	}
	
	@Recover
	public void recover(NumberFormatException ex) {
		System.out.println("Recover method: NumberFormatException");
	}

	@Recover
	public void recover(NullPointerException ex) {
		System.out.println("Recover method: NullPointerException");
	}

}
Rispondi