コントローラクラスの例外処理を共通化します。
例外のハンドルは@ExceptionHandlerを付与したメソッドで行います。
これを使用することでtry-catchも少しだけ減らすことができ、コントローラクラスに複数のAPIを用意した場合に
エラー処理を共通的に記述することができます。
まずは簡単なソースを。
package spring.rest.test;
import java.sql.SQLException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExceptionController {
@RequestMapping(value="/exception", method = RequestMethod.GET)
public void exception() throws Exception {
throw new Exception();
}
/**
* SQLExceptionの例外処理
* @param e
* @throws Exception
*/
@ExceptionHandler(SQLException.class)
private void sqlExceptionHandler(Exception e) {
System.out.println("SQLException Handler");
// ここでthrow e;してもexceptionHandlerにはいかない
}
/**
* Runtime系の例外処理
*/
@ExceptionHandler(RuntimeException.class)
private void runtimeExceptionHandler(RuntimeException e) {
System.out.println("RuntimeException Handler");
}
/**
* その他のException例外処理
*/
@ExceptionHandler(Exception.class)
private void exceptionHandler(Exception e) {
System.out.println("Exception Handler");
}
}
上記の例ですと、exception()でExceptionをスローしているのでexceptionHandler()が実行されます。
ここに例外処理を記載することができます。
例えばSQLExceptionの場合だとロールバックとログ出力を行うなどなど。
これは簡単な例ですので実際には親クラスに@ExceptionHandlerを使用したエラー処理を書いておいて、
必要な場合には子クラスでオーバーライドして個別のエラー処理を書くのがいいと思います。
こんな感じでしょうか。
exceptionHandler()を子クラスでオーバーライドしなければ親クラスの
exceptionHandler()がコールされます。
BaseAbstractController.java
package spring.rest.test;
import java.util.HashMap;
import java.util.Map;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestController;
@RestController
public abstract class BaseAbstractController {
/**
* その他のExceptionの例外処理
* @param e
*/
@ExceptionHandler
protected Map<String, Object> exceptionHandler(Exception e) {
Map<String, Object> map = new HashMap<>();
map.put("basecontroller", "error");
return map;
}
}
ExceptionController.java
package spring.rest.test;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ExceptionController extends BaseAbstractController{
@RequestMapping(value="/exception", method = RequestMethod.GET)
public void exception() throws Exception {
throw new Exception();
}
/**
* SQLExceptionの例外処理
* @param e
* @throws Exception
*/
@ExceptionHandler(SQLException.class)
private void sqlExceptionHandler(Exception e) {
System.out.println("SQLException Handler");
// ここでthrow e;してもexceptionHandlerにはいかない
}
/**
* Runtime系の例外処理
*/
@ExceptionHandler(RuntimeException.class)
private void runtimeExceptionHandler(RuntimeException e) {
System.out.println("RuntimeException Handler");
}
/**
* その他のException例外処理
*/
@ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR)
@ExceptionHandler(Exception.class)
@Override
protected Map<String, Object> exceptionHandler(Exception e) {
Map<String, Object> map = new HashMap<>();
map.put("override", "error");
return map;
}
}
コメント