經上網搜尋google以及stackoverflow爬文,同時也看Springframework官方文件,試著了解為何RequestMappingHandlerMapping沒有找到對應的handler method,照理來說已經有定義@RequestMapping,應會找到對應的handler,爬完文後,如果MVCConfig中有@EnableWebMvc且Controller對應的package有被@ComponentScan掃描到,這個問題,不應存在,為了能繼續完成Spring MVC的介紹,有空的時候會再debug看看,故dispatchServlet部分就回歸載入xml組態檔的方式,同時在讀官方文件的時候,新增一個filter不一定要實作AbstractSecurityWebApplicationInitializer,在WebApplicationInitializer裡有registerServletFilter方法可以新增filter,我們可以在WebConfigForJavaConfig.java程式碼空白的地方按右鍵->source->Override/Implement Methods,勾選以下畫面方法
WebConfigForJavaConfig.java程式碼如下:
public class WebConfigForJavaConfig extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
// TODO Auto-generated method stub
// return null;
return new Class<?> []{PersistenceConfig.class}; //暫時已不需要載入SecurityConfig.class
}
@Override
protected Class<?>[] getServletConfigClasses() {
// TODO Auto-generated method stub
return null;
// return new Class<?>[]{MVCConfig.class}; //先註解掉本行,改用createServletApplicationContext()方法載入dispatch servlet xml組態檔
}
@Override
protected String[] getServletMappings() {
// TODO Auto-generated method stub
//return null;
return new String[] {"/"}; //不變
}
@Override
protected Dynamic registerServletFilter(ServletContext servletContext,
Filter filter) {
// TODO Auto-generated method stub
return super.registerServletFilter(servletContext, new SiteMeshFilter()); //Web初始化的時候註冊一個新的filter,即前面所提之SiteMeshFilter()
}
@Override
protected WebApplicationContext createServletApplicationContext() {
// TODO Auto-generated method stub
XmlWebApplicationContext ctx=new XmlWebApplicationContext(); //使用此class載入dispatch servlet組態檔
ctx.setConfigLocation("/WEB-INF/springconfig/dispatchServletcontext.xml");
return ctx;
}
@Override
protected Filter[] getServletFilters() {
// TODO Auto-generated method stub
return new Filter[]{
new OpenEntityManagerInViewFilter() //啟用JPA EntityManager lazy loading
};
}
}
另dispatchservletcontext.xml程式碼如下:
<context:component-scan base-package="tw.blogger.springtech.springmvc.controller"/>
<context:annotation-config/>
<mvc:annotation-driven />
<mvc:resources location="/resources/" mapping="/resources/**"/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"
value="org.springframework.web.servlet.view.JstlView"/>
<property name="prefix" value="/WEB-INF/views/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages"/>
</bean>
DCNController.java稍作修改,@RequestMapping也可以用在Class level上,在這個class以下每個方法的@RequestMapping在網址列上前面都會prepend class level的@RequestMapping,code如下:
@Controller
@RequestMapping("/dcn")
public class DCNController {
@RequestMapping //不指定mapping網址,即會對應到class的mapping URL http://localhost:8080/SpringMVC/dcn
public String DCNList(Model model){
model.addAttribute("dcns", dcnRepository.findAll());
return "DCNList";
}
.......
//對應的網址http://localhost:8080/SpringMVC/dcn/add
@RequestMapping(value="/add", method=RequestMethod.POST)
public String processDCNForm(@ModelAttribute("newDCN") DCN newDCN){
dcnService.add(newDCN);
return "redirect:/dcn"; //表單新增成功後導向/dcn,列入所有紀錄
}
}
昨日的addDCN.jsp排版稍作變化,已更新在昨日的post,基本上就是使用Grid系統來排版,接著要新增DCNList.jsp,主要用來列出所有紀錄,用到EL expression以及<c:forEach>來列出所有資料,code如下:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>DCN List</title>
<div class="grid">
<div class="row">
<div class="span1"></div>
<div class="span10">
<div class="panel">
<div class="panel-header bg-lightBlue fg-white">DCN List</div>
<div class="panel-content">
<table class="table striped bordered hovered">
<thead>
<tr>
<th class="text-center">Serial</th>
<th class="text-center">DCN No</th>
<th class="text-center">DCN Rev</th>
<th class="text-center">Category</th>
<th class="text-center">Tracking Number</th>
<th class="text-center">Issued Date</th>
<th class="text-center">Completed Date</th>
</tr>
</thead>
<tbody>
<c:forEach items="${dcns}" var="dcn" varStatus="counter">
<tr>
<td class="text-center"><c:out value="${counter.index+1}" /></td>
<td class="text-center">${dcn.no}</td>
<td class="text-center">${dcn.rev}</td>
<td class="text-center">${dcn.category}</td>
<td class="text-center">${dcn.trackNumber}</td>
<td class="text-center">${dcn.issuedDate}</td>
<td class="text-center">${dcn.completedDate}</td>
</tr>
</c:forEach>
</tbody>
<tfoot>
</tfoot>
</table>
</div>
</div>
</div>
</div>
</div>
啟動Server,網址列打入http://localhost/SpringMVC/dcn/add即可出現以下畫面
新增資料後,導向/dcn,網頁畫面如下
觀察console紀錄的log,RequestMapping handler方法已對應到tw.blogger.springtech.springmvc.controller.DCNController.DCNList,另外亦找到JPA EntityManger Query所產生的SQL,到資料庫將資料撈出來
22:54:05 [http-nio-8080-exec-10] DispatcherServlet - DispatcherServlet with name 'dispatcher' processing GET request for [/SpringMVC/dcn/]
22:54:05 [http-nio-8080-exec-10] RequestMappingHandlerMapping - Looking up handler method for path /dcn/
22:54:06 [http-nio-8080-exec-10] RequestMappingHandlerMapping - Returning handler method [public java.lang.String tw.blogger.springtech.springmvc.controller.DCNController.DCNList(org.springframework.ui.Model)]
22:54:06 [http-nio-8080-exec-10] DispatcherServlet - Last-Modified value for [/SpringMVC/dcn/] is: -1
Hibernate: select dcn0_.prikey as prikey1_0_, dcn0_.category as category2_0_, dcn0_.completedDate as complete3_0_, dcn0_.issuedDate as issuedDa4_0_, dcn0_.no as no5_0_, dcn0_.rev as rev6_0_, dcn0_.trackNumber as trackNum7_0_ from DCN dcn0_
22:54:06 [http-nio-8080-exec-10] DispatcherServlet - Rendering view [org.springframework.web.servlet.view.JstlView: name 'DCNList'; URL [/WEB-INF/views/DCNList.jsp]] in DispatcherServlet with name 'dispatcher'
22:54:06 [http-nio-8080-exec-10] JstlView - Added model object 'dcns' of type [java.util.ArrayList] to request in view with name 'DCNList'
22:54:06 [http-nio-8080-exec-10] JstlView - Forwarding to resource [/WEB-INF/views/DCNList.jsp] in InternalResourceView 'DCNList'
22:54:06 [http-nio-8080-exec-10] DispatcherServlet - Successfully completed request
明日再繼續介紹Controller常用的Annnotation。