3月15日——培训第80天

本文详细介绍了SpringMVC框架中的关键组件HandlerMapping和ViewResolver的作用及配置方式,并提供了具体的XML配置示例和控制器代码样例。此外还探讨了如何自定义视图,包括生成PDF和Excel文件的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天说一下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();
 }
}

虽然结果是对的,但是上面的代码写的很傻,我也知道……

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值