今天好像大家來得都相當的晚……
=====================================================================
先把Spring說完,然後是UML和設計模式,還有複習,最後應該是框架整合
Spring的表述層應用……
數據層應用是使用了模版的一種模式,通過Spring的jdbcTemplate讀取數據庫,通過模版調用回調
函數;LocalSessionFactoryBean得到Session,然後配合HibernateTemplate就可以……
與數據層類似,Spring不僅提供了具體的MVC實現,也給出了引入其它Web組件的接口。
由於具有天生的IOC和AOP特性,使得Spring的Web層應用輕巧而易於擴展。
即使是使用Struts等第三方框架,IOC和AOP特性也能很好地將它們融合進來。
Spring的MVC實現中,控制器也分爲總控制器和分控制器。
總控制器是DispatcherServlet,類似於Struts中ActionServlet。
分控制器是Controller,其處理請求的方法是handleRequest,類似於Struts中的Action
模型與視圖被定義成一個整體,在Spring中是使用ModelAndView表示的。
Struts中:
ActionServlet(總控制器)、RequestProcessor(模塊控制器)、Action(分控制器)三個控制器
嚴格來說,Struts中是沒有模型的,模型分邏輯模型和數據模型兩種………………
同樣的數據可以通過Spring的控制器生成pdf、excel、jsp等衆多視圖
------------------------------------------------------------------
SpringMVC大概流程:
符合配置要求的(比如.do結尾)請求來了之後,會被交給總控制器DispatcherServlet,
然後DispatcherServlet經過請求映射HandlerMapping來解析,解析後返回ModelAndView,
然後交給ViewResolver解析,最終生成視圖
配置DispatcherServlet-web.xml;(和Struts一樣也在web.xml中配置……)
定義Controller,返回模型與視圖;
配置Controller;
生成頁面,並訪問模型。
例子:
spring.jar加入到web工程的lib裏面去。
DispatcherServlet在org.springframework.web.servlet中
web.xml中配置
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
這樣會給人一種假象,好像整個網站都是以.htm結尾的靜態網頁,其實是發送請求的動態網頁,所有擴展名
爲htm的網頁都會提交請求給總控制器,而html是靜態頁面
現在還需要分支控制器controller
import org.springframework.web.servlet.ModelAndView ;
import org.springframework.web.servlet.mvc.Controller ;
public class MyController implements Controller
{
private String msg ;
public void setMsg(String msg)
{
this.msg = msg ;
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception
{
return new ModelAndView("first.jsp","msg", msg) ;//ModelAndView返回給DispatcherServlet
//會往請求作用域裏面存入這個msg,可以通過EL表達式
//直接去取,比如${msg}
}
}
ModelAndView是一個具體的類,裏面有setter方法,可以採用依賴注入的方式
比如first.jsp中可以有:
${msg}
新建一個dispatcher-servlet.xml
假如總控制器的名字是aaa,那麼這個xml文件的名字默認情況下應該是aaa-servlet.xml!
當然也可以通過別的方式改名
//用Spring的依賴注入,DOCTYPE的創建是參考bean.xml的
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>//注意這裏之所以不用id而用name是因爲id中是不可以有“/”的!
<bean name="/first.htm" class="spring.MyController">
<property name="msg" value="Hello,World" />
</bean>
</beans>
總控制器叫DispatcherServlet、分支控制器是Controller、ModelAndView
解析出View
=====================================================================
把上面的例子稍微改一下,改成一個登錄的例子,應該把視圖和控制器隔離開來!
控制器:
import org.springframework.web.servlet.ModelAndView ;
import org.springframework.web.servlet.mvc.Controller ;
public class MyController implements Controller,ApplicationContextAware
{
private String msg ; //模型信息
private Properties targets ;//使用屬性類存儲success和failure兩個字符串……
private JdbcTemplate template ;//需要依賴注入JdbcTemplate信息
private ApplicationContext context ;
public void setTemplate(JdbcTemplate template)
{
this.template = template ;
}
public void setTargets(Properties targets)
{
this.targets = targets ;
}
public void setMsg(String msg)
{
this.msg = msg ;
}
public ModelAndView handleRequest(HttpServletRequest request,
HttpServletResponse response) throws Exception
{
String target = "success" ;
Object[] args = {request.getParameter("username"),
request.getParameter("password")} ;//從請求獲得用戶名和密碼!
List result =
template.queryForList("select * from users where username=? and password=?",args) ;
if(result.isEmpty())
{
target = "failure" ;
}
return new ModelAndView(targets.getProperty(target),"msg",msg) ;
//如果不需要返回模型信息的話,就不要後面兩個參數就可以了!
}
}
bean.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
//配置數據源:
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///j2ee" />
<property name="username" value="root" />
<property name="password" value="root" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource" />
</bean>
//配置控制器
<bean name="/first.htm" class="spring.MyController">
<property name="template" ref="jdbcTemplate"/>
<property name="msg" value="Hello,World" />
<property name="targets">
<props>
<prop key="success">/success.jsp</prop>
<prop key="failure">/failure.jsp</prop>
</props>
</property>
</bean>
</beans>
然後再創建出success.jsp和failure.jsp,就可以觀察結果了。
輸入網址,別忘了在地址中提供查詢字符串:
/first.htm?username=jsp&password=jsp
=======================================================================
注意上面兩個例子裏面都沒有提到HandlerMapping和ViewResolver以及View,其實不配置
前兩個,也會默認給你一個配置的,最後一個View也一樣,不管它的話也會有默認的設置。
這裏有一點需要注意!!
dispatcher-servlet.xml默認情況下是放在WEB-INF裏面的,但是以前裝載bean.xml的時候
是用XMLBeanFactory根據提供的路徑裝載的,但是這個despatcher-servlet.xml不在類路徑
裏面,沒辦法通過這種方式裝載,
現在如果我想給這個配置文件改名!並且我想把它放到classes目錄中去。
該怎麼做呢????
修改web.xml:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/classes/bean.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
==============================================================================
落了20分鐘的課程……
*.do給ActionServlet,然後根據模塊路徑轉到RequestProcessor,然後模塊控制器再根據
.do前面的名稱選擇適當的Action控制器
Spring的AOP可以對Struts進行更改,三種方式:
1、更改Action
2、在RequestProcessor去找Action之前加一道"屏障"
3、在ActionServlet去找RequestProcessor之前加一道“屏障”
比如說:http://localhost:8080/工程名/模塊名/*.do
例子:
將Struts整合進Spring中:
package cn.itcast ;
在struts-config中的最後加上:
其實在struts中的這個配置文件主要需要更改的第一是加上個plug-in,
第二是更改controller名稱,然後再依賴注入就成了。
<action-mappings>
<action path="/list" type="cn.itcast.action.ListAction">
<forward name="success" path="/list.jsp" />
</action>
</action-mappings>
<controller
processorClass="org.springframework.web.struts.DelegatingRequestProcessor"/>
<message-resources parameter="cn.itcast.ApplicationResources" />
<plug-in className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation" value="/WEB-INF/bean.xml"/>
</plug-in>
這樣所有的請求就被轉到了Spring中,而不是Struts裏面,在Struts中根本感知不到Spring的存在
Spring和Struts按照如下方式集成的時候,根本就不需要怎麼更改Struts,只需要考慮Spring怎麼去
影響Struts的行爲就可以了。Spring使得程序鬆耦合,不至於表述層和數據層之間過分的依賴,而且
事務管理方面Spring也做的十分的不錯。
bean.xml中:
<beans>
<bean name="/list" class="cn.itcast.action.ListAction">
<property name="msg" value="hello!" />
</bean>
</beans>
public class ListAction extends Action
{
private String msg ;
//加入msg的setter方法
public ActionForward execute()
{
request.setAttribute("msg",msg);
return mapping.findForward("success");
}
}
list.jsp:
${msg}
=========================================================
下面把Hibernate整合進來:
建立hibernate.cfg.xml
<session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql///j2ee</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="show_sql">true</property>
</session-factory>
新建實體類:
package cn.itcast.vo;
public class Account
{
private int id ;
private balance ;
//getter和setter方法
}
Account.hbm.xml:
<hibernate-mapping package="cn.itcast.vo">
<class name="Account" table="accounts">
<id name="id" column="id">
<generator class="identity" />
</id>
<property name="balance" column="balance" />
</class>
</hibernate-mapping>
bean.xml:
<beans>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.localSessionFactoryBean">
//加入Hibernate的兩個配置文件的位置
<property name="configLocation" value="classpath:hibernate.cfg.xml" />
<property name="mappingLocations">
<list>
<value>classpath:cn/itcast/vo/Account.hbm.xml</value>
</list>
</property>
</bean>
<bean id="hibernateTemplate"
class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean name="/list" class="cn.itcast.action.ListAction">
<property name="template" ref="hibernateTemplate" />
<property name="className" value="cn.itcast.vo.Account" />
</bean>
</beans>
public class ListAction extends Action
{
private String className ;
private HibernateTemplate template ;
//加入className和template的setter方法
public ActionForward execute()
{
List list = template.find("from "+className) ;
request.setAttribute("list",list);
return mapping.findForward("success");
}
}
//然後在list.jsp中迭代出來就成了。
<%@ taglib prefix="logic" uri="/WEB-INF/struts-logic.tld" %>
<table>
<logic:iterate id="row" name="list">
<tr>
<td>${row.id}</td>
<td>${row.balance}</td>
</tr>
</logic:iterate>
</table>
注意一個問題!!Hibernate的兩個配置文件的DOCTYPE一定要寫對,就是要以官方文檔爲準
---------------------------------------------------------------------
今天中午一點去面試了,也不知道對方的底細,當然也不知道自己的底細,糊里糊塗的就去了,
挺怪的,對方表現很沉穩,我也裝的很沉穩(其實我這個人骨子裏是很浮躁的,我一直是如此,
如果有人覺得我這個人踏實,那一定是誤會我了,有時我會裝的很踏實,就像今天面試的時候,
其實想想也知道,做it折行的,如果你很沉穩,你爲什麼來培訓呢?),雙方都沉穩,沉穩的
讓氣氛有些憋悶,那個地方挺漂亮,剛進門兩邊的牆上甚至寫滿了程序代碼!(不知是什麼語言,
反正不是C、C++或者java),二樓竟然有很多青年男女在踢毽子,一看就是個全是年輕人的地方,
面試的時候沒有問太多技術方面的細節問題(幾乎就沒怎麼問),主要問的是對某些東西的體會
或是感受,說白了就是處於優勢地位套你的話,探你的底,筆試題只有一道,我都懷疑我是否作對
了,因爲當時一看確實是太簡單了,就是一個樹的遞歸,真沒別的東西,當時不確定,回來寫了
一下子,其實看懂和寫明白確實差着距離,雖然寫出來了,但是還是不熟練……
package com.yuanbin.practice;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Demo {
public static void generateTree(List list, int pid , int level)
{
StringBuffer title = new StringBuffer("") ;
if( list != null && list.size() != 0)
{
Iterator it = list.iterator() ;
while(it.hasNext())
{
Tree node = (Tree)it.next();//得到一個節點
if(node.getPid()==pid)
{
String name = node.getName();//得到節點的名稱
for(int i = 0 ; i < level ; i ++)
{
title.append(" ");
}
title.append(name);
System.out.println(title.toString());
title = new StringBuffer("");
generateTree(list,node.getId(),level+1);
}
}
}
}
public static void main(String[] args)
{
Tree tree1 = new Tree(0,1,"一級標題");
Tree tree2 = new Tree(1,2,"二級標題");
Tree tree3 = new Tree(2,3,"三級標題");
Tree tree4 = new Tree(0,4,"一級標題");
Tree tree5 = new Tree(3,5,"四級標題");
Tree tree6 = new Tree(1,6,"二級標題");
Tree tree7 = new Tree(1,7,"二級標題");
Tree tree8 = new Tree(0,8,"一級標題");
Tree tree9 = new Tree(2,9,"三級標題");
Tree[] tree = {tree1,tree2,tree3,tree4,tree5,tree6,
tree7,tree8,tree9};
List list = new ArrayList();
for(int i = 0 ; i < tree.length ; i ++)
{
list.add(tree[i]);
}
generateTree(list,0,0);
}
}
事實證明,我沒有做錯,題目的意思就是讓你根據程序填空而已,沒什麼,代碼的意思
呢,也就是根據父id去遍歷子節點,作爲一級節點來說,父id是0(也就是沒有父id)
所以程序的入口點要從父id爲0開始,level級別是爲了表明各個節點名稱之前到底有
多少空格,每次找到一個節點之後,就立刻找這個id的子節點,找到子節點之後,立刻
再去找這個子節點的子節點(典型的遞歸調用,沒什麼好說的)。