今天说一下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();
}
}
虽然结果是对的,但是上面的代码写的很傻,我也知道……