3月15日——培訓第80天

今天說一下HandlerMapping和ViewResolver在SpringMVC中的作用:


<?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>
 
 //注意:下面的id字段可以不用加入!
 <bean id="handlerMapping"
  class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">

  <property name="mappings">
   <props>
    <prop key="/first.htm">first</prop>
   </props>
  </property>
 </bean>
 //配置控制器
 <bean name="/firs" 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>

-----------------------------------------------------------------
在bean.xml中加上如下代碼:(注意下面的配置文件是針對昨天的mvc工程的!)
 //HandlerMapping:
 <bean class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props>
        <prop key="/first.htm">first</prop>
        <prop key="/second.htm">first</prop>
      </props>
    </property>
  </bean>

  //ViewResolver
  <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
  <bean id="success" class="org.springframework.web.servlet.view.InternalResourceView">
    <property name="url" value="/success.jsp" />
  </bean>
  <bean id="failure" class="org.springframework.web.servlet.view.InternalResourceView">
    <property name="url" value="/failure.jsp" />
  </bean>

 

也就是修改後的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 class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
      <props>
        <prop key="/first.htm">first</prop>
        <prop key="/second.htm">first</prop>
      </props>
    </property>
  </bean>

  <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
  <bean id="success" class="org.springframework.web.servlet.view.InternalResourceView">
    <property name="url" value="/success.jsp" />
  </bean>
  <bean id="failure" class="org.springframework.web.servlet.view.InternalResourceView">
    <property name="url" value="/failure.jsp" />
  </bean>

  <bean id="first" class="spring.MyController">
    <property name="template" ref="jdbcTemplate" />
    <property name="targets">
      <props>
        <prop key="success">/success.jsp</prop>
        <prop key="failure">/failure.jsp</prop>
      </props>
    </property>
  </bean>
</beans>
---------------------------------------------
web.xml:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
 xmlns="http://java.sun.com/xml/ns/j2ee"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
 http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <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/bean.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
 
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.htm</url-pattern>
  </servlet-mapping>

</web-app>

------------------------------------------
工程中有三個jsp頁面
first.jsp:
  <body>
    ${msg}
  </body>

failure.jsp:
  <body>
    failure. <br>
  </body>

success.jsp:
  <body>
    success. <br>
  </body>

--------------------------------------------
//控制器代碼:
package spring;

import java.util.List;
import java.util.Properties;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;

public class MyController implements Controller,
 ApplicationContextAware
{

 private Properties targets;

 private JdbcTemplate template;
 
 private ApplicationContext context;

 public void setTemplate(JdbcTemplate template)
 {
  this.template = template;
 }

 public void setTargets(Properties targets)
 {
  this.targets = targets;
 }

 public ModelAndView handleRequest(HttpServletRequest request,
   HttpServletResponse response) throws Exception
 {
  // TODO Auto-generated method stub
  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";
   System.out.println("failure");
  }
  return new ModelAndView(target);
 }

 public void setApplicationContext(ApplicationContext arg0) throws BeansException
 {
  // TODO Auto-generated method stub
  context = arg0;
 }

}

=======================================================================================
上面用的是InternalResourceView……
當然你也可以自己做一個視圖……
package spring ;

public class MyView implements View
{
 public void render(Map model, HttpServletRequest request,
  HttpServletResponse response)
  throws Exception
 {
  //將map迭代,然後存入請求作用域,這裏其實就是將模型信息存入請求作用域,
  //如果model是null的話(比如return return new ModelAndView("my")其實
  //就是返回了一個視圖,沒有返回模型),那麼就不進入下面的if分支了,直接生成
  //視圖了
  if(model!=null)
  {
   Set entrySet = model.entrySet() ;
   Iterator it = entrySet.iterator() ;
   while(it.hasNext())
   {
    Map.Entry entry = (Map.Entry) it.next() ;
    request.setAttribute(entry.getKey().toString,entry.getValue());
    
   }
  }
  PrintWriter out = response.getWriter() ;
  out.println("<h1>this is my first view!</h1>") ;
  request.getRequestDispatcher(url).forward() ;
 }
};

