可單例開發、典型的教科書式的mvc構架----springmvc----day01
springmvc-day01
springmvc的基礎知識
1.springmvc框架
1.1什麼是springmvc
springmvc是spring框架的一個模組,springmvc和spring無需通過中間整合層進行整合。
springmvc是一個基於mvc的web框架。
1.2mvc在B/S系統下的應用
mvc是一個設計模式,mvc在B/S系統下的應用:
1.3springmvc框架
第一步:發起請求到前端控制器(DispatcherServlet)
第二步:前端控制器請求HandlerMapping查詢Handler
可以根據xml配置、註解進行查詢
第三步:處理器對映器HandlerMapping向前端控制器返回Handler
第四步:前端控制器呼叫處理器介面卡去執行Handler
第五步:處理器介面卡去執行Handler
第六步:Handler執行完成給介面卡返回ModelAndView
第七步:處理器介面卡向前端控制器返回ModelAndView
ModelAndView是springmvc框架的一個底層物件,包括Model和view
第八步:前端控制器請求檢視解析器去進行檢視解析
根據邏輯檢視名解析成真正的檢視(jsp)
第九步:檢視解析器向前端控制器返回view
第十步:前端控制器進行檢視渲染
檢視渲染將模型資料(在ModelAndView物件中)填充到request域。
第十一步:前端控制器向用戶響應結果。
元件:
1.前端控制器DispatcherServlet(不需要程式設計師開發)
作用接收請求,響應結果,相當於轉發器,中央處理器。
有了DispatcherServlet減少了其他元件之間的耦合度。
2.處理器對映器HandlerMapping(不需要程式設計師開發)
作用:根據請求的url查詢Handler
3.處理器介面卡HandlerAdapter
作用:按照特定規則(HandlerAdapter要求的規則)去執行Handler
4.處理器Handler(需要程式設計師開發)
注意:編寫Handler時按照HandlerAdapter的要求去做,這樣介面卡才可以去正確執行Handler
5.檢視解析器View resolver(不需要程式設計師開發)
作用:進行檢視解析,根據邏輯檢視名解析成真正的檢視(view)
6.檢視View(需要程式設計師開發jsp)
View是一個介面,實現類支援不同的View型別(jsp、freemarker、pdf...)
2.入門程式
2.1需求
以案例作為驅動
springmvc和mybatis使用一個案例(商品訂單管理)。
功能需求:商品列表查詢
2.2環境準備
資料庫環境:mysql
java環境:
jdk
eclipse indigo
springmvc版本:spring3.2
需要spring3.2所有jar(一定要包括spring-webmvc-x.x.x.RELEASE.jar)
2.3配置前端控制器
在web.xml中配置前端控制器。
<!-- springmvc前端控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- contextConfigLocation配置springmvc載入的配置檔案(配置處理器、對映器、介面卡等等)
如果不配置contextConfigLocation,預設載入的是/WEB-INF/servlet名稱-servlet.xml(springmvc-servlet.xml)
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<!--
第一種:*.action,訪問以.action結尾由DispatcherServlet進行解析
第二種:/,所有訪問的地址都由DispatcherServlet進行解析,對於靜態檔案的解析需要配置不讓DispatcherServlet解析
使用此種方法可以實現RESTful風格的url
第三種:/*,這樣配置不對,使用這種配置,最終需要發到一個jsp頁面時,
仍然會有DispatcherServlet解析jsp地址值,不能提供jsp頁面找到handler,會報錯
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
2.4配置處理器介面卡
在classpath下的springmvc.xml中配置處理器介面卡
<!-- 處理器介面卡 -->
<!-- 所有處理器介面卡都實現HandlerAdapter介面 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
通過檢視原始碼:
public class SimpleControllerHandlerAdapter implements HandlerAdapter {
@Override
public boolean supports(Object handler) {
return (handler instanceof Controller);
}
@Override
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return ((Controller) handler).handleRequest(request, response);
}
@Override
public long getLastModified(HttpServletRequest request, Object handler) {
if (handler instanceof LastModified) {
return ((LastModified) handler).getLastModified(request);
}
return -1L;
}
}
此介面卡能執行實現Controller介面的Handler
public interface Controller {
/**
* Process the request and return a ModelAndView object which the DispatcherServlet
* will render. A {@code null} return value is not an error: it indicates that
* this object completed request processing itself and that there is therefore no
* ModelAndView to render.
* @param request current HTTP request
* @param response current HTTP response
* @return a ModelAndView to render, or {@code null} if handled directly
* @throws Exception in case of errors
*/
ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;
}
2.5開發Handler
需要實現controller介面,才能由org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter介面卡執行。
public class ItemsController1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 呼叫service查詢資料庫,查詢商品列表,這裡使用靜態資料模擬
List<Items> itemsList = new ArrayList<Items>();
// 向list中填充靜態資料
Items items_1 = new Items();
items_1.setName("聯想筆記本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 聯想膝上型電腦!");
Items items_2 = new Items();
items_2.setName("蘋果手機");
items_2.setPrice(5000f);
items_2.setDetail("iphone6蘋果手機!");
itemsList.add(items_1);
itemsList.add(items_2);
// 返回ModelAndView
ModelAndView modelAndView = new ModelAndView();
// 相當於resquest的setAttribute,在jsp頁面中通過itemsList取資料
modelAndView.addObject("itemsList", itemsList);
//指定檢視
modelAndView.setViewName("/WEB-INF/jsp/items/itemsList.jsp");
return modelAndView;
}
}
2.6檢視編寫
2.7配置Handler
將編寫Handler在spring容器中載入。
<!-- 配置Handler -->
<bean id="itemsController1" name="/queryItems.action" class="com.changemax.ssm.controller.ItemsController1"></bean>
2.8配置處理器對映器
在classpath下的springmvc.xml中配置處理器對映器
<!-- 處理器對映器 -->
<!-- 將bean的name作為url進行查詢,需要在配置Handler時指定beanname(就是url) beanname的所有對映器都實現了HTTPResultHandler -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
2.9配置檢視解析器
需要配置解析器jsp的檢視解析器
<!-- 檢視解析器 -->
<!-- 解析jsp檢視,預設使用jstl標籤,classpath下得有jstl的jar包 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置jsp路徑的字首 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置jsp路徑的字尾 -->
<property name="suffix" value=".jsp" />
</bean>
2.10部署除錯
訪問地址:http://localhost:8080/springmvc-day01/queryItems.action
3.非註解的處理器對映器的介面卡
3.1非註解的處理器對映器
處理器對映器:
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
另一個對映器:
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
<!-- 處理器對映器 -->
<!-- 將bean的name作為url進行查詢,需要在配置Handler時指定beanname(就是url) beanname的所有對映器都實現了HTTPResultHandler -->
<bean
class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!-- 簡單url對映 -->
<bean
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
對Itesmcontroller進行url地址對映,url就是queryItems.action
<prop key="/queryItems1.action">itemsController1</prop>
<prop key="/queryItems2.action">itemsController1</prop>
<prop key="/queryItems3.action">itemsController2</prop>
</props>
</property>
</bean>
多個對映器可以並存,前端控制器判斷url能讓哪些對映器對映,就讓正確的對映器處理。
3.2非註解的處理器介面卡
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter
要求編寫的Handler實現Controller介面。
public class ItemsController1 implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 呼叫service查詢資料庫,查詢商品列表,這裡使用靜態資料模擬
List<Items> itemsList = new ArrayList<Items>();
org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter
要求編寫的Handler實現HttpRequestHandler介面
public class ItemsController2 implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 呼叫service查詢資料庫,查詢商品列表,這裡使用靜態資料模擬
List<Items> itemsList = new ArrayList<Items>();
<!-- 處理器介面卡 -->
<!-- 所有處理器介面卡都實現HandlerAdapter介面 -->
<bean class="org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter"></bean>
<!-- 另一個非註解的介面卡 -->
<bean class="org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter" />
4.DispatcherServlet.properties
前端控制器從上邊的檔案中載入處理器對映器、介面卡、檢視解析器等元件,如果不在springmvc.xml中配置,使用預設載入的配置。
5.註解的處理器對映器和介面卡
對映器:
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping(過時)
在spring3.1之後使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping
介面卡:
在spring3.1之前使用org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter(過時)
在spring3.1之後使用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter
5.1配置註解對映器和介面卡
<!-- 註解的對映器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!-- 註解的介面卡 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
<!-- mvc:annotation-driven代替上邊註解對映器和註解介面卡的配置
mvc:annotation-driven預設載入很多的引數繫結方法,比如json轉換解析器就預設載入了,
如果使用mvc:annotation-driven不用配置上邊的RequestMappingHandlerMapping和RequsetMappingHandleAdaper
實際開發中使用:mvc:annotation-driven
-->
5.2開發註解Handler
使用註解的對映器和註解的介面卡。(註解的對映器和註解的介面卡必須配對使用)
//使用@Controller註解標識這個是個控制器
@Controller
public class ItemsController3 {
// 商品查詢列表
//@RequestMapping實現了對方法和url進行對映,一個方法對應一個url
//一般建議url和方法名一樣,便於維護
@RequestMapping("/queryItems")
public ModelAndView queryItems() throws Exception {
// 呼叫service查詢資料庫,查詢商品列表,這裡使用靜態資料模擬
List<Items> itemsList = new ArrayList<Items>();
// 向list中填充靜態資料
Items items_1 = new Items();
items_1.setName("聯想筆記本");
items_1.setPrice(6000f);
items_1.setDetail("ThinkPad T430 聯想膝上型電腦!");
Items items_2 = new Items();
items_2.setName("蘋果手機");
items_2.setPrice(5000f);
items_2.setDetail("iphone6蘋果手機!");
itemsList.add(items_1);
itemsList.add(items_2);
ModelAndView modelAndView = new ModelAndView();
// 相當於resquest的setAttribute,在jsp頁面中通過itemsList取資料
modelAndView.addObject("itemsList", itemsList);
// 指定檢視
//通過springmvc配置檔案,可以省掉jsp路徑的字首和字尾
modelAndView.setViewName("items/itemsList");
return modelAndView;
}
}
5.3在spring容器中載入Handler
<!-- 對於註解的handler配置可以單個配置
在實際開發中,建議使用元件掃描
-->
<bean id="itemsController3"
class="com.changemax.ssm.controller.ItemsController3"></bean>
<!-- 可以使用掃描controller、service、...
這裡讓掃描controller,指定controller的包路徑
-->
<context:component-scan base-package="com.changemax.ssm.controller"></context:component-scan>
5.4部署除錯
訪問:http://localhost:8080/springmvc-day01/queryItems.action
6原始碼分析(瞭解)
通過前端控制器原始碼分析springmvc的執行過程。
第一步:前端控制器接收請求
呼叫doDiapatch
第二步:前端控制器呼叫處理器對映器查詢Handler
第三步:呼叫處理器介面卡執行Handler,得到執行結果ModelAndView
第四步:檢視渲染,將model資料填充到request域。
檢視解析,得到view。
呼叫view的渲染方法,將model資料填充到request域
7.入門程式小結
通過入門程式理解springmvc前端控制器、處理器對映器、處理器介面卡、檢視解析器用法。
前端控制器配置:
第一種:*.action,訪問以.action結尾 由DispatcherServlet進行解析
第二種:/,所以訪問的地址都由DispatcherServlet進行解析,對於靜態檔案的解析需要配置不讓DispatcherServlet進行解析
使用此種方式可以實現RESTful風格的url
處理器對映器:
非註解處理器對映器(瞭解)
註解的處理器對映器(掌握)
對標記@Controller類中標識有@RequestMapping的方法進行對映。在@RequestMapping裡邊定義對映的url。
使用註解的對映器不用再xml中配置url和Handler的對映關係。
處理器介面卡:
非註解的處理器介面卡(瞭解)
註解的處理器介面卡(掌握)
註解處理器介面卡的註解的處理器對映器是配對使用。理解為不能使用非註解對映器進行對映。
<mvc:annotation-driven></mvc:annotation-driven>可以替代下邊的配置:
<!--註解對映器 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
<!--註解介面卡 -->
<bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter"/>
實際開發使用:mvc:annotation-driven
檢視解析器配置字首和字尾:
<!-- 檢視解析器 -->
<!-- 解析jsp檢視,預設使用jstl標籤,classpath下得有jstl的jar包 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 配置jsp路徑的字首 -->
<property name="prefix" value="/WEB-INF/jsp/" />
<!-- 配置jsp路徑的字尾 -->
<property name="suffix" value=".jsp" />
</bean>
如此配置之後,就可以在程式中不用指定字首和字尾
8.springmvc和mybatis整合
8.1需求
使用springmvc和mybatis完成商品列表查詢。
8.2整合思路
spring將各層進行整合
通過spring管理持久層的mapper(相當於dao介面)
通過spring管理業務層service,service中可以呼叫mapper介面。
spring進行事物控制。
通過spirng管理表現層Handler,Handler中可以呼叫service介面。
mapper、service、Handler都是javabean。
第一步:整合dao層:
mybatis和spring整合,通過spring管理mapper介面。
使用mapper的掃描器自動掃描mapper介面在spring中進行註冊。
第二步:整合service層
通過spring管理service介面。
使用配置方式將service介面配置在spring配置檔案中。
實現事務控制。
第三步:整合springmvc
由於springmvc是spring的模組,不需要整合。
8.3準備環境
資料庫環境:mysql
Java環境:
jdk1.8
eclipse indigo
springmvc4.3
所需要jar包;
資料庫驅動包:mysql
mybatis的jar包
mybatis和spring的整合包
log4j包
dbcp資料庫連線池包
spring3.2所有jar包
jstl包
8.4整合dao
mybatis和spring進行整合
8.4.1sqlMapConfig.xml
mybatis自己的配置檔案:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 全域性的setting配置,根據需要新增 -->
<!-- 別名定義 -->
<typeAliases>
<package name="com.changemax.ssm.po" />
</typeAliases>
<!-- 載入 對映檔案 由於使用spring和mybatis的整合包進行mapper掃描,這裡不需要配置了 -->
<mappers>
<!-- <mapper resource="sqlmap/User.xml" /> -->
<!-- 批量載入mapper 指定mapper介面的包名,mybatis自動掃描包下邊所有mapper介面進行載入 遵循一些規範: 需要將mapper介面類名和mapper.xml對映檔名稱保持一致,且在一個目錄
中 上邊規範的前提是:使用的是mapper代理方法 和spring整合後,使用mapper掃描器,這裡不需要配置了 -->
<!-- <package name="com.changemax.ssm.mapper" /> -->
</mappers>
</configuration>
8.4.2applicationContext-jdbc.xml
配置:
資料來源
SqlSessionFactory
mapper掃描器
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.2.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.2.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.2.xsd ">
<!-- 和jdbc配置相關的 -->
<!-- 載入db.properties檔案中的內容,db.properties檔案中的key命名要具有一定的特殊規則 -->
<context:property-placeholder
location="classpath:db.properties" />
<!-- 配置資料來源,c3p0連線池 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="30" />
<property name="maxIdle" value="5" />
</bean>
<!-- 配置sqlSessionFactory -->
<bean id="sqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 資料庫連線池 -->
<property name="dataSource" ref="dataSource" />
<!-- 載入mybatis的全域性配置檔案 -->
<property name="configLocation"
value="classpath:mybatis/sqlMapConfig.xml" />
</bean>
<!-- mapper掃描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 掃描包路徑,如果需要掃描多個包,中間使用半形逗號隔開 -->
<property name="basePackage" value="com.changemax.ssm.mapper"></property>
<property name="sqlSessionFactoryBeanName"
value="sqlSessionFactory" />
</bean>
</beans>
8.4.3applicationContext-transaction.xml
8.4.4逆向工程生成po類及mapper(單表增刪改查)
將生成的檔案拷貝至工程中。
8.4.5手動定義商品查詢mapper
針對綜合查詢mapper,一般情況會有關聯查詢,建議自定義mapper
8.4.5.1ItemsMapperCustom.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.changemax.ssm.mapper.ItemsMapperCustom" >
<!-- 定義商品查詢的sql片段,就是商品查詢條件 -->
<sql id="query_items_where">
<!-- 使用動態sql,通過if判斷,滿足條件進行sql拼接 -->
<!-- 商品查詢條件通過ItemsQueryVo包裝物件 中itemsCustom屬性傳遞 -->
<if test="itemsCustom!=null">
<if test="itemsCustom.name!=null and itemsCustom.name!=''">
items.name LIKE '%${itemsCustom.name}%'
</if>
</if>
</sql>
<!-- 商品列表查詢 -->
<!-- parameterType傳入包裝物件(包裝了查詢條件)
resultType建議使用擴充套件物件
-->
<select id="findItemsList" parameterType="com.changemax.ssm.po.ItemsQueryVo"
resultType="com.changemax.ssm.po.ItemsCustom">
SELECT items.* FROM items
<where>
<include refid="query_items_where"></include>
</where>
</select>
</mapper>
8.4.5.2ItemsMapperCustom.java
package com.changemax.ssm.mapper;
import java.util.List;
import com.changemax.ssm.po.ItemsCustom;
import com.changemax.ssm.po.ItemsQueryVo;
public interface ItemsMapperCustom {
//商品查詢列表
public List<ItemsCustom> findItemsList(ItemsQueryVo itemsQueryVo)throws Exception;
}
8.5整合service
讓spring關聯service介面。
8.5.1定義service介面
public interface ItemsService {
/**
* 商品查詢列表
* <p>
&n