iT邦幫忙

DAY 11
0

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

[Controller]混用xml組態檔及Java Config,"Handler Method Not Found"問題暫時解決

經上網搜尋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。


上一篇
[Controller]Spring MVC Controller CRUD常用annotations介紹(I)
下一篇
[Controller/View]資料直接輸出JSON以及XML格式(I, ContentNegotiatingViewResolver)
系列文
無痛學習SpringMVC與Spring Security31

尚未有邦友留言

立即登入留言