然後在bean.xml中注入
<bean id="my" class="spring.MyView">
</bean>

最後在控制器中返回
 return return new ModelAndView("my");

============================================================
如果要生成pdf呢?

如果要生成PDF文件,必須生成一個AbstractPdfView 類型的視圖。主要是通過擴展這個類實現的。
AbstractPdfView 中有一個抽象方法需要實現,即 void buildPdfDocument( Map model,
Document document, PdfWriter writer, HttpServletRequest request,
    HttpServletResponse response)

方法中的Document 和PdfWriter位於com.lowagie.text包中,這是lowagie的一個開源項目
iText中的包,網址是www.lowagie.com,目前最高版本是1.4
iText項目基於面向對象的思想,將PDF文件抽象成Document對象,然後以Element爲基礎抽象
了PDF中的元素,這包括Anchor, Cell, Chapter, Chunk, Graphic, Header, Image,
Jpeg, List, ListItem, Meta, Paragraph, Phrase, Rectangle, Row, Section,
Table等等。具體參考API文檔。

public class MyPdfView extends AbstractPdfView {
 public void buildPdfDocument(Map model, Document document,
   PdfWriter pdfWriter, HttpServletRequest request,
   HttpServletResponse response) throws Exception {
  String msg = (String) model.get("msg");
  Paragraph e = new Paragraph(msg);
  e.setAlignment(Element.ALIGN_CENTER);
  document.add(e);
 }
}

註冊:
<bean id="first" class="spring.mvc.MyPdfView"/>
<bean id=“resolver"
 class="org.springframework.web.servlet.view.BeanNameViewResolver" />
==========================================================================

