2006年8月24日
1.index.html
<iframe id="mainIframe" scrolling="no" frameborder="0" width="100%" src="a.html"></iframe>
<a href="#" onclick="page('a.html')">a页面</a><a href="#" onclick="page('b.html')">b页面</a>
2 a.html //内嵌页面
<script language="javascript">
changeHight();
</script>
3. b.html //内嵌页面
<script language="javascript">
changeHight();
</script>
4. page.js
function changeHight(){
var iFrm = parent.document.getElementById("mainIframe");
var subWeb = iFrm.contentDocument;
if(subWeb){
if (subWeb.body.scrollHeight>480)
iFrm.height = subWeb.body.scrollHeight+20;
else
iFrm.height=500;
}
if(top.document.frames["mainIframe"].document && window.document.body.scrollHeight!="0"){
parent.document.getElementById("mainIframe").style.height=window.document.body.scrollHeight;
}
if(top.document.frames["mainIframe"].document && window.document.body.scrollHeight=="0"){
parent.document.getElementById("mainIframe").style.height=500;
}
}
function page(page){
document.getElementById("mainIframe").src=page;
}
造成IE,FireFox,Opera中Iframe显示差异原因在于
1.iframe在FireFox中取法为parent.document.getElementById("mainIframe").contentDocument,而在ie,opera中为parent.document.getElementById("mainIframe").document
2.当页面无滚动时,window.document.body.scrollHeight在IE中能取到,fireFox和Opera中取不到。
摘要: 1.myapp/index.html
<html>
<head>
文件操作
<iframe id="iframefile" scrolling="no" frameborder="0" width="100%" src="/myapp/fileUpload.jsp"></iframe>
&l...
阅读全文
一些频繁使用的javascript页面控制,做个总结。
下面是部分代码。
<html>
<head>
<script language="javascript">
function a(){
window.document.getElementsByName("dx")[0].checked=true;
}
function b(){
window.document.getElementsByName("dx")[0].checked=false;
}
function c(){
window.document.getElementsByName("fx")[0].checked=true;
}
function d(){
window.document.getElementsByName("fx")[0].checked=false;
}
function e(){
for(i=0;i<window.document.getElementsByName("fx").length;i++){
if(!window.document.getElementsByName("fx")[i].checked){
window.document.getElementsByName("fx")[i].checked=true;
}
}
}
function f(){
for(i=0;i<window.document.getElementsByName("fx").length;i++){
if(window.document.getElementsByName("fx")[i].checked){
window.document.getElementsByName("fx")[i].checked=false;
}
}
}
function g(){
window.document.getElementById("lbka")[1].selected=true;
}
function h(){
alert("选择号为:"+window.document.getElementById("lbka").selectedIndex + " 值为:" +window.document.getElementById("lbka")[window.document.getElementById("lbka").selectedIndex].value+" 文本值为:" + window.document.getElementById("lbka")[window.document.getElementById("lbka").selectedIndex].text);
}
function m(){
sel = false;
var val="";
for(i=0;i<window.document.getElementsByName("dx").length;i++){
if(window.document.getElementsByName("dx")[i].checked){
val = window.document.getElementsByName("dx")[i].value;
sel=true;
break;
}
}
if(sel){
alert("单选值为:"+val);
}else{
alert("请选择文件");
return false;
}
}
function j(){
var sel = false;
var val="";
for(i=0;i<window.document.getElementsByName("fx").length;i++){
if(window.document.getElementsByName("fx")[i].checked){
if(val==""){
val=window.document.getElementsByName("fx")[i].value;
}else{
val = val + "," +window.document.getElementsByName("fx")[i].value;
}
}
}
if(val==""){
alert("请选择文件");
return false;
}else{
alert("复选值为:"+val);
}
}
</script>
</head>
<body>
<table id="table1" width="100%" border="1" align="center" cellpadding="0" cellspacing="0">
<tr>
<td>文件</td>
<td>列表框</td>
<td>单选</td>
<td>复选</td>
</tr>
<tr>
<td>文件A</td>
<td><select name="lbka"><option value="lbka1">文件A1</option><option value="lbka2">文件A2</option></select></td>
<td><input type="radio" name="dx" value="dxa"></td>
<td><input type="checkbox" name="fx" value="fxa"></td>
</tr>
<tr>
<td>文件B</td>
<td><select name="lbkb"><option value="lbkb1">文件B1</option><option value="lbkb2">文件B2</option></select></td>
<td><input type="radio" name="dx" value="dxb"></td>
<td><input type="checkbox" name="fx" value="fxb"></td>
</tr>
<tr>
<td colspan="4">
<a href="#" onclick="a();">单选A选中</a>
<a href="#" onclick="b();">单选A不选中</a>
<a href="#" onclick="c();">复选A选中</a>
<a href="#" onclick="d();">复选A不选中</a>
<a href="#" onclick="e();">复选全选</a>
<a href="#" onclick="f();">复选全不选</a>
<a href="#" onclick="g();">选中列表框文件A2</a>
<a href="#" onclick="h();">取得选中列表框A的值,文本</a>
<a href="#" onclick="m();">判断单选选择</a>
<a href="#" onclick="j();">判断复选选择</a>
</td>
</tr>
</table>
</body>
</html>
主要通过javascript实现,理解IE的DOM结构,并调用元素的固定方法,可以实现表单元素的动态增删。
下面是部分代码。
<html>
<head>
<script language="javascript">
function add(){
//取得表格
var table = document.getElementById("table1");
//取得行数;
var num = table.rows.length;
//增加一行
var newrow1 = table.insertRow(num-1);
var cell1 = newrow1.insertCell();
var cell2 = newrow1.insertCell();
var cell3 = newrow1.insertCell();
var cell4 = newrow1.insertCell();
//增加行元素
var inputcell2 = document.createElement("<input size='32' name=''>");
cell2.appendChild(inputcell2);
var inputcell4_1 = document.createElement("<input size='32' name=''>");
var inputcell4_2 = document.createElement("<input type='button' value='删除元素'onClick='del(this);'/>");
cell4.appendChild(inputcell4_1);
cell4.appendChild(inputcell4_2);
//刷新标签显示
frash();
}
function del(obj){
//取得按钮所在行
var i = obj.parentNode.parentNode.rowIndex;
var tab = document.getElementById("table1");
//删除按钮所在行
tab.deleteRow(i-1);
frash();
}
function frash(){
var table = document.getElementById("table1");
var num = table.rows.length;
//计算动态元素个数
var n = num-2;
for(i=1;i<=n;i++){
//设置标签值
table.rows[i].cells[0].innerText="元素"+i+"属性A";
//设置属性值
table.rows[i].cells[1].childNodes[0].setAttribute("name","ysa"+i);
table.rows[i].cells[2].innerText="元素"+i+"属性B";
table.rows[i].cells[3].childNodes[0].setAttribute("name","ysb"+i);
}
}
</script>
</head>
<body>
<table id="table1" width="100%" border="1" align="center" cellpadding="0" cellspacing="0">
<tr>
<td>标签1</td>
<td><input name="a"></td>
<td>标签2</td>
<td><input name="b"></td>
</tr>
<tr>
<td colspan="4" align="center"><a href="#" onclick="add();">增加元素</a></td>
</tr>
</table>
</body>
</html>
页面打印通常直接调用IE中打印命令,并通过class控制打印范围。当页面文件内容过多,无法完整打印时,可以通过javascript控制缩放实现完整打印。
下面是部分代码。
<
html>
<head>
<title>***上海市眼病防治中心病人结帐费用报表***</title>
<meta http-equiv="Content-Type" content="text/
html; charset=gb2312">
<!--media=print 这个属性可以在打印时有效-->
<style media=print>
.Noprint{display:none;}
.PageNext{page-break-after: always;}
</style>
<style>
body,td,th
{
font-size: 12px;
}
.tdp
{
border-bottom: 1 solid #000000;
border-left: 1 solid #000000;
border-right: 0 solid #ffffff;
border-top: 0 solid #ffffff;
}
.tabp
{
border-color: #000000;
border-collapse:collapse;
}
.NOPRINT {
font-family: "宋体";
font-size: 12px;
}
</style>
<script language="javascript">
var i=0;
function zoomL(){
i++;
document.getElementById("f").style.zoom=1+i/3;
}
function zoomS(){
i--;
document.getElementById("f").style.zoom=1+i/3;
}
</script>
</head>
<body >
<OBJECT id=WebBrowser classid=CLSID:8856F961-340A-11D0-A96B-00C04FD705A2 height=0 width=0 V
IEWASTEXT> </OBJECT>
<input type=button value=打印 onclick="document.all.WebBrowser.ExecWB(6,1)" class="NOPRINT">
<input type=button value=直接打印 onclick="document.all.WebBrowser.ExecWB(6,6)" class="NOPRINT">
<input type=button value=页面设置 onclick="document.all.WebBrowser.ExecWB(8,1)" class="NOPRINT">
<input type=button value=打印预览 onclick="document.all.WebBrowser.ExecWB(7,1)" class="NOPRINT">
<input type=button value=放大 onclick="zoomL();" class="NOPRINT">
<input type=button value=缩小 onclick="zoomS();" class="NOPRINT">
<br/>
<table width="90%" border="0" align="center" cellpadding="0" cellspacing="0">
<tr align="center">
<td colspan="5"><font size="3">上海市眼病防治中心病人结帐费用报表(A) </font></td>
</tr>
<tr>
<td>汇总人次 5</td>
<td>费用合计 15853.12</td>
<td>统计日期 </td>
<td>制表人 023</td>
<td>制表日期:2004-05-13</td>
</tr>
</table>
<table width="90%" border="1" align="center" cellpadding="2" cellspacing="0" bordercolor="#000000" class="tabp" id="f">
<tr>
<td >姓名</td>
<td >住院号</td>
<td >科室</td>
<td >结帐日期</td>
<td >出院日期</td>
<td >费用合计</td>
<td >医保交易费用</td>
<td >分类给付费用</td>
<td >非医保交易费</td>
</tr>
<tr>
<td > </td>
<td > </td>
<td > </td>
<td > </td>
<td > </td>
<td > </td>
<td > </td>
<td > </td>
<td > </td>
</tr>
</table>
<hr align="center" width="90%" size="1" n
oshade class="NOPRINT" >
<!--分页-->
<div class="PageNext"></div>
<table width="90%" border="1" align="center" cellpadding="2" cellspacing="0" bordercolor="#000000" class="tabp">
<tr>
<td >第2页</td>
</tr>
<tr>
<td >看到分页了吧</td>
</tr>
<tr>
<td > </td>
</tr>
<tr>
<td > </td>
</tr>
<tr>
<td ><table width="100%" border="0" cellspacing="0" cellpadding="0">
<tr>
<td width="50%" >这样的报表
对一般的要求就够了。</td>
<td> </td>
</tr>
</table></td>
</tr>
</table>
<table width="780%" border="1" class="Noprint">
<tr>
<td>能不能打印</td>
</tr>
</table>
</body>
</
html>
思路是把表单类型设置为enctype="multipart/form-data",其他表单中文本数据通过javascript处理,附加在action后面,后台通过request.getParameter()取得。上传文件调用commons-fileupload.jar中方法。
下面是部分代码。
<form name="ajform" action="/da.do" method="post" enctype="multipart/form-data">
<tr><td><input name="a" value=""></td></tr>
<tr><td><input name="b" type="file"></td></tr>
<tr><td><a href="#" onclick="checksubmit();">提交</a></td></tr>
</form>
<script language="javascript">
function checksubmit(){
var value = "/da.do?formAction=save";
value = value+"&a="+ window.document.getElementById("a").value;
window.document.ajform.action=value;
window.document.ajform.submit();
}
</script>
String a = request.getParameter("a");
try {
//文件上传目录“/file/wj”
String filepath= request.getSession().getServletContext().getRealPath("/")+"file"+File.separator+"wj";
//文件上传临时目录“/file/temp”
String tempPath = request.getSession().getServletContext().getRealPath("/")+"file"+File.separator+"temp";
File dir = new File(filepath);
//建立目录
if(!dir.exists()){
dir.mkdirs();
}
File dir1 = new File(tempPath);
if(!dir1.exists()){
dir1.mkdirs();
}
DiskFileUpload fu = new DiskFileUpload();
//设置最大文件尺寸,这里是10MB
fu.setSizeMax(10485760);
//设置缓冲区大小,这里是4kb
fu.setSizeThreshold(4096);
//设置临时目录:
fu.setRepositoryPath(tempPath);
List fileItems = fu.parseRequest(request);
Iterator iter = fileItems.iterator();
while (iter.hasNext()) {
FileItem item = (FileItem) iter.next();
String fileName = item.getName();
//判断是否为文件
if(fileName!=null){
//取文件名
String name = fileName.substring(fileName.lastIndexOf(File.separator)+1);
if(fileName!=null&& !fileName.equals("")) {
File file = new File(filepath+File.separator+name);
//上传文件
item.write(file);
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
<html>
<head>
</head>
<body>
<embed height=240 name=aa style="BORDER-BOTTOM:#2a8a21 3px solid;BORDER-LEFT:#2a8a21 3px solid;BORDER-RIGHT:#2a8a21 3px solid;BORDER-TOP:#2a8a21 3px solid"
type=audio/x-pn-realaudio-plugin width=320 loop="no" console="clip1" reset="false"
controls="ImageWindow" src="a1.rmvb">
</embed><br>
<embed height=30 type=audio/x-pn-realaudio-plugin width=320 console="clip1" reset="false" autostart="false" controls="controlpanel">
</embed><br>
<embed height=30 type=audio/x-pn-realaudio-plugin width=320 console="clip1" reset="false" autostart="false" controls="statusbar">
</embed><br>
<Script Language=JavaScript>
function OpenFile(txt){
document.aa.src=txt.value;
}
</Script>
</body>
</html>
1。EJB打包
<?xml version="1.0"?>
<project name="jartest" default="jar" basedir=".">
<property name="build.dir" value="${basedir}/build" />
<property name="build.classes.dir" value="${build.dir}/classes" />
<target name="jar" description="打包成Jar">
<jar jarfile="${basedir}/ejbfile.jar">
<fileset dir="${build.classes.dir}">
<include name="**/*.class" />
</fileset>
<metainf dir="${basedir}/META-INF ">
<include name="**" />
</metainf>
</jar>
</target>
</project>
2。web应用打包
<?xml version="1.0"?>
<project name="wartest" default="war" basedir=".">
<target name="war" description="创建WEB发布包">
<war warfile="${basedir}/EJBTest.war" webxml="${basedir}/WEB-INF/web.xml">
<fileset dir="${basedir}">
<include name="**"/>
<exclude name="build.xml" />
<exclude name="/WEB-INF/web.xml" />
</fileset>
</war>
</target>
</project>
1.web.xml中配置Spring的servlet和servlet-mapping
<servlet>
<servlet-name>example</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>example</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2.配置spring配置文件application-servlet.xml
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/page/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login.do">loginAction</prop>
</props>
</property>
</bean>
<bean id="loginAction" class="loginAction">
<property name="commandClass">
<value> LoginActionVo </value>
</property>
<property name="formView">
<value>login</value>
</property>
<property name="sessionForm">
<value>true</value>
</property>
<property name="serviceLocator">
<ref bean="servicelocator" />
</property>
</bean>
3.新建類繼承SimpleFormController﹐並複寫protected Object formBackingObject(HttpServletRequest request) 和 protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
Object cmd, BindException ex)。常用結構為
protected Object formBackingObject(HttpServletRequest request){
LoginActionVo loginActionVo = new LoginActionVo ();
request.setAttribute(" loginActionVo", loginActionVo);
return loginActionVo;
}
protected ModelAndView onSubmit(HttpServletRequest request, HttpServletResponse response,
Object cmd, BindException ex){
LoginActionVo loginActionVo =(LoginActionVo)cmd;
Map map = new HashMap();
map.put(" loginActionVo", loginActionVo);
request.getSession().setAttribute(this.getFormSessionAttributeName(), loginActionVo);
return new ModelAndView("login",map);
}
4.將jsp頁面參數和VO進行綁定。綁定的方法為頁面元素name和VO對象對應﹐當進行深層次的綁定時﹐要注意﹐在變量的get方法中進行初始化。在servlet2.4容器中可以不用c:out標籤
輸入框綁定﹕<input name="user.name" value = "<c:out value="${loginActionVo.user.name}"/>" type="text" disabled="disabled" size="14" maxlength="14" /></td>
VO為﹕
public class loginActionVo{
private User user;
public User getUser(User user){
if( user == null){
user = new User();
}
return user;
}
}
以SimpleFormController為例
1。spring 接收一個請求後首先會判斷"get"還是"post"方法
2。1 "get"方法時
2。1。1 首先創建一個command對象﹐通過調用AbstractFormController的formBackingObject方法得到﹐通常是一個pojo﹐根據name用來和提交的數據綁定。
2。1。2 然後會創建一個BindException對象﹐裡面包括command對象﹐和其他一些屬性。
2。1。3 判斷sessionForm 屬性﹐默認為false。如果為true﹐就會把command對象對象保存在session裡 面。session中key為類名+".FORM." + command對象名。可以通過request.getSession().getAttribute(this.getFormSessionAttributeName(request));得到command對象。
2。1。4 調用AbstractFormController的referenceData方法。這個方法默認為空﹐可以復寫來初始化頁面參數。
2。1。5 返回ModelAndView對象﹐返回formview頁面。
2 。2 “post”方法時
2。2。1 首先得到command對象,如果SessionForm = false﹐調用formBackingObjectde創建
如果SessionForm = true,從request.getSession中得到原command對象﹐然後將command對象從
Session中刪除。
2。2。2 然後會創建一個ServletRequestDataBinder對象﹐裡面包括command對象﹐和其他一些屬性。
這個過程將調用initBinder()﹔可以複寫這個方法初始化數據。
2。2。3 調用processFormSubmission(HttpServletRequest request, HttpServletResponse response, Object command, BindException errors)。有錯誤時返回formview頁面﹐否則進入successview頁面。這個過程將調用onSubmit(Object command)﹐必須複寫這個方法放入業務邏輯。
1./WEB-INF/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">
<!--
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
-->
<!--
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-servlet.xml</param-value>
</context-param>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
-->
<servlet>
<servlet-name>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<!--
<taglib>
<taglib-uri>/spring</taglib-uri>
<taglib-location>/WEB-INF/spring.tld</taglib-location>
</taglib>
-->
</web-app>
2./WEB-INF/application-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="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/login.do">loginAction</prop>
</props>
</property>
</bean>
<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>.jsp</value>
</property>
</bean>
<bean id="loginAction" class="onlyfun.caterpillar.LoginAction">
<property name="commandName">
<value>command</value>
</property>
<property name="commandClass">
<value>onlyfun.caterpillar.LoginForm</value>
</property>
<property name="successView">
<value>success</value>
</property>
<property name="formView">
<value>form</value>
</property>
<property name="user">
<ref local="user" />
</property>
</bean>
<bean id="user" class="onlyfun.caterpillar.User">
<property name="username">
<value>111</value>
</property>
<property name="password">
<value>111</value>
</property>
</bean>
</beans>
3./form.jsp
<%@taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>Login</title></head>
<body>
<spring:bind path="command.*">
<font color="red"><b>${status.errorMessage}</b></font><br>
</spring:bind>
請輸入使用者名稱與密碼:<p>
<form name="loginform" action="login.do" method="post">
<spring:bind path="command.username">
名稱 <input type="text" name="${status.expression}" value="${status.value}"/>
<font color="red">${status.errorMessage}</font><br>
</spring:bind>
<spring:bind path="command.password">
密碼 <input type="password" name="${status.expression}" value="${status.value}"/>
<font color="red">${status.errorMessage}</font><br>
</spring:bind>
<input type="submit" value="確定"/>
</form>
注意:輸入錯誤會再回到這個頁面中。
</body>
</html>
4./index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
begin......
<%
response.sendRedirect("login.do");
%>
</body>
</html>
5./success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head><title>Login Success</title></head>
<body>
<H1><c:out value="用戶名﹕${user}"/></H1>
</body>
</html>
6./WEB-INF/classes/onlyfun/caterpillar/LoginAction.class
package onlyfun.caterpillar;
import org.springframework.validation.BindException;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.*;
public class LoginAction extends SimpleFormController {
private User user;
protected ModelAndView onSubmit(Object command,BindException errors) throws Exception {
LoginForm form = (LoginForm) command;
String username = user.getUsername();
String password = user.getPassword();
if(username.equals(form.getUsername()) &&
password.equals(form.getPassword())) {
return new ModelAndView(this.getSuccessView(),"user", form.getUsername());
}
else {
errors.reject("loginfail", "使用者名稱或密碼錯誤");
if(!(username.equals(form.getUsername()))){
errors.rejectValue("username", "error", null, "使用者名稱錯誤");
}
if(!(password.equals(form.getPassword()))){
errors.rejectValue("password", "error", null, "密碼錯誤");
}
return new ModelAndView(this.getFormView(),errors.getModel());
}
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
7./WEB-INF/classes/onlyfun/caterpillar/LoginForm.class
package onlyfun.caterpillar;
public class LoginForm {
private String username;
private String password;
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public String getPassword() {
return password;
}
}
8./WEB-INF/tags/spring.tld
9./WEB-INF/tags/c.tld
10./WEB-INF/classes/onlyfun/caterpillar/User.class
package onlyfun.caterpillar;
public class User {
private String username;
private String password;
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
}
HttpServletRequest,HttpServletResponse:这两个属性的作用范围最小。
时间上:只是本身请求和应答完成就失效,当然转发是把当前的request对象取出来传给另一
个资源,其实本身的request对象还是只生存到本次请求结束,response也同样。
空间上:只能发送请求的客户端有效。
HttpSession:一次连结到客户端关闭,时间作用范围比上面两个大,空间任用范围相同。
ServletConfig:从一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对本servlet
有效,一个servlet的ServletConfig对象不能被另一个servlet访问。
ServletContext:对任何servlet,任何人在任何时间都有效,这才是真正全局的对象。
那么,ServletConfig参数和ServletContext参数到底应该如何使用,如何取得?
一般来说,对整个应用的配置,为了不使用“硬编码”,应该配置为ServletContext参数,比如字
符集设定。
<web-app>
.................
<init-param>
<param-name>charset</param-name>
<param-value>GB2312</param-value>
</init-param>
.................
</web-app>
注意以上格式只是2。0以后的标准格式,旧容器(引擎)采用服务商自己的格式配置。注意它的
父元素应该是<web-app>也就是说它是对一个应用作用的。
而如果只有一个特定的servlet要设定的参数,其它servlet不能共享,应该配置为ServletConfig
参数,如一个读取附件的servlet要用到绝对目录,而别的servlet不会用到:
<servlet>
<servlet-name>GetAtt</servlet-name>
<servlet-class>mail.GetAttServlet</servlet-class>
<init-param>
<param-name>absPath</param-name>
<param-value>/usr/mail/ax/axman/Maildir/</param-value>
</init-param>
</servlet>
不用说,因为在<servlet>标签中已经指定了name和class,也就是说只有mail.GetAttServlet这个
servlet中才能取到path,而别的Servlet是不能取到的。
那么如何访问这两个对象的参数呢?
访问ServletConfig参数:
首先要取得ServletConfig对象,然后调用它的getInitParameter();方法。要访问
ServletConfig对象,jsp中直接使用config内置对象,但因为你的JSP编译后的servlet一般不会被
加到web.xml中的,所以一般不会通过jsp来取对本JSP编译后的servlet的配置参数,那么在servlet
中要得到ServletConfig对象有两种方法:
在inii()方法中取到:通过init的重载方法传递
.....
public class Test extends HttpServlet
{
ServletConfig config;
public void init(ServletConfig config) throws ServletException {
this.config = config;
}
..................
}
然后在下面的方法中就可以访问config对象。但要注意,为了确保能从构造方法中到到当前servlet的
config对象,应该调用父类的构造方法:
.....
public class Test extends HttpServlet
{
ServletConfig config;
public void init(ServletConfig config) throws ServletException {
super.init(config);
this.config = config;
}
..................
}
通过getServletConfig()方法直接到时,这样做的好处是不必调手工传递属性,想在任何时候都可
以得到。
还有第三种方法,要自己实现一些接口,这里作为一般讨论就不介绍了。
要访问ServletContext对象,只要从现有的ServletConfig对象getServletContext()就可以了,然后
调用它的getInitParameter()方法就可以获取它的参数。
按说:ServletContext对象的作用域比ServletConfig作用域大,为什么要从ServletConfig中到得
ServletContext对象呢?我个人认为:容器保存了很多个ServletContext对象,请求时容器到底取哪一个
给你呢?那就取其中包含ServletConfig信息的那个给你,就是说取ServletConfig对象的父级对象。就好
象HttpSession要从requset中取得一样,就是取那个包含当前requese对象的session对象给你,这只是我
的个人想法,还没有来得及看具体实现。反正就这么用吧。
JSF和Spring集成的资料比较少,原理是获得彼此的上下文引用,以此进一步获得各自管理的bean,这是可能的,因为两者是web应用框架都遵循servlet规范,为二者整合提供了可能和基础.
在Spring中ApplicationContext是相当重要的类,对于web应用,它还包装了javax.servlet.ServletContext,为web应用提供了所有可以利用的数据,包括可管理bean,Faces中通过FacesContext类可以获得所有可以利用的资源,同样包括JSF的可管理支持bean,它们都围绕着ServletContext提供了自己的门面,通过各自的门面在Servlet容器的世界里彼此相通.
本文介绍两种方式,实现二者集成:
1. 通过写自己的类来完成二者的连通,实际上只是获得彼此世界里存活的bean,对于JSF中事件处理可能需要更进一步的构思和编码,为了这点,第二个方法介绍了一种框架.
2. 使用框架完成二者集成.
一 自己动手,下面的代码以示例为主,其它涉及的类和接口略去.
这个工具类提供在JSF世界里查找Spring管理的bean.也实现在Spring中查找JSF组件的方法.
package com.skysoft.rbac.dao;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import javax.faces.context.FacesContext;
import javax.servlet.ServletContext;
import javax.faces.el.ValueBinding;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
public final class SpringFacesUtil {
public SpringFacesUtil() {
}
/**
* 从Spring中查找bean.
* @param beanname String
* @return Object
*/
public static Object findBean(String beanname) {
ServletContext context = (ServletContext) FacesContext.getCurrentInstance().
getExternalContext().getContext();
ApplicationContext appctx = WebApplicationContextUtils.
getRequiredWebApplicationContext(context);
return appctx.getBean(beanname);
}
/**
* 从JSF中查找bean.
* @param beanname String
* @return Object
*/
public static Object lookupBean(String beanname) {
Object obj = getValueBinding(getJsfEl(beanname)).getValue(FacesContext.
getCurrentInstance());
return obj;
}
private static ValueBinding getValueBinding(String el) {
return getApplication().createValueBinding(el);
}
private static Application getApplication() {
ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.
getFactory(FactoryFinder.APPLICATION_FACTORY);
//FactoryFinder.FACES_CONTEXT_FACTORY
//FactoryFinder.RENDER_KIT_FACTORY
return appFactory.getApplication();
}
private static String getJsfEl(String value) {
return "#{" + value + "}";
}
}
下面定义一个由JSF管理的bean:
package com.skysoft.rbac.dao;
import javax.servlet.ServletContext;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.skysoft.struts.jsf.util.FacesUtils;
public class ServiceLocatorBean
implements ServiceLocator {
private static final String DAO_SERVICE_BEAN_NAME = "userDAO";
//这个dao就是由Spring提供的管理bean,这个dao可以使用Hibernate实现.
private UserDAO dao;
public ServiceLocatorBean() {
this.dao = (UserDAO)SpringFacesUtil.findBean(DAO_SERVICE_BEAN_NAME);
}
public UserDAO getDao() {
return dao;
}
}
下面是一个使用ServiceLocatorBean的类.
public class UserDAOImp
extends HibernateDaoSupport implements UserDAO {
private UserDAO dao;
private List list;
public UserDAOImp() {}
public List getList() {
if (list == null) {
list = dao.getList();
}
return list;
}
public UserDAO getDao() {
return dao;
}
public void setDao(UserDAO dao) {
this.dao = dao;
}
}
在faces-config.xml中的配置:
<managed-bean>
<managed-bean-name>serviceLocatorBean</managed-bean-name>
<managed-bean-class>com.skysoft.rbac.dao.ServiceLocatorBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>User</managed-bean-name>
<managed-bean-class>com.skysoft.rbac.User</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>serviceLocator</property-name>
<property-class>com.skysoft.rbac.dao.ServiceLocatorBean</property-class>
<value>#{serviceLocatorBean}</value>
</managed-property>
</managed-bean>
在applicationContext.xml中的配置:
<bean id="userDAO" class="com.skysoft.rbac.dao.UserDAOImp">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>
二 使用框架
1 介绍
这个框架是Spring相关项目,提供一个包de.mindmatters.faces.spring,这个包包含JSF和Spring框架综合集成的粘合代码,这些代码以独立于一个实现的方式完成,这样它能和任何JSF实现一起使用.
本包的提供的代码主要目的是尽可能透明的集成两个框架,主要特征:
l JSF/JSP开发者应该能访问Spring管理的Beans,就好象它们是由JSF管理的.
l JSF可管理beans应能集成入Spring.
l RequestHandledEvent事件也应该能被发布到Spring.
2 JSF配置集成
本包构造了一个基于faces配置文件(e.g. /WEB-INF/faces-config.xml)的WebApplicationContext类, 让它成为遵循"spring-beans" DTD配置文件(e.g. defined in /WEB-INF/applicationContext.xml)来配置的ApplicationContext的孩子,这样依从"faces-config" DTD的WebApplicationContext就是全特征的,即自动拥有如下功能:
l JSF可管理beans实现了Spring的*Aware interfaces:
ApplicationContextAware
BeanFactoryAware
BeanNameAware
ResourceLoaderAware
ServletContextAware
l JSF可管理beans实现Spring的lifecycle interfaces:
InitializingBean
DisposableBean
l 实现Spring的FactoryBean interface
l 实现Spring的ApplicationListener interface
l 发布ApplicationEvent事件.
l 从资源中读取消息.
等等,更多可看Spring.
3 访问方式
1) 从JSF中程序化的访问Spring管理的beans.
因为在FacesWebApplicationContext和ApplicationContext之间有层次关系,所以你的JSF可管理支持beans能容易的实现ApplicationContextAware接口,并能通过getBean方法访问它而不管它是否定义在FacesWebApplicationContext中还是定义在父ApplicationContext类对象中.
2) 通过JSF EL从JSF中访问Spring管理的beans.
能够使用JSF EL访问beans无论你引用的bean由JSF管理还是由Spring管理.两个bean上下文在存取时间合并.
a) 直接访问:
如果一个带有请求名字的bean只存在于Spring上下文内的话,这个bean被使用,bean的singleton属性设置被完全保持.
b) 区域化访问(scoped access):
如果你要从JSF定义bean的作用域的能力上得益还想让那个bean由Spring管理,那么就要在两个上下文中定义,只是对于JSF上下文中的定义的类类型要使用de.mindmatters.faces.spring.SpringBeanFactory类,你还应该设置那个bean的singleton属性到false,因这能覆盖你的作用域设置.在你使用JSF EL访问bean时,你总能获得一个遵从你在JSF上下文中定义的作用域设置的由Spring管理的bean的实例.
三 用法
通常,就象设置任何其它JSF web应用一样设置你的web应用,下面的样例配置展示怎样使能上面提到的特征。
在web.xml
配置中必须加入下列配置条目,
同时注意把该库的jsf-spring.jar
放在适当的位置.
<web-app>
.........
<!--
过滤器用于向Spring发布RequestHandledEvent,它应该影射到和FacesServlet url相同的模式.
-->
<filter>
<filter-name>RequestHandled</filter-name>
<filter-class>de.mindmatters.faces.spring.support.RequestHandledFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>RequestHandled</filter-name>
<url-pattern>*.faces</url-pattern>
</filter-mapping>
<!--
这个侦听器用于装入Spring beans的父应用上下文.
-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
.........
</web-app>
下面的一些说明,都可以通过下载这个Spring相关项目得到,列在这里只为演示上面的说明的功能.
WEB-INF/faces-config.xml
<!-- 一个纯JSF管理的bean -->
<managed-bean>
<managed-bean-name>jsfBean</managed-bean-name>
<managed-bean-class>example.NameBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>name</property-name>
</managed-property>
</managed-bean>
<!--一个SpringBeanScope用来定义Spring可管理bean的作用域.-->
<managed-bean>
<managed-bean-name>scopedAccessSpringBean</managed-bean-name>
<managed-bean-class>de.mindmatters.faces.spring.SpringBeanScope</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<!-- 这是一个纯JSF可管理bean,它持有一个到Spring可管理bean的一个引用. -->
<managed-bean>
<managed-bean-name>referencingBean</managed-bean-name>
<managed-bean-class>example.ReferencingBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
<managed-property>
<property-name>referencedBean</property-name>
<value>#{managedPropertyAccessSpringBean}</value>
</managed-property>
</managed-bean>
WEB-INF/applicationContext.xml (partial)
<!-- 一个纯Spring的可管理bean -->
<bean id="directAccessSpringBean" class="example.NameBean"/>
<!-- 一个向JSF作用域提供的可管理bean. -->
<bean id="scopedAccessSpringBean" class="example.NameBean" singleton="false"/>
<!-- 一个纯Spring的可管理bean,它由一个JSF可管理bean引用.(当然了,它也能被直接访问啦.) -->
<bean id="managedPropertyAccessSpringBean" class="example.NameBean" singleton="false"/>
参考:
1./home.xsl
<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="
http://www.w3.org/1999/XSL/Transform">
<xsl:output method="html" omit-xml-declaration="yes" />
<xsl:template match="/">
<html>
<head><title>Hello!</title></head>
<body>
<h1>My First Words</h1>
<xsl:for-each select="wordList/word">
<xsl:value-of select="."/><br />
</xsl:for-each>
</body>
</html>
</xsl:template>
</xsl:stylesheet>
2./index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<center><input type="button" value="xslt" onclick="location.href='home.htm'"></center>
</body>
</html>
3./WEB-INF/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>hello</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/application-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>hello</servlet-name>
<url-pattern>*.htm</url-pattern>
</servlet-mapping>
</web-app>
4./WEB-INF/application-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="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/home.htm">homeAction</prop>
</props>
</property>
</bean>
<bean id="bundleViewResolver" class="org.springframework.web.servlet.view.ResourceBundleViewResolver">
<property name="basename">
<value>views</value>
</property>
</bean>
<bean id="homeAction" class="xslt.HomePageController"/>
</beans>
5./WEB-INF/classes/views_zh_TW.properties
home.class=xslt.HomePage
home.stylesheetLocation=/home.xsl
home.root=wordList
6./WEB-INF/classes/xslt/HomePage.class
package xslt;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.jdom.Element;
import org.jdom.output.DOMOutputter;
import org.springframework.web.servlet.view.xslt.AbstractXsltView;
import org.w3c.dom.Node;
public class HomePage extends AbstractXsltView {
protected Node createDomNode(
Map model, String rootName, HttpServletRequest req, HttpServletResponse res
) throws Exception {
org.jdom.Document doc = new org.jdom.Document();
Element root = new Element(rootName);
doc.setRootElement(root);
List words = (List) model.get("wordList");
for (Iterator it = words.iterator(); it.hasNext();) {
String nextWord = (String) it.next();
Element e = new Element("word");
e.setText(nextWord);
root.addContent(e);
}
// convert JDOM doc to a W3C Node and return
return new DOMOutputter().output( doc );
}
}
7./WEB-INF/classes/xslt/HomePageController.class
package xslt;
import java.util.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class HomePageController extends AbstractController{
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp) throws Exception {
Map map = new HashMap();
List wordList = new ArrayList();
wordList.add("hello");
wordList.add("world");
map.put("wordList", wordList);
return new ModelAndView("home", map);
}
}
1.
Abstract
在
Java
的世界裡,要操控
XML
,最簡單的方法莫過於使用
JDOM
。在這裡我簡單的介紹如何用
JDOM
從無到有的建立一分
XML
、當有一份
XML file
時,如何將這個
XML file
讀進程式裡及如何利用
JDOM
將
XML
透過
XSLT
轉成
HTML
。
JDOM
是由
Brett Mclaughlin
和
Jason Hunter
編寫,在
http://www.jdom.org
可免費下載。
2.
建立、新增、刪除、輸出
範例
1
展示如何建立、新增、刪除及輸出一份
XML
,每份
XML
在
JDOM
裡是由一個
Document
類別代表,所以一開始我們要先
new
一個
Document
,在建構
Document
時應指明根節點,如果沒有指明,在建構應由
setRootElement
設定。基本上
XML
都可以化成一個樹狀結構,所以,在產生根節點之後,就由根節點開始增加子節點,新增的方式是呼叫
Element.addContent
將新的節點加入。刪除如果知道是某節點以下的子節點,則可呼叫
Element.getChildren
取得所有子節點,再找出要刪除的點節予以刪除。
當建立好
XML
之後,通常我們會希望將它輸出到檔案,
JDOM
提供了
XMLOutputter
類別供我們輸出之用,輸出前要先設定編碼方式,不然,會以
UTF-8
為預設值,
setNewlines
則是指明輸出時是否要幫我們斷行,方便閱讀,如果沒有加這行指令,預設是不會斷行,那麼所有資料將在同一行上。
=====
範例
1 =====
import org.jdom.*;
import org.jdom.output.*;
import java.io.*;
import java.util.List;
public class myCreate {
public myCreate() {
String[] strChapter = { "XML
簡論
", "
編寫
XML", "
剖析
XML", "
約制
XML", "
驗正
XML", "
轉換
XML" };
Element elmtRoot = new Element("Article");
Document docJDOM = new Document(elmtRoot);
//
新增
for(int i=0; i<6; i++) {
Element elmtChapter = new Element("Chapter");
elmtChapter.addContent(strChapter[i]);
elmtChapter.setAttribute("sort", new Integer(i).toString());
elmtRoot.addContent(elmtChapter);
}
//
刪除
List lstChapter = elmtRoot.getChildren("Chapter");
lstChapter.remove(4);
//
輸出
OutputXML(docJDOM, "e:/myJDOM.xml");
}
private void OutputXML(Document docXML, String strFilename) {
XMLOutputter fmt = new XMLOutputter();
try {
fmt.setEncoding("big5");
fmt.setNewlines(true);
FileWriter fwXML = new FileWriter(strFilename);
fmt.output(docXML, fwXML);
fwXML.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
myCreate myCreate1 = new myCreate();
}
}
3.
讀進一份
XML file
目前
XML
最常被拿來應用的領域之一大概就是當作設定檔,因此,如何從檔案中讀入一份已存在的
XML
更為重要。
JDOM
是利用
SAX
或
DOM
來剖析
XML
,用
SAX
會比
DOM
,所以一般都是用
SAX
,如果對
SAX
不熟悉,在
http://www.saxproject.org/
相關文件資料。
範例
2
就是用
SAX
建立
Document
,在建立
SAXBuilder
時傳入的參數指出是否用
DTD
驗正
XML
的合法性,
true
表示要,
false
表示不要。當呼叫
build
之後
JDOM
就已經幫我們用
SAX
建立好一棵
XML Tree
,如此我們就可以很方便由
Tree
中找到我們要的節點。
=====
範例
2 =====
import org.jdom.*;
import org.jdom.input.*;
import org.jdom.output.*;
import java.io.*;
import java.util.List;
public class myRead {
public myRead() {
Document docJDOM;
//
利用
SAX
建立
Document
SAXBuilder bSAX = new SAXBuilder(false);
try {
docJDOM = bSAX.build(new File("e:/myJDOM.xml"));
}
catch (JDOMException e) {
e.printStackTrace();
return;
}
//
在根節點中加入一個新的子節點
Element elmtRoot = docJDOM.getRootElement();
Element elmtChapter = new Element("Chapter");
elmtChapter.setText("
驗正
XML");
elmtChapter.setAttribute("sort", "4");
elmtRoot.addContent(elmtChapter);
//
印出所有根節點的子節點
List lstChildren = elmtRoot.getChildren("Chapter");
for(int i=0; i<lstChildren.size(); i++) {
Element elmtChild = (Element) lstChildren.get(i);
System.out.println("Child " + i);
System.out.println(" Text:" + elmtChild.getText());
System.out.println(" Attribute:" + elmtChild.getAttributeValue("sort"));
}
//
輸出到檔案
OutputXML(docJDOM, "e:/myJDOM2.xml");
}
private void OutputXML(Document docXML, String strFilename) {
XMLOutputter fmt = new XMLOutputter();
try {
fmt.setEncoding("big5");
fmt.setNewlines(true);
FileWriter fwXML = new FileWriter(strFilename);
fmt.output(docXML, fwXML);
fwXML.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
myRead myRead1 = new myRead();
}
}
4.
轉換
XML
到
HTML
要將
XML
轉成
HTML
當然要先寫好
XSL
,但是即使寫好
XSL
,
JDOM
也並不提供
XML
轉換,幸好在
JDOM
安裝好之後,就會有
Apache
的
Xalan
,它可以幫我們做這樣的轉換。
要使用
Apache
的
Xalan
,首先確定
xalan.jar
在
classpath
裡。
Xalan
的第一個用法是在命令列執行,指令如下…
C:\> java org.apache.xalan.xslt.Process –IN XML
文件
–XSL XSL
樣版
–OUT
輸出檔名
命令列的用法在一般的運用裡是很方便,但是我們有興趣的是在程式裡怎麼用。範例
4
提供了一個簡單的
sample
。
=====
範例
4 =====
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.stream.*;
public class myGenHTML {
public myGenHTML(String strXML, String strXSL, String strHTML) {
try {
GenHTML(strXML, strXSL, strHTML);
}
catch (TransformerConfigurationException e) {
e.printStackTrace();
}
catch (TransformerException e) {
e.printStackTrace();
}
}
private void GenHTML(String strXMLFile, String strXSLFile, String strHTMLFile) throws TransformerConfigurationException, TransformerException
{
TransformerFactory myFactory = TransformerFactory.newInstance();
Transformer myTransformer = myFactory.newTransformer(new StreamSource(strXSLFile));
myTransformer.transform(new StreamSource(strXMLFile), new StreamResult(strHTMLFile));
}
public static void main(String[] args) {
myGenHTML myGenHTML1 = new myGenHTML(args[0], args[1], args[2]);
}
}