2006年10月12日
display-name元素提供GUI工具可能会用来标记这个特定的Web应用的一个名称
description元素给出与此有关的说明性文本
context-param元素声明应用范围内的初始化参数。
filter 过滤器元素将一个名字与一个实现javax.servlet.Filter接口的类相关联
filter-mapping 命名一个过滤器后,就要利用filter-mapping元素把它与一个或多个servlet或JSP页面相关联。
listener servlet API的版本2.3增加了对事件监听程序的支持,事件监听程序在建立、修改和删除会话或 servlet环境时得到通知。Listener元素指出事件监听程序类。
servlet 在向servlet或JSP页面制定初始化参数或定制URL时,必须首先命名servlet或JSP页面。Servlet元素就是用来完成此项任务的。
servlet-mapping 服务器一般为servlet提供一个缺省的URL:
http://host/webAppPrefix/servlet/ServletName。但是,常常会更改这个URL,以便servlet可以访问初始化参数或更容易地处理相对URL。在更改缺省URL时,使用servlet-mapping元素。
session-config 如果某个会话在一定时间内未被访问,服务器可以抛弃它以节省内存。可通过使用HttpSession的setMaxInactiveInterval方法 明确设置单个会话对象的超时值,或者可利用session-config元素制定缺省超时值。
mime-mapping 如果Web应用具有想到特殊的文件,希望能保证给他们分配特定的MIME类型,则mime-mapping元素提供这种保证。
welcome-file-list元素指示服务器在收到引用一个目录名而不是文件名的URL时,使用哪个文件。
error-page元素使得在返回特定HTTP状态代码时,或者特定类型的异常被抛出时,能够制定将要显示的页面。
taglib元素对标记库描述符文件(Tag Libraryu Descriptor file)指定别名。此功能使你能够更改TLD文件的位置,而不用编辑使用这些文件的JSP页面。
resource-env-ref 元素声明与资源相关的一个管理对象。
resource-ref 元素声明一个资源工厂使用的外部资源。
security-constraint 元素制定应该保护的URL。它与login-config元素联合使用
login-config元素来指定服务器应该怎样给试图访问受保护页面的用户授权。它与sercurity-constraint元素联合使用。
security-role 元素给出安全角色的一个列表,这些角色将出现在servlet元素内的security-role-ref元素的role-name子元素中。分别地声明角色可使高级IDE处理安全信息更为容易。
env-entry 元素声明Web应用的环境项。
ejb-ref 元素声明一个EJB的主目录的引用。
ejb-local-ref 元素声明一个EJB的本地主目录的应用。
一般的MVC框架处理的问题包括
1.将web页面中的输入元素封装成为一个(请求)数据对象。
2.根据请求不同调用相应的逻辑处理单元,并将(请求)数据对象作为参数传入。
3.逻辑处理单元完成运算后,返回一个结果数据对象。
4.将结果数据对象中的数据与预先设计好的表现层相融合并展现给用户。
1.介绍一下junit
junit是一个用来单元测试的工具,它可以针对一个/多个类的单个或多个方法进行测试,还可以自动化套件测试.将junit.jar包从www.junit.org.载下来放到eclipse 项目中的java build path中.
2.创建一个TestCase
File > New > JUnit Test Case 或者点击""来创建一个TestCase
代码如下
import junit.framework.TestCase;
public class SampleTest extends TestCase {
private java.util.List emptyList;
/**
* Sets up the test fixture.
* (Called before every test case method.)
*/
protected void setUp() {
emptyList = new java.util.ArrayList();
}
/**
* Tears down the test fixture.
* (Called after every test case method.)
*/
protected void tearDown() {
emptyList = null;
}
public void testSomeBehavior() {
assertEquals("Empty list should have 0 elements", 0, emptyList.size());
}
public void testForException() {
try {
Object o = emptyList.get(0);
fail("Should raise an IndexOutOfBoundsException");
}
catch (IndexOutOfBoundsException success) {
}
}
}
这个例子有两个方法需要测试,第一个方法测试list中没有任何对象,第二个方法测试没有使用断言,它一定会成功
3.创建一个TestSuite
通过测试套件可以运行多个测试用例
(3.1)选择 File > New > Other... > Java > JUnit > JUnit Test Suite. 或者Other... > Java > JUnit > JUnit Test Suite,
import junit.framework.Test;
import junit.framework.TestSuite;
public class AllTests {
public static Test suite() {
TestSuite suite = new TestSuite("Test for com.xu.Test");
//$JUnit-BEGIN$
suite.addTestSuite(SampleTest .class);
//$JUnit-END$
return suite;
}
}
Inversion
of Control Containers(IOC)由容器来控制程序间的关系,而非程序来控制,就是所谓的容器控制反转。
Dependency Injection 容器动态的将某种动态关系注入到主键当中。
依赖注入的几种实现
type1 接口注入
public class ClassA {
private InterfaceB clzB;
public doSomething() {
Ojbect obj =
Class.forName(Config.BImplementation).newInstance();
clzB = (InterfaceB)obj;
clzB.doIt()
}
……
}
我们通过配置文件动态的加载类,然后强制转换成相应的类来实现动态注入,对于IOC容器来说加载类的过程由容器来完成。
web容器采用type1 接口注入的具体应用
public class MyServlet extends HttpServlet {
public void doGet(
HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
……
}
}
Type2 设值注入 它由容器通过Setter方法完成依赖关系的设置
Type3构造了注入
public class DIByConstructor {
private final DataSource dataSource;
private final String message;
public DIByConstructor(DataSource ds, String msg) {
this.dataSource = ds;
this.message = msg;
}
……
}
Bean Wrapper
由容器将依赖关系注入到组件当中,在运行期间由spring根据配置文件,将其它对象的引用通过组件提供的setter方法进行设定。运行期间动态生成对象并设定它对依赖关系.
Object obj = Class.forName("net.xiaxin.beans.User").newInstance();
BeanWrapper bw = new BeanWrapperImpl(obj);
bw.setPropertyValue("name", "Erica");
System.out.println("User name=>"+bw.getPropertyValue("name"));
Bean Factory
创建并且维护Bean实例它可以配置
1. Bean的属性值及其依赖关系(即对其它Bean的引用)
2. Bean的创建模式(是否单例模式)
3. Bean的初始化和销毁方法
4. Bean的依赖关系
ApplicationContext
覆盖了BeanFactory所有的方法,而且提供了新的功能。它有以下扩展功能
1.国际化的支持
2.资源访问
3.事件传播
4.多实例加载
spring提供了可配置的ApplicationContext加载机制。加载器有两种选择:ContextLoaderListener或ContextLoaderServlet一个利用servlet2.3的Listener接口实现而另一个则利用Servlet接口实现。
在web.xml中加入
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
或者:
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>
org.springframework.web.context.ContextLoaderServlet
</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
Web容器会自动加载WEB-INF/applicationContext.xml初始化ApplicationContext实例.如果你指定配置文件就可以通过context-param指定:
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/myApplicationContext.xml</param-value>
</context-param>
配置完成后就可以通过WebApplicationContextUtils.getWebApplicationContext方法在Web应用中获取ApplicationContext的引用.
spring至关重要的一环就是装配,即配置文件的编写,接下来我按刚才实际过程中一步步简单讲解。
首先,要在web.xml中配置DispatcherServlet,它是作为Spring MVC的前端控制器.必须在web.xml中配置好,如下
<
servlet
>
<servlet-name>ntx</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
实际上,spring的配置文件可以分切到多个xml文件,我们这个简单的示例就把它配置到ntx.xml中
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC
"-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans
default-autowire="no"
default-lazy-init="false"
default-dependency-check="none"
>
<bean id="loginService" class="ntx.service.serviceimpl.LoginServiceImpl"/>
<bean id="loginController" class="ntx.controller.LoginController">
<property name="loginService">
<ref bean="loginService"/>
</property>
<property name="gotoUrl">
<value>/showResult.jsp</value>
</property>
</bean>
<bean id="SimpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/userLogin.do">loginController</prop>
</props>
</property>
</bean>
</beans>
配置好上面的这些后,要在WEB-INF下要建立ntx-servlet.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="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass"><value>org.springframework.web.servlet.view.JstlView</value></property>
<property name="prefix"><value></value></property>
<property name="suffix"><value></value></property>
</bean>
</beans>
接下来,要指明哪些请求将交给spring的DispatcherServlet来处理,所以在web.xml中添加<servlet-mapping>
<servlet-mapping>
<servlet-name>ntx</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
为了能正确载入DispatcherServlet等配置文件,我们要在web.xml中配置一个上下文载入器ContextLoaderListener或者ContextLoaderServlet,我们这里为了兼容版本较低的Serlvet容器(实际上我采用的2.4),采用第二种:
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
这样就全部配置完毕了,当然,上面的ntx.xml是我在项目完成以后才配置完成的,这里不再多讲,有bean元素的配置大家可以参考有关资料理解,很容易理解的,下面再给出完整的web.xml配置以及java
<?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">
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/ntx.xml</param-value>
</context-param>
<servlet>
<servlet-name>ntx</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>context</servlet-name>
<servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
<load-on-startup>100</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ntx</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
根据ntx.xml知道,总共有三个java文件,LoginController.java是控制器,继承了最简单的Controller(实际上spring有很多控制器供我们选择),接下来是一个简单控制器的源码
package ntx.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.Controller;
import ntx.service.LoginService;
public class LoginController implements Controller...{
private LoginService loginService ;
private String gotoUrl;
public ModelAndView handleRequest(HttpServletRequest request,HttpServletResponse response) throws Exception ...{
String userName = request.getParameter("userName");
this.getUserInfo(request, userName);
return new ModelAndView(this.getGotoUrl());
}
private void getUserInfo(HttpServletRequest request,String userName)...{
String userInfo = loginService.getUserInfo(userName);
request.setAttribute("userInfo", userInfo);
}
public String getGotoUrl() ...{
return gotoUrl;
}
public void setGotoUrl(String gotoUrl) ...{
this.gotoUrl = gotoUrl;
}
public LoginService getLoginService() ...{
return loginService;
}
public void setLoginService(LoginService loginService) ...{
this.loginService = loginService;
}
}
还有service层的接口以及实现,较简单,
package ntx.service;
public interface LoginService ...{
public String getUserInfo(String userName);
}
package ntx.service.serviceimpl;
import ntx.service.LoginService;
public class LoginServiceImpl implements LoginService ...{
public String getUserInfo(String userName)...{
return "你的名字是:" + userName;
}
}
好了,最后是两个jsp文件,一个index.jsp用来显示一个表单,输入名字,一个showResult.jsp用来显示结果,只贴出相关的代码
<body>
This is my Test Spring page. <br>
<div>
<form method="post" action="/userLogin.do">
<input type="text" name="userName" size="30"/><br/>
<input type="submit" value="提交"/>
</form>
</div>
</body>
<body>
This is the Result: <br>
<c:out value="${userInfo}" default="没有结果"/>
</body>
发布到tomcat或者其它Servlet容器可以正常使用,提交以后将显示:
This is the Result:
你的名字是:gavin
1.用变量引用函数,该变量执行和函数一样的效果
函数定义以后 如 function square(x) { return x*x;}
我们可以 var a = square(4) a 16
var b = square b 就相当于函数squre,它是squre的一个引用,执行效果一样
var c = b(10) c 100
2.将函数指定为一个对象属性的用法
var o = new Object;
o.square = new Function("x","return x*x;");
var y = o.square(10);
3.利用函数直接量,将它赋给数组元素;
var a = new Array(3);
a[0] = function(x){return x*x;};
a[1] = 10;
a[2] = a[0](a[1]);
alert("a[2] = "+a[2]);
4.将函数做为数据
function add(x,y){ return x+y};
function subtract(x,y){return x-y};
function multiply(x,y){return x*y};
function divide(x,y){return x/y};
function operate(operator,operand1,operand2){
return operator(operand1,operand2);
}
var i = operate(add,operate(add,2,3),subtract(10,8));
alert(i);