例:
lib中有一個itext文件夾裏面的jar包加入到工程中來……
package spring ;
public class MyPdfView extends AbstractPdfView
{
 public void buildPdfDocument(//參數略)//重寫這個方法
 {
  response.setHeader("content-disposition","attachment;filename=first.pdf");
  //上面那句話是以附件形式打開pdf
  Paragraph e = new Paragraph("This is my first pdf!");
  e.setAlignment(Element.ALIGN_CENTER);
  document.add(e);
 }
}

在bean.xml中加入:
<bean id="pdf" class="spring.MyPdfView">
</bean>

最後控制器中要返回:return new ModelAndView("pdf");

就可以了。


=====================================================

生成Excel也是用了一個框架

與生成PDF類似,生成Excel時也要定義Excel的視圖對象,它必須由AbstractExcelView
擴展而來。要重寫其中的void buildExcelDocument(Map model, HSSFWorkbook workbook,
HttpServletRequest request, HttpServletResponse response)方法,用於組裝Excel文檔。

HSSFWorkbook位於org.apache.poi.hssf.usermodel 包,是apache的另一個開源項目
Jakarta POI,網址是http://jakarta.apache.org/poi
整個POI項目主要用於生成MS的一些文檔,如Excel、Word等等。具體參考其官方文檔

public class MyExcelView extends AbstractExcelView {
 public void buildExcelDocument(Map model, HSSFWorkbook workbook,
   HttpServletRequest request, HttpServletResponse response)
   throws Exception {
  HSSFSheet sheet = workbook.createSheet("first");
  HSSFRow header = sheet.createRow(0);
  header.createCell((short) 0).setCellValue("id");
  header.createCell((short) 1).setCellValue("msg");
  HSSFRow r1 = sheet.createRow(1);
  r1.createCell((short) 0).setCellValue(1);
  r1.createCell((short) 1).setCellValue((String) model.get("msg"));
 }
}

例:POI的位置:spring文件夾的lib文件夾裏面:poi-2.5.1.jar

package spring ;

public class MyExcelView extends AbstractExcelView
{
 public void buildExcelDocument(Map model,HSSFWorkbook workbook,HttpServletRequest request,
  HttpServletResponse response)
 {
  HSSFSheet sheet = workbook.createSheet("first");
  HSSFRow header = sheet.createRow(0);
  header.createCell((short) 0).setCellValue("id");
  header.createCell((short) 1).setCellValue("msg");
  HSSFRow r1 = sheet.createRow(1);
  r1.createCell((short) 0).setCellValue(1);
  r1.createCell((short) 1).setCellValue((String) model.get("msg"));
 }
}

<bean id="excel" class="spring.MyExcelView">
</bean>

return new ModelAndView("excel","msg","hello,poi!") ;
================================================================================
重要的知識點:Spring自己的MVC,以及怎麼集成Struts……

總控制器是DispatcherServlet,剩下的地址去諮詢HandlerMapping,
一般情況下默認使用BeanNameUrlHandlerMapping,還有SimpleUrlHandlerMapping
Controller控制器返回ModelAndView,由這個ModelAndView去找ViewResolver,
最後ViewResolver解析成View

ViewResolver:InternalResourseViewResolver、BeanNameViewResolver

集成Struts:
1、直接繼承ActionSupport
2、使用Action代理DelegatingActionProxy
3、使用DelegatingRequestProcessor模塊控制器代理

Controller裏面有一個對錶單處理的細節,可以參考Spring的技術手冊。

Action的execute之前可以對錶單進行校驗,在Spring中通過使用一個Interceptor
攔截器進行處理,Spring技術手冊中也有介紹。

==================================================================

RMI與JNDI:
RMI:遠程方法調用(Remote Method Invocation)是面向對象的。
RPC:遠程過程調用(面向過程的)

RMI是EJB技術基礎之一,它使得EJB能夠分佈在不同服務器上,但卻可以協同工作。
開發RMI的步驟: 1、定義遠程接口 2、給出遠程接口的實現類 3、用rmic編譯實現類,
生成stub和skeleton4、向註冊表註冊5、編寫客戶端程序,客戶端程序需要包含有stub


什麼叫做遠程:兩個虛擬機之間的調用就叫做遠程調用

RMI可以使這種遠程的調用可以像本地調用一樣的簡單
如果沒有RMI就必須創建Socket纔可以,有了RMI就可以直接到另一個虛擬機上面找
對象然後直接調用了。

遠程接口,擴展自Remote接口的接口。
------------------------------------------------------
java.rmi.Remote就是遠程接口,這又是一個空接口,和Serializable、
cloneable、JspTag一樣都是空接口。
新建一個接口,這個接口必須是public而且擴展自Remote接口,接口中定義的方法
是可以供用戶調用的業務方法,所有的業務方法都必須要拋出java.rmi.RemoteException
HelloWorld.java:
package first ;

import java.rmi.Remote ;

public interface HelloWorld extends Remote
{
 public String sayHello(String name)
  throws java.rmi.RemoteException;
}

HelloWorldImpl.java:

package first ;
import java.rim.server.UnicastRemoteObject ;
public class HelloWorldImpl extends UnicastRemoteObject,implements HelloWorld
{
 //這個空的構造函數必須有,且必須得像下面這樣拋出異常!
 public HelloWorldImpl() throws java.rmi.RemoteException
 {
 
 }

