SpringMVC 框架項目小結
SpringMVC是一個基于DispatcherServlet的MVC框架,每一個請求最先訪問的都是DispatcherServlet,DispatcherServlet負責轉發每一個Request請求給相應的Handler,Handler處理以后再返回相應的視圖(View)和模型(Model),返回的視圖和模型都可以不指定,即可以只返回Model或只返回View或都不返回。
DispatcherServlet是繼承自HttpServlet的,既然SpringMVC是基于DispatcherServlet的,那么我們先來配置一下DispatcherServlet,好讓它能夠管理我們希望它管理的內容。HttpServlet是在web.xml文件中聲明的。
<servlet> <servlet-name>securityWeb</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath*:conf/applicationContext-mvc.xml</param-value> </init-param> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>securityWeb</servlet-name> <url-pattern>*.do</url-pattern> </servlet-mapping>
上面聲明了一個名為securityWeb的DispatcherServlet,該Servlet將處理所有以“.do”結尾的請求。在初始化DispatcherServlet的時候,SpringMVC默認會到/WEB-INF目錄下尋找一個叫[servlet-name]-servlet.xml的配置文件,來初始化里面的bean對象,該文件中對應的bean對象會覆蓋spring配置文件中聲明的同名的bean對象。如上面的就會在/WEB-INF目錄下尋找一個叫securityWeb-servlet.xml的文件;當然也可以在Servlet中聲明配置文件的位置。如上面代碼已經寫出路徑。</span>
DispatcherServlet會利用一些特殊的bean來處理Request請求和生成相應的視圖返回。
關于視圖的返回,Controller只負責傳回來一個值,然后到底返回的是什么視圖,是由視圖解析器控制的,在jsp中常用的視圖解析器是InternalResourceViewResovler,它會要求一個前綴和一個后綴
<?xml version="1.0" encoding="UTF-8"?> <!--- DispatcherServlet application context for DeclareOnline's web tier. spring mvc 的 DispatcherServlet 對應的配置文件
--> <beans xmlns="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/context
<!-- - The controllers are autodetected POJOs labeled with the @Controller annotation. Spring mvc將在該路徑下尋找Controller(有Controller注釋的類) --> <context:component-scan base-package="com.zhjy.dps.*"/> <!-- 使用依賴控制器類名字的慣例,將URI映射到控制器 --> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" /> <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <!-- 啟動Spring MVC的注解功能,完成請求和注解POJO的映射 --> <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- 定義Spring MVC 的模板文件 --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <!-- 支持JSTL --> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> <!-- 模板的路徑 --> <property name="prefix" value="/" /> <!-- 模板文件后綴 --> <property name="suffix" value=".jsp" /> </bean>
</beans></pre>
在上述視圖解析器中,如果Controller返回的是securityWeb/index,那么通過視圖解析器解析之后的視圖就是/WEB-INF/securityWeb/index.jsp。要使用注解的SpringMVC需要在SpringMVC的配置文件中進行聲明,具體方式為先引入mvc命名空間,然后利用<mvc:annotation-driven />進行聲明。
主要是說說Controller.
一個類使用了@Controller進行標記的都是Controller
@Controller public class PlanController { }
有了Controller之后,那么到底是怎樣請求一個Controller具體的方法的呢,那是通過@RequestMapping來標記的,@RequestMapping可以標記在類上面,也可以標記在方法上,當方法上和類上都標記了@RequestMapping的時候,那么對應的方法對應的Url就是類上的加方法上的,如下面的index方法,其對應的URL應為類上的/blog加上index方法上的/index,所以應為/blog/index,所以當請求/blog/index.do的時候就會訪問BlogController的index方法。
@Controller
public class PlanController {@RequestMapping("service/index") public String index(Map<String, Object> map) { return "secruityWeb/index"; }
} </pre>
在RequestMapping中還可以指定一個屬性method,其主要對應的值有RequestMethod.GET和RequestMethod.POST,利用該屬性可以嚴格的控制某一方法只能被標記的請求路徑對應的請求方法才能訪問,如指定method的值為GET,則表示只有通過GET方式才能訪問該方法,默認是都可以訪問。
在SpringMVC中常用的注解還有@PathVariable,@RequestParam,@PathVariable標記在方法的參數上,利用它標記的參數可以利用請求路徑傳值,看下面一個例子
@RequestMapping(value="/comment/{blogId}", method=RequestMethod.POST)
public void comment(Comment comment,@PathVariable int blogId, HttpSession session, HttpServletResponse response) throws IOException {} </pre>
在該例子中,blogId是被@PathVariable標記為請求路徑變量的,如果請求的是/blog/comment/1.do的時候就表示blogId的值為1. 同樣@RequestParam也是用來給參數傳值的,但是它是從頭request的參數里面取值,相當于request.getParameter("參數名")方法。在Controller的方法中,如果需要WEB元素HttpServletRequest,HttpServletResponse和HttpSession,只需要在給方法一個對應的參數,那么在訪問的時候SpringMVC就會自動給其傳值,但是需要注意的是在傳入Session的時候如果是第一次訪問系統的時候就調用session會報錯,因為這個時候session還沒有生成。
接下來討論一下方法的返回值,主要有一下情況:
- 返回一個ModelAndView,其中Model是一個Map,里面存放的是一對對的鍵值對,其可以直接在頁面上使用,View是一個字符串,表示的是某一個View的名稱
- 返回一個View,也就是一個字符串,這個時候如果需要給頁面傳值,可以給方法一個Map參數,該Map就相當于一個Model,往該Model里面存入鍵值對就可以在頁面上進行訪問了
- 返回一個Model也就是一個Map,這個時候將解析默認的生成的view name。
- 什么也不返回,這個時候可以利用HttpServletResponse進行返回,也可以直接使用printStream進行返回 </ul> 下面是一個實例:
@RequestMapping("/work/plan/findProjectByState") public String findProjectByState(YearPlanMgrQueryForm form,String planState, HttpServletRequest request, HttpServletResponse response) { HttpSession session = request.getSession(); String industryId = (String) session.getAttribute("industryID"); String planName = request.getParameter("planName"); String personSituation = request.getParameter("planState"); try { if(planState != null && !"".equals(planState)){ form.setPlanState(planState); } int pageNo = 1; int fetch = 8; String pageNumber = request.getParameter("pageNumber"); String pageSize = request.getParameter("pageSize"); // 得到頁碼 if (pageNumber == null) { pageNo = PageUtil.getPageNum(request, PageUtil.DEFAULT_PAGENUM); } else { pageNo = Integer.parseInt(pageNumber); }// 得到每頁記錄數 if (pageSize == null) { fetch = PageUtil.getPageSize(request, 8); } else { fetch = Integer.parseInt(pageSize); } // 獲取列表 System.out.println(personSituation); Page<Map<String, Object>> page = projectPlanService.findProjectByState(planName, industryId, personSituation, pageNo, fetch); request.setAttribute("personSituation", personSituation); request.setAttribute("page", page); request.setAttribute("pageSize", fetch); } catch (Exception e) { throw new PlatformException(e); } return "/module/industry/planlist"; }</pre><br />