今天說一下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();
}
}
雖然結果是對的,但是上面的代碼寫的很傻,我也知道……