 public String sayHello(String name)
  throws java.rmi.RemoteException
  //注意,這個異常可以不拋出!!!
 {
  return "Hello,"+name ;
 }
}

注意遠程對象要綁到rmiregistry上面去。

package first ;
import java.rmi.Naming ;
public class RunRmi
{
 public static void main(String[] args) throws Exception
 {
  HelloWorld hw = new HelloWorldImpl() ;//遠程對象
  Registry reg = LocateRegistry.createRegistry(1099);
  Naming.rebind("//localhost/hello",hw);
  //向指定機器的rmi註冊表裏綁定一個對象名字叫做hello,端口是1099
  //一個對象綁定到一個名字上,是JNDI(java naming and directory Interface)
  //也就是“命名與目錄服務”所幹的事情
 }
}

package first ;
import java.rmi.Naming ;
public class Client
{
 public static void main(String[] args) throws Exception
 {
  
  
  HelloWorld hw = (HelloWorld)Naming.lookup("//162.105.81.190/hello",hw);
  System.out.println(hw.sayHello("World"));
  //向指定機器的rmi註冊表裏綁定一個對象名字叫做hello,端口是1099
  //一個對象綁定到一個名字上,是JNDI(java naming and directory Interface)
  //也就是“命名與目錄服務”所幹的事情
 }
}
javac -d classes HelloWorld.java(將這個java文件編譯後的類文件放到classes文件夾裏面)
javac -d classes -classpath .;classes HelloWorldImpl.java
javac -d classes -classpath .;classes RunRmi.java
javac -d classes -classpath .;classes Client.java

還得生成stub和singleton對象。
通過命令:
rmic first.HelloWorldImpl
生成HelloWorldImpl_Stub.class

然後使用命令rmiregistry啓動rmi註冊表,
java first.Client


====================================================================================
老師寫的標準代碼:


HelloWorld.java:
package first;

import java.rmi.Remote;

public interface HelloWorld extends Remote
{
 public String sayHello(String name) throws java.rmi.RemoteException;
}
----------------------------------
HelloWorldImpl.java
package first;

import java.rmi.server.UnicastRemoteObject;
import java.rmi.Naming;

public class HelloWorldImpl extends UnicastRemoteObject implements HelloWorld
{
 public HelloWorldImpl() throws java.rmi.RemoteException {
 }

 public String sayHello(String name) {
  return "Hello, "+name;
 }
 
}
----------------------------------
RunRmi.java//服務器端把創建出的對象綁到本地的rmi註冊表的一個叫做hello的名字上面
package first;

import java.rmi.Naming;
import java.rmi.registry.*;


public class RunRmi
{
 public static void main(String[] args) throws Exception {
  HelloWorld impl = new HelloWorldImpl();
        Registry reg = LocateRegistry.createRegistry(1099);
  //注意上面那句話可以不寫,但是如果不寫的話,要求你必須在對應類路徑下輸入命令
  //rmiregistry,然後客戶端虛擬機就可以運行Client.class了。
  //如果寫上了上面那句話,就需要在服務器中運行RunRmi程序,然後客戶端才能運行Client.class。
        Naming.rebind("//localhost/hello", impl);
        System.out.println("Server ok!");
 }
}
--------------------------------------------
Client.java://客戶端通過lookup的方法從hello這個名字上把服務器的對象拿過來,然後調用方法。
package first;

import java.rmi.Naming;
import java.rmi.registry.*;
public class Client
{
 public static void main(String[] args) throws Exception {
  
        HelloWorld hw = (HelloWorld)Naming.lookup("//162.105.81.190/hello");
        System.out.println(hw.sayHello("World"));
 }
}
-----------------------------
==============================================================================

sql語句(比如用一條語句實現一些複雜功能)、java基礎(275試題)、數據庫原理、設計模式和uml畫類圖
Struts問的頻率是最高的、Hibernate其次、Spring被問到的是最少的。

java275認證試題很重要
還有314認證和285認證


==================================================================================

public class RmiDemo
{
 public static void main(String[] args)
 {
  ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
  HelloWorld hw = (HelloWorld)context.getBean("hw");
  Systenm.out.println(hw.sayHello("World"));
 }
}

bean.xml中的依賴注入寫法:

<bean id="hw" class="org.springframework.remoting.rmi.RmiProxyFactoryBean">
 <property name="serviceUrl" value="rmi://localhost:1099/hello" />
 //注意,如果是在客戶機上配置的話,要把localhost換成服務器端的ip地址。
 <property name="serviceInterface" value="first.HelloWorld" />
</bean>

先進入命令行,
start rmiregistry 1199
java first.RunRmi

這樣就提供了遠程服務!
===========================================================================
面試過兩關:一是HR這一關(主要看這個人的溝通能力和人品方面,HR希望找一個踏實的、能幹活
的人,溝通能力很重要,一定要表現的踏實一些);第二關是過技術經理這一關,到這裏的時候可能
會被問到這樣一些問題(比如“我這裏有蟲子,還有瓶子,蟲子每過一分鐘就會自我複製,或是自我分裂,
蟲子充滿這個瓶子,那麼…………”,考你的潛力之類的)。面對面試你的技術人員絕對不能夠裝懂,這是最
忌諱的

-------------------------------------------------------------------------
遞歸是很好用的東西,使用遞歸的時候你不需要考慮太多的東西,儘管交給程序去做它想做的事情,你只要
定義好規則,遞歸的調用處理是程序着急的問題,你不用着急

比如快速排序的算法如下:
使用快速排序方法對a[ 0 :n- 1 ]排序
從a[ 0 :n- 1 ]中選擇一個元素作爲m i d d l e,該元素爲支點
把餘下的元素分割爲兩段left 和r i g h t,使得l e f t中的元素都小於等於支點,而right 中的元素都大於等於支點
遞歸地使用快速排序方法對left 進行排序
遞歸地使用快速排序方法對right 進行排序
所得結果爲l e f t + m i d d l e + r i g h t

代碼可以如下實現:

package com.yuanbin.sort;

import java.util.ArrayList;
import java.util.List;

public class Demo {
 
 public static int[] findRight(int[] a, int middlePoint)
 {
  List list = new ArrayList();
  
  for(int i = 0 ; i < a.length ; i ++)
  {
   if(a[i] > middlePoint)
   {
    list.add(new Integer(a[i]));
   }
  }
  
  int length = list.size();
  int[] right = new int[length] ;
  for(int i = 0 ; i < length ; i ++)
  {
   right[i] = ((Integer)list.get(i)).intValue();
  }
  return right ;
 }
 
 public static int[] findLeft(int[] a, int middlePoint)
 {
  List list = new ArrayList();
  
  for(int i = 0 ; i < a.length ; i ++)
  {
   if(a[i] < middlePoint)
   {
    list.add(new Integer(a[i]));
   }
  }
  
  int length = list.size();
  int[] left = new int[length] ;
  for(int i = 0 ; i < length ; i ++)
  {
   left[i] = ((Integer)list.get(i)).intValue();
  }
  return left ;
 }
 
 public static int[] QuickSort(int[] a)
 {
  
  if(a.length > 1)
  {
   int[] left = findLeft(a,a[a.length / 2]);
   int[] right = findRight(a,a[a.length / 2]);
   int leftLength = left.length ;
   int rightLength = right.length ;
   
   int[] leftReal = QuickSort(left);
   int[] rightReal = QuickSort(right);
   
   int[] result = new int[leftLength + rightLength + 1];
   
   for(int i = 0 ; i < leftLength ; i ++)
   {
    result[i] = leftReal[i] ;    
   }
   result[leftLength] = a[a.length / 2] ;
   
   int k = 0 ;
   for(int i = leftLength + 1 ; i < result.length ; i ++)
   {
    result[i] = rightReal[k] ;
    k ++ ;
   }
   return result ;
  }
  return a ;
 }
 
 public static void main(String[] args)
 {
  int[] a = {44,67,2,9,1,88,22,14,54,-1,-33,22,19} ;
  int[] result = QuickSort(a) ;
  for(int i = 0 ; i < result.length ; i ++)
  {
   System.out.print(result[i]+"   ");
  }
  System.out.println();
 }
}

雖然結果是對的,但是上面的代碼寫的很傻,我也知道……

 

 

發佈了111 篇原創文章 · 獲贊 6 · 訪問量 18萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章