iT邦幫忙

DAY 16
0

無痛學習SpringMVC與Spring Security系列 第 16

[Controller]使用@ExceptionHandler自行定義錯誤訊息網頁

昨日的程式沒有跑出來最後發現是我自己超連結網址打錯,不是程式錯誤,上一篇已更新,今天來分享@ExceptionHandler的用途。

不管是開發的時候或是遇到使用者非預期的存取web應用程式未定義的功能或是找不到網頁等等HTTP Error的時候,常見的錯誤HTTP Status Error Code如500(Internal Server Error), 404(Not Found), 406(Media Type Not Acceptable),Tomcat的標準網頁都長得很醜,Spring MVC中@ExceptionHandler就是來協助開發者自行定義錯誤訊息網頁,@ExceptionHandler接受的參數為繼承xxxxException的class,例如@ExceptionHandler(IOException.class),今天要分享的是存取一個在資料庫不存在的紀錄,因為此操作在Web已經初始化完成了,故屬於Runtime Exception,因此首先先新增DCNNotFouncException.class於tw.blogger.springtech.springmvc.controller.exception下並繼承RuntimeException,接著需要在class level上宣告@ResponseStatus,這個annotation會向DispatcherServlet註冊ResponseStatusExceptionResolver,簡單說就是告訴DispatchSerlvet某些HTTP Exception的資訊由此class提供,@ResponseStatus參數value要指定這個class要處理哪一個HTTP Status Error Code, 參數Reason對應到錯誤訊息的字串,另外我們需要在這個class宣告產生Exception的相關參數,以及產生對應的getter方法,以便Controller裡可以存取exception有關的參數,其code如下

import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.ResponseStatus;

@ResponseStatus(value=HttpStatus.INTERNAL_SERVER_ERROR, reason="No DCN Records are found") //HTTP Status Error Code:500
public class DCNNotFoundException extends RuntimeException{

	private static final long serialVersionUID = 197995355855327591L;
	
	private String dcnNo;
	private Integer rev;

	public DCNNotFoundException(String dcnNo, Integer rev) {
		this.dcnNo = dcnNo;
		this.rev=rev;
	}

	public String getDcnNo() {
		return dcnNo;
	}

	public Integer getRev() {
		return rev;
	}
}

先測試DCNNotFoundException是否catch到Runtime Exception,以及自行定義的錯誤訊息有沒有出現在錯誤網頁,故先更新DCNRepositoryImp code如下:

@Repository("DCNRepository")
@Transactional(propagation =Propagation.REQUIRED)
public class DCNRepositoryImp implements DCNRepository {

	@PersistenceContext
	private EntityManager entityManager;
	
	
	.....

	@Override
	public DCN findByNoAndRev(String dcnNo, Integer rev) {
		// TODO Auto-generated method stub
		Query query=entityManager.createQuery("select d from DCN d where d.no =:no and d.rev =:rev");
		query.setParameter("no", dcnNo);
		query.setParameter("rev", rev);
		DCN dcn=new DCN();
		try{ 
		dcn=(DCN)query.getSingleResult();
	   }catch(PersistenceException ex){
			ex.printStackTrace();
		   throw new DCNNotFoundException(dcnNo, rev); //如果搜尋不到紀錄則丟出自行定義的Exception class
		}
		
		return dcn;
	}
}

啟動Server,網址列打入一個不存在的紀錄,出現畫面如下:

message已有更新,再來我們要新增@ExceptionHandler於Controller中來指定此類錯誤網頁,其Code如下:

@Controller
@RequestMapping("/dcn")
public class DCNController {
	
	......

	@ExceptionHandler(DCNNotFoundException.class)
	public ModelAndView handleDCNRecordError(DCNNotFoundException exception){
		ModelAndView mav=new ModelAndView();
		mav.addObject("invalidDCN", exception.getDcnNo()); //取得產生exception的變數
		mav.addObject("invalidRev", exception.getRev());
		mav.setViewName("DCNNotFound");//錯誤網頁名稱為DCNNotFound.jsp
		return mav;
	}
	
}

接著新增DCNNotFound.jsp:

<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>



<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>${invalidDCN } R${invalidRev }  Not Found</title>


<div class="grid">
	<div class="row">
		<div class="span1"></div>
			<div class="span10">
					<div class="notice marker-on-bottom bg-darkRed">
						<div class="fg-white">
							${invalidDCN } R${invalidRev } Not Found. Please Check If DCN No Is Wrong Or A New DCN Record Need Be Added
						</div>
					</div>
					<br/>
					<p class="text-center">
					<a href="<spring:url value="/dcn"/>" class="button info">Back To DCN List</a>
					</p>
			</div>
		</div>
</div>

重新啟動Server,畫面如下


上一篇
[Controller]@MatrixVariable以及@RequestParam多參數存取特定網頁
下一篇
[View]輸出Excel格式報表
系列文
無痛學習SpringMVC與Spring Security31

尚未有邦友留言

立即登入留言