参考:Sping 2.0.8\docs\MVC-step-by-step
实现目标
编写一个ShirdrnController,实现了org.springframework.web.servlet.mvc.Controller接口;
使用JSP文件作为视图,将控制器返回的Model渲染出来,JSP文件中使用了JSTL;
使用InternalResourceViewResolver实现视图的解析。
准备工作
工程结构如下所示:
SpringMVCViewResolver
│ .classpath
│ .mymetadata
│ .project
│ .springBeans
│
├─.myeclipse
├─src
│ └─org
│ └─shirdrn
│ ├─beans
│ │ PersonBean.java
│ │
│ └─spring
│ └─controller
│ ShirdrnController.java
│
└─WebRoot
│ index.jsp
│ persons.jsp
│
├─META-INF
│ MANIFEST.MF
│
└─WEB-INF
│ c-1_0-rt.tld
│ c-1_0.tld
│ c.tld
│ fmt-1_0-rt.tld
│ fmt-1_0.tld
│ fmt.tld
│ fn.tld
│ permittedTaglibs.tld
│ scriptfree.tld
│ shirdrn-servlet.xml
│ spring.tld
│ sql-1_0-rt.tld
│ sql-1_0.tld
│ sql.tld
│ web.xml
│ x-1_0-rt.tld
│ x-1_0.tld
│ x.tld
│
├─classes
│ └─org
│ └─shirdrn
│ ├─beans
│ │ PersonBean.class
│ │
│ └─spring
│ └─controller
│ ShirdrnController.class
│
└─lib
commons-attributes-api.jar
commons-attributes-compiler.jar
commons-beanutils.jar
commons-collections.jar
commons-digester.jar
commons-fileupload.jar
commons-httpclient.jar
commons-lang.jar
commons-logging.jar
cos.jar
dom4j-1.6.jar
freemarker.jar
itext-1.3.jar
jakarta-oro-2.0.8.jar
jasperreports-1.0.3.jar
jaxen-1.1-beta-4.jar
jstl.jar
jxl.jar
log4j-1.2.13.jar
poi-2.5.1.jar
spring-beans.jar
spring-context.jar
spring-core.jar
spring-web.jar
spring-webmvc.jar
standard.jar
velocity-1.4.jar
velocity-tools-generic-1.2.jar
velocity-tools-view-1.2.jar
其中,PersonBean就是一个POJO,如下所示:
package org.shirdrn.beans;
import java.io.Serializable;
import java.util.Date;
public class PersonBean implements Serializable {
private Integer id;
private String name;
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
实现过程
为了清晰,我按照步骤实现,如下所示:
第一步,注入List。
在该ShirdrnController控制器中使用Setter注入了一个PersonBean的List,作为Model,因此,首先要在shirdrn-servlet.xml中注入PersonBean的List中的每一个Person,这里注入了3个bean,如下所示:
<bean id="personABean" class="org.shirdrn.beans.PersonBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="id">
<value>1001</value>
</property>
<property name="name">
<value>张叁</value>
</property>
<property name="email">
<value>[email protected]</value>
</property>
</bean>
<bean id="personBBean" class="org.shirdrn.beans.PersonBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="id">
<value>1002</value>
</property>
<property name="name">
<value>王者</value>
</property>
<property name="email">
<value>[email protected]</value>
</property>
</bean>
<bean id="personCBean" class="org.shirdrn.beans.PersonBean"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="id">
<value>1003</value>
</property>
<property name="name">
<value>将军</value>
</property>
<property name="email">
<value>[email protected]</value>
</property>
</bean>
将List注入到ShirdrnController中,在shirdrn-servlet.xml文件中配置如下:
<bean id="shirdrnController"
class="org.shirdrn.spring.controller.ShirdrnController"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="personsBean">
<list>
<ref bean="personABean" />
<ref bean="personBBean" />
<ref bean="personCBean" />
</list>
</property>
</bean>
第二步,实现ShirdrnController,如下所示:
package org.shirdrn.spring.controller;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
public class ShirdrnController implements Controller {
private List personsBean;
public List getPersonsBean() {
return personsBean;
}
public void setPersonsBean(List personsBean) {
this.personsBean = personsBean;
}
public ModelAndView handleRequest(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
return new ModelAndView("persons","persons",getPersonsBean());
}
}
这里,返回了return new ModelAndView("persons","persons",getPersonsBean());,其中,第一个“persons”是视图文件的名称,对应于JSP文件persons.jsp,第二个“persons”就是Model。一个PersonBean的List。
第三步,定义HandlerMapping,URL映射方式。
仍然使用SimpleUrlHandlerMapping映射方式,在shirdrn-servlet.xml文件中配置URL映射方式,如下所示:
<bean id="shirdrnUrlMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="mappings">
<props>
<prop key="/shirdrn.xyz">shirdrnController</prop>
</props>
</property>
</bean>
当请求的URL为shirdrn.xyz的时候,使用控制器ShirdrnController进行控制转发,然后再交由中央控制器DispatcherServlet,选择合适的视图解析器,实现视图的派发。
第四步,配置视图解析器。
在shirdrn-servlet.xml文件中,配置视图解析器,如下所示:
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver"
abstract="false" singleton="true" lazy-init="default"
autowire="default" dependency-check="default">
<property name="viewClass">
<value>org.springframework.web.servlet.view.JstlView</value>
</property>
<property name="prefix">
<value>/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
bean为viewResolver,使用InternalResourceViewResolver视图解析器进行视图的解析。
这里的property的name很关键:
viewClass指定了选择何种视图技术,这里使用JSTL技术;
prefix是视图文件的前缀,即目录名,因为我们把persons.jsp放到了目录/WebRoot/之下,所以只需要配置一个“/”,如果放在目录/WebRoot/目录下的一个名称为view的目录中,这里prefix的值应该为/view/;
suffix是视图文件的后缀,即扩展名,如使用JSP文件,则为“.jsp”。
第五步,实现视图文件。
这里是用到了两个JSP文件,分别如下。
index.jsp文件,是一个中间转发页面,实现了定向,定向到/shirdrn.xyz:
<%@ page session="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ page language="java" pageEncoding="UTF-8"%>
<c:redirect url="/shirdrn.xyz"></c:redirect>
persons.jsp,实现视图的渲染,显示数据:
<%@ page session="false"%>
< prefix="c" uri=">
<%@ taglib prefix="fmt" uri="http://java.sun.com/jstl/fmt" %>
<%@ page language="java" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>人员列表页面</title>
<style type="text/css">
body{
font-size:16px;
color:yellow;
}
</style>
</head>
<body bgcolor="#FFFFFF">
<table bgcolor="green" border="1" borderColor="#FFFFFF" align="center" width="100%">
<tr>
<td colspan="3"><b>人员列表如下</td>
</tr>
<tr>
<td>ID</td><td>姓名</td><td>Email</td>
</tr>
<c:forEach items="${persons}" var="person">
<tr>
<td><c:out value="${person.id}" /></td>
<td><c:out value="${person.name}" /></td>
<td><c:out value="${person.email}" /></td>
</tr>
</c:forEach>
</table>
</body>
</html>
第六步,配置应用的web.xml文件。
在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>shirdrn</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>shirdrn</servlet-name>
<url-pattern>*.xyz</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
测试实现
启动Tomcat Web Server。
在浏览器地址栏中键入链接地址http://localhost:8080/SpringMVCViewResolver/shirdrn.xyz,显示如图所示:
关于异常
因为是第一次使用JSTL,感觉挺新鲜的。
需要两个jar包:standard.jar和jstl.jar。
但还是除了点异常:
org.apache.jasper.JasperException: /persons.jsp(27,4) According to TLD or attribute directive in tag file, attribute items does not accept any expressions
org.apache.jasper.compiler.DefaultErrorHandler.jspError(DefaultErrorHandler.java:39)
org.apache.jasper.compiler.ErrorDispatcher.dispatch(ErrorDispatcher.java:405)
org.apache.jasper.compiler.ErrorDispatcher.jspError(ErrorDispatcher.java:146)
org.apache.jasper.compiler.Validator$ValidateVisitor.checkXmlAttributes(Validator.java:955)
org.apache.jasper.compiler.Validator$ValidateVisitor.visit(Validator.java:710)
org.apache.jasper.compiler.Node$CustomTag.accept(Node.java:1441)
org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2163)
org.apache.jasper.compiler.Node$Visitor.visitBody(Node.java:2213)
org.apache.jasper.compiler.Node$Visitor.visit(Node.java:2219)
org.apache.jasper.compiler.Node$Root.accept(Node.java:456)
org.apache.jasper.compiler.Node$Nodes.visit(Node.java:2163)
org.apache.jasper.compiler.Validator.validate(Validator.java:1489)
org.apache.jasper.compiler.Compiler.generateJava(Compiler.java:157)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:286)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:267)
org.apache.jasper.compiler.Compiler.compile(Compiler.java:255)
org.apache.jasper.JspCompilationContext.compile(JspCompilationContext.java:556)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:293)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:291)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:241)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
org.springframework.web.servlet.view.InternalResourceView.renderMergedOutputModel(InternalResourceView.java:111)
org.springframework.web.servlet.view.AbstractView.render(AbstractView.java:250)
org.springframework.web.servlet.DispatcherServlet.render(DispatcherServlet.java:965)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:744)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:663)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:394)
org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:348)
javax.servlet.http.HttpServlet.service(HttpServlet.java:689)
javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
异常信息提示:items属性不能够接受任何表达式,其实怎么可能呢,不接受怎么渲染视图啊。
实际上一个版本的问题,将JSP页面中:
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
应该改为:
< prefix="c" uri=">
这样就解决了。