2006年5月12日
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]);
}
}
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">
<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>*.do</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>form.jsp</welcome-file>
</welcome-file-list>
</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.InternalResourceView</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="commandClass">
<value>onlyfun.caterpillar.LoginForm</value>
</property>
<property name="successView">
<value>success</value>
</property>
<property name="formView">
<value>form</value>
</property>
</bean>
</beans>
3./WEB-INF/classes/onlyfun/caterpillar/LoginAction.class
package onlyfun.caterpillar;
import org.springframework.web.servlet.mvc.SimpleFormController;
import org.springframework.web.servlet.*;
public class LoginAction extends SimpleFormController {
protected ModelAndView onSubmit(Object command) throws Exception {
LoginForm form = (LoginForm) command;
if("111".equals(form.getUsername()) &&
"111".equals(form.getPassword())) {
return new ModelAndView(this.getSuccessView(),"user", form.getUsername());
}
else {
return new ModelAndView(this.getFormView());
}
}
}
4./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;
}
}
5./form.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>Login</title></head>
<body>
請輸入使用者名稱與密碼:<p>
<form name="loginform" action="login.do" method="post">
名稱 <input type="text" name="username"/><br>
密碼 <input type="password" name="password"/><br>
<input type="submit" value="確定"/>
</form>
注意:輸入錯誤會再回到這個頁面中。
</body>
</html>
6./success.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>Login Success</title></head>
<body>
<H1> Hello, ${user}!!</H1>
This is your secret gift.
</body>
</html>
1. /hellouser.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<html>
<head><title>HelloPage</title></head>
<body>
<H1> ${helloWord}</H2>
</body>
</html>
2./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>
<%
response.sendRedirect("hellouser.do");
%>
</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>*.do</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="/hellouser.do">helloUserAction</prop>
</props>
</property>
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass">
<value>org.springframework.web.servlet.view.InternalResourceView</value>
</property>
</bean>
<bean id="helloUserAction" class="onlyfun.caterpillar.HelloUserAction">
<property name="helloWord">
<value>Hello!</value>
</property>
<property name="viewPage">
<value>/hellouser.jsp</value>
</property>
</bean>
</beans>
5./WEB-INF/classes/onlyfun/caterpillar/HelloUserAction.class
package onlyfun.caterpillar;
import java.io.IOException;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.springframework.web.servlet.mvc.Controller;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.bind.RequestUtils;
public class HelloUserAction implements Controller {
private String helloWord;
private String viewPage;
public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
//String user = RequestUtils.getRequiredStringParameter(req, "user");
Map model = new HashMap();
model.put("helloWord", getHelloWord());
// model.put("user", user);
return new ModelAndView(getViewPage(), model);
}
public void setViewPage(String viewPage) {
this.viewPage = viewPage;
}
public String getViewPage() {
return viewPage;
}
public void setHelloWord(String helloWord) {
this.helloWord = helloWord;
}
public String getHelloWord() {
return helloWord;
}
}
1.EventRouter.js
/**
* @author user
*/
var jsEvent = new Array();
jsEvent.EventRouter = function(el,eventType){
this.lsnrs = new Array();
this.el = el;
el.eventRouter = this;
el[eventType] = jsEvent.EventRouter.callback;
};
jsEvent.EventRouter.prototype.addListener = function(lsnr){
this.lsnrs.append(lsnr,true);
} ;
jsEvent.EventRouter.prototype.notify = function(e){
var lsnrs = this.lsnrs;
for(var i=0;i<lsnrs.length;i++){
var lsnr = lsnrs[i];
lsnr.call(this,e);
}
};
jsEvent.EventRouter.callback=function(event){
var e = event || window.event;
var router = this.eventRouter;
router.notify(e);
};
Array.prototype.append = function(obj,nodup){
if(nodup){
this[this.length]=obj;
}
};
2.mousemat.css
.mousemat{
background-color:#ffe0d0;
border:solid maroon 0px;
position:absolute;
margin:0px;
width:500px;
height:500px;
top:50px;
left:50px;
}
.thumbnail{
background-color:#ffe0d0;
border:solid maroon 0px;
position:absolute;
margin:0px;
width:100px;
height:100px;
top:50px;
left:600px;
}
.cursor{
background-color:blue;
position:relative;
height:5px;
width:5px;
}
3.mousemat.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<link rel='stylesheet' type = 'text/css' href = 'mousemat.css'>
<script type ='text/javascript' src = 'EventRouter.js'></script>
<script type='text/javascript'>
var cursor = null;
window.onload = function(){
var mat = document.getElementById('mousemat');
cursor = document.getElementById('cursor');
var mouseRouter = new jsEvent.EventRouter(mat,"onmousemove");
//var mouseRouter = new jsEvent.EventRouter(mat,"onclick");
mouseRouter.addListener(writeStatus);
mouseRouter.addListener(drawThumbnail);
};
function writeStatus(e){
window.status = e.clientX + "," + e.clientY;
}
function drawThumbnail(e){
cursor.style.left = ((e.clientX/5)-2) + "px";
cursor.style.top = ((e.clientY/5)-2) + "px";
}
</script>
</head>
<body>
<div class='mousemat' id='mousemat'></div>
<div class='thumbnail' id='thumbnail'>
<div class = 'cursor' id = 'cursor'></div>
</div>
</body>
</html>
1.mousemat.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "
http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<link rel='stylesheet' type = 'text/css' href = 'mousemat.css'>
<script type='text/javascript'>
var cursor = null;
window.onload = function(){
var mat = document.getElementById('mousemat');
mat.onmousemove = mouseObserver;
cursor = document.getElementById('cursor');
}
function mouseObserver(event){
var e = event || window.event;
writeStatus(e);
drawThumbnail(e);
}
function writeStatus(e){
window.status = e.clientX + "," + e.clientY;
}
function drawThumbnail(e){
cursor.style.left = ((e.clientX/5)-2) + "px";
cursor.style.top = ((e.clientY/5)-2) + "px";
}
</script>
</head>
<body>
<div class='mousemat' id='mousemat'></div>
<div class='thumbnail' id='thumbnail'>
<div class = 'cursor' id = 'cursor'></div>
</div>
</body>
</html>
2.mousemat.css
mousemat{
background-color:#ffe0d0;
border:solid maroon 0px;
position:absolute;
margin:0px;
width:500px;
height:500px;
top:50px;
left:50px;
}
.thumbnail{
background-color:#ffe0d0;
border:solid maroon 0px;
position:absolute;
margin:0px;
width:100px;
height:100px;
top:50px;
left:600px;
}
.cursor{
background-color:blue;
position:relative;
height:5px;
width:5px;
}
1.MyHtml.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type='text/javascript'>
var req = null;
var console = null;
var READY_STATE_UNINITIALIZED = 0;
var READY_STATE_LOADING = 1;
var READY_STATE_LOADED = 2;
var READY_STATE_INTERACTIVE = 3;
var READY_STATE_COMPLETE = 4;
function sendRequest(url,params,HttpMethod){
if(!HttpMethod){
HttpMethod = "GET";
}
req = initXMLHTTPRequest();
if(req){
req.onreadystatechange = onReadyState;
req.open(HttpMethod,url,true);
req.setRequestHeader("Content-Type","application/x-www-form-urlencoded");
req.send(params);
}
}
function initXMLHTTPRequest(){
var xRequest = null;
if(window.XMLHttpRequest){
xRequest = new XMLHttpRequest();
}else if(window.ActiveXObject){
xRequest = new ActiveXObject("Microsoft.XMLHTTP");
}
return xRequest;
}
function onReadyState(){
var ready = req.readyState;
var data = null;
if(ready==READY_STATE_COMPLETE){
data = req.responseText;
}else{
data = "loading...[" + ready +"]";
}
toConsole(data);
}
function toConsole(data){
if(console!=null){
var newline = document.createElement("div");
console.appendChild(newline);
var txt = document.createTextNode(data);
console.appendChild(txt);
}
}
window.onload = function(){
console = document.getElementById('console');
sendRequest("data.txt");
}
</script>
</head>
<body>
<DIV id ='console'></DIV>
</body>
</html>
2.data.txt
i'm ok!!!!!!!!
1.new_file.htm
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Untitled Document</title>
<SCRIPT type='text/javascript' src='new_file.js'></SCRIPT>
<SCRIPT type='text/javascript'>
window.onload = load;
</SCRIPT>
</head>
<body>
<CENTER><INPUT type='button' id='b1'></INPUT></CENTER>
</body>
</html>
2.new_file.js
var value = '500';
function load(){
var domEl = document.getElementById('b1');
JsButton(value,domEl);
}
function JsButton(value,domEl){
this.domEl = domEl;
this.value = value;
this.domEl.buttonObj = this;
//this.domEl.onclick = function(){
//alert(this.value);
//}
this.domEl.onclick = JsButton.prototype.clickHandler;
}
JsButton.prototype.clickHandler = function(){
//alert(this.value); 在回調函數中調用this屬性時﹐
//得到的是對應的DOM元素裡面的數值﹐此處為空。
var buttonObj = this.buttonObj;
var value =(buttonObj && buttonObj.value)? buttonObj.value:"unknown value";
alert(value);
}
1.musical_dyn_keys.css
.musicalKeys{
background-color:#ffe0d0;
border:solid maroon 2px;
position:absolute;
overflow:auto;
margin:4px;
}
.toplong{
width:536px;
height:68px;
top:24px;
left:24px;
}
.sidebar{
width:100px;
height:400px;
top:24px;
left:570px;
}
.musicalButton{
border:solid navy 1px;
width:60px;
height:60px;
position:relative;
margin:2px;
float:left;
}
.do{background-color:red;}
.re{background-color:orange;}
.mi{background-color:yellow;}
.fa{background-color:green;}
.so{background-color:blue;}
.la{background-color:indigo;}
.ti{background-color:violet;}
div.console{
font-family:arial,helvetica;
font-size:16px;
color:navy;
background-color:white;
border:solid navy 2px;
width:536px;
height:320px;
top:106px;
left:24px;
margin:4px;
position:absolute;
overflow:auto;
}
2.musical_dyn_keys.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<title>Two Keyboards</title>
<LINK rel='stylesheet' type='text/css' href='musical_dyn_keys.css'/>
<SCRIPT type='text/javascript' src='musical_dyn_keys.js'></SCRIPT>
<SCRIPT type='text/javascript'>
window.onload=assignKeys
</SCRIPT>
</head>
<body>
<DIV id='keyboard-top' class='toplong musicalKeys'></DIV>
<DIV id='keyboard-side' class='sidebar musicalKeys'></DIV>
<DIV id='console' class='console'></DIV>
</body>
</html>
3.musical_dyn_keys.js
var notes = new Array("do","re","mi","fa","so","la","ti","do");
function assignKeys(){
var candidates = document.getElementsByTagName("DIV");
if(candidates){
for(var i=0;i<candidates.length;i++){
var candidate = candidates[i];
if(candidate.className.indexOf('musicalKeys')>=0){
makeKeyboard(candidate);
}
}
}
}
function makeKeyboard(el){
for(var i=0;i<notes.length;i++){
var key=document.createElement("DIV");
key.className = notes[i] + " musicalButton";
alert(key.className);
key.note = notes[i];
key.onclick = playNote;
el.appendChild(key);
}
}
function playNote(event){
var note = this.note;
var console = document.getElementById('console');
if(note && console){
console.innerHTML +=note + ".";
}
}
1.murical.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<link rel='stylesheet' type='text/css' href='musical.css'>
<script type='text/javascript' src="musical.js"></script>
<script type='text/javascript'>
window.onload = assignKeys
</script>
</head>
<body>
<DIV>
<DIV id='keyboard' class='musicalKeys'>
<DIV class='do musicalButton'></DIV>
<DIV class='re musicalButton'></DIV>
<DIV class='mi musicalButton'></DIV>
<DIV class='fa musicalButton'></DIV>
<DIV class='so musicalButton'></DIV>
<DIV class='la musicalButton'></DIV>
<DIV class='ti musicalButton'></DIV>
<DIV class='do musicalButton'></DIV>
</DIV>
<DIV id='console' class='console'></DIV>
</DIV>
</body>
</html>
2.musical.css
.body{
background-color:white;
}
.musicalKeys{
background-color:#ffe0d0;
boarder:solid maroon 2px;
width:536px;
height:68px;
top:24px;
left:24px;
margin:4px;
position:absolute;
overflow:auto;
}
.musicalButton{
border:solid navy 1px;
width:60px;
height:60px;
position:relative;
margin:2px;
float:left;
}
.do{background-color:red;}
.re{background-color:orange;}
.mi{background-color:yellow;}
.fa{background-color:green;}
.so{background-color:blue;}
.la{background-color:indigo;}
.ti{background-color:violet;}
div.console{
font-family:arial,helvetica;
font-size:16px;
color:navy;
background-color:white;
border:solid navy 2px;
width:536px;
height:320px;
top:106px;
left:24px;
margin:4px;
position:absolute;
overflow:auto;
}
3.musical.js
function assignKeys(){
var keyboard=document.getElementById("keyboard");
var keys = keyboard.getElementsByTagName("DIV");
if(keys){
for(var i=0;i<keys.length;i++){
var key=keys[i];
var classes=(key.className).split(" ");
if(classes && classes.length>=2 && classes[1]=="musicalButton"){
var note=classes[0];
key.note=note;
//key.onmouseover=playNote;
key.onclick = playNote;
}
}
}
}
function playNote(event){
var note = this.note;
var console = document.getElementById("console");
if(note && console){
console.innerHTML += note + ".";
}
}
MyHtml.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script type="text/javascript" src="prototype.js"></script>
<script type="text/javascript" src="rico.js"></script>
<script type='text/javascript'>
function accordion(){
var outer = $('myAccordion');
outer.style.width = '320px';
new Rico.Accordion(
outer,
{panelHeight:400,
expandedBg:'#909090',
collapsedBg:'#404040'
}
);
}
window.onload = accordion
</script>
</head>
<body>
<div id='myAccordion'>
<div>
<div>first title</div>
<div>first!!!!!</div>
</div>
<div>
<div>second title</div>
<div>second!!!!!</div>
</div>
</div>
</body>
</html>
String sql = "INSERT INTO AB(A,B,C,D,E) VALUES(?,?,?,?,?)";
sql = sql.toUpperCase();
String str="
\\s*INSERT\\s+INTO\\s+([^\\(]+)\\(([^\\)]+)\\)\\s*VALUES\\s*\\(([^\\)]+)\\)\\s*";
Pattern p = Pattern.compile(str);
Matcher m = p.matcher(sql);
m.find();
String table = m.group(1);
String cols = m.group(2);
String values = m.group(3);
System.out.println("table ==== " + table); //AB
System.out.println("cols ==== " + cols); //A﹐B﹐C﹐D﹐E
System.out.println("values ==== " + values); //﹖﹐﹖﹐﹖﹐﹖﹐﹖
註﹕.表示任何字符
[abc]表示abc之一字符
[^abc]表示非abc的一字符
\s表示空格﹐tab,換行﹐換頁﹐回車
\S表示非空格﹐tab,換行﹐換頁﹐回車
\d表示數字[0-9]
\D表示非數字[^0-9]
\w表示詞字符[a-zA-Z0-9]
\W表示非詞字符[^a-zA-Z0-9]
匹配量詞 X? 表示1或0個X
X* 表示0或n個X
X+表示1或n個X
一、概要
在JAVA應用程式特別是基於WEB的程式中,經常遇到字符的編碼問題。為了防止出現亂碼,首先需要了解JAVA是如何處理字符的,這樣就可以有目的地在輸入/輸出環節中增加必要的轉碼。其次,由於各種伺服器有不同的處理方式,還需要多做試驗,確保使用中不出現亂碼。
二、基本概念2.1 JAVA中字符的表達
JAVA中有char、byte、String這幾個概念。char 指的是一個UNICODE字符,為16位的整數。byte 是字節,字符串在網路傳輸或存儲前需要轉換為byte數組。在從網路接收或從存儲設備讀取後需要將byte數組轉換成String。String是字符串,可以看成是由char組成的數組。String 和 char 為內存形式,byte是網路傳輸或存儲的序列化形式。
舉例:
英
String ying = “英”;
char ying = ying.charAt(0);
String yingHex = Integer.toHexString(ying);
82 F1
byte yingGBBytes = ying.getBytes(“GBK”);
GB編碼的字節數值
D3 A2
2.2 編碼方式的簡介
String序列化成byte數組或反序列化時需要選擇正確的編碼方式。如果編碼方式不正確,就會得到一些0x3F的值。常用的字符編碼方式有ISO8859_1、GB2312、GBK、UTF-8/UTF-16/UTF-32。
ISO8859_1用來編碼拉丁文,它由單字節(0-255)組成。
GB2312、GBK用來編碼簡體中文,它有單字節和雙字節混合組成。最高位為1的字節和下一個字節構成一個漢字,最高位為0的字節是ASCII碼。
UTF-8/UTF-16/UTF-32是國際標準UNICODE的編碼方式。 用得最多的是UTF-8,主要是因為它在對拉丁文編碼時節約空間。
UNICODE值 UTF-8編碼
U-00000000 - U-0000007F: 0xxxxxxx
U-00000080 - U-000007FF: 110xxxxx 10xxxxxx
U-00000800 - U-0000FFFF: 1110xxxx 10xxxxxx 10xxxxxx
U-00010000 - U-001FFFFF: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
U-00200000 - U-03FFFFFF: 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
U-04000000 - U-7FFFFFFF: 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
三、J2SE中相關的函數
String str =”英”;
//取得GB2312編碼的字節
byte[] bytesGB2312 = str.getBytes(“GB2312”);
//取得平臺缺省編碼的字節(solaris為ISO8859_1,windows為GB2312)
byte[] bytesDefault = str.getBytes();
//用指定的編碼將字節轉換成字符串
String newStrGB = new String(bytesGB2312, “GB2312”);
//用平臺缺省的編碼將字節轉換成字符串(solaris為ISO8859_1,windows為GB2312)
String newStrDefault = new String(bytesDefault);
//用指定的編碼從字節流裏面讀取字符
InputStream in = xxx;
InputStreamReader reader = InputStreamReader( in, “GB2312”);
char aChar = reader.read();
四、JSP、數據庫的編碼
4.1 JSP中的編碼
(1) 靜態聲明:
CHARSET有兩個作用:
JSP文件的編碼方式:在讀取JSP文件、生成JAVA類時,源JSP文件中漢字的編碼
JSP輸出流的編碼方式:在執行JSP時,往response流裏面寫入數據的編碼方式
(2) 動態改變:在往response流裏面寫數據前可以調用response.setContentType(),設定正確的編碼類型。
(3) 在TOMCAT中,由Request.getParameter() 得到的參數,編碼方式都是ISO8859_1。所以如果在瀏覽器輸入框內輸入一個漢字“英”,在伺服器端就得到一個ISO8859_1編碼的(0x00,0xD3,0x00,0xA2)。所以通常在接收參數時轉碼:
String wrongStr = response.getParameter(“name”);
String correctStr = new String(wrongStr.getBytes(“ISO8859_1”),”GB2312”);
在最新的SERVLET規範裏面,也可以在獲取參數之前執行如下代碼:
request.setCharacterEncoding(“GB2312”);
4.2 數據庫的編碼
(1) 數據庫使用UTF-16
如果String中是UNICODE字符,寫入讀出時不需要轉碼
(2) 數據庫使用ISO8859_1
如果String中是UNICODE字符,寫入讀出時需要轉碼
寫入:String newStr = new String(oldStr.getByte(“GB2312”), “ISO8859_1”);
讀出:String newStr = new String(oldStr.getByte(“ISO8859_1”),”GB2312”);
五、源文件的編碼
5.1 資源文件
資源文件的編碼方式和編輯平臺相關。在WINDOWS平台下編寫的資源文件,以GB2312方式編碼。在編譯時需要轉碼,以確保在各個平臺上的正確性:
native2ascii –encoding GB2312 source.properties
這樣從資源文件中讀出的就是正確的UNICODE字符串。
5.2 源文件
源文件的編碼方式和編輯平臺相關。在WINDOWS平台下開發的源文件,以GB2312方式編碼。在編譯的時候,需要指定源文件的編碼方式:
javac –encoding GB2312
JAVA編譯後生成的字節文件的編碼為UTF-8。
點最新版TOMCAT4.1.18支援request.setCharacterEncoding(String enc)
點資源文件轉碼成company.name=\u82f1\u65af\u514b
點如果數據庫使用utf-16則不需要這部分轉碼
點頁面上應有
轉碼ⅰ:
String s = new String
(request.getParameter(“name”).getBytes(“ISO8859_1”),”GB2312”);
轉碼ⅱ:
String s = new String(name.getBytes(“GB2312”),”ISO8859_1”);
轉碼ⅲ:
String s = new String(name.getBytes(“ISO8859_1”),” GB2312”);
1.單個.class文件編譯
首先從控制台進入jad.exe目錄
運行 jad example1.class
(此時example1.class和jad.exe位於同一個目錄)
成功運行後﹐當前目錄下產生一個新文件example1.jad﹐裡面為反編譯後的java代碼
2.多個.class文件編譯
與1大致相同
輸入jad -o -dtest -sjava *.class
其中"test"表示反編譯文件的存放目錄﹐"java"表示反編譯後產生文件的後綴名
3.某文件夾下所有文件編譯
與1大致相同
輸入jad -o -dtest -sjava tree/**/*.class
其中"test"表示反編譯文件的存放目錄﹐"java"表示反編譯後產生文件的後綴名
tree表示源文件夾名
詳細說明參看“Readme.txt”
jad下載聯接
http://www.infoxa.com/asp/soft_file/xxnr_soft_242.htm
Java操作Excel的一种方法
bromon原创 版权所有
MS的电子表格(Excel)是Office的重要成员,是保存统计数据的一种常用格式。作为办公文档,势必要涉及到的电子文档的交换,Excel是一种在企业中非常通用的文件格式,打印和管理也比较方便。在一个Java应用中,将一部分数据生成Excel格式,是与其他系统无缝连接的重要手段。
在开源世界中,有两套比较有影响的API可供使用,一个是POI,一个是jExcelAPI。其中jExcelAPI是一个韩国程序员的作品,虽然没有POI那样血统高贵,但是在笔者的使用过程中,感觉简单方便,对中文支持非常好,功能也比较强大。可以在sourceforge.net下载。作者的网站上对它的特征有如下描述:
● 支持Excel 95-2000的所有版本
● 生成Excel 2000标准格式
● 支持字体、数字、日期操作
● 能够修饰单元格属性
● 支持图像和图表
应该说以上功能已经能够大致满足我们的需要。最关键的是这套API是纯Java的,并不依赖Windows系统,即使运行在Linux下,它同样能够正确的处理Excel文件。另外需要说明的是,这套API对图形和图表的支持很有限,而且仅仅识别PNG格式。
搭建环境
将下载后的文件解包,得到jxl.jar,放入classpath,安装就完成了。
基本操作
一、创建文件
拟生成一个名为“测试数据.xls”的Excel文件,其中第一个工作表被命名为“第一页”,大致效果如下:
代码(CreateXLS.java):
- //生成Excel的类
- import java.io.*;
- import jxl.*;
- import jxl.write.*;
- public class CreateXLS
- {
- public static void main(String args[])
- {
- try
- {
- //打开文件
- WritableWorkbook book=Workbook.createWorkbook(new File(“测试.xls”));
-
- //生成名为“第一页”的工作表,参数0表示这是第一页
- WritableSheet sheet=book.createSheet(“第一页”,0);
-
- //在Label对象的构造子中指名单元格位置是第一列第一行(0,0)
- //以及单元格内容为test
- Label label=new Label(0,0,”test”);
- //将定义好的单元格添加到工作表中
- sheet.addCell(label);
- /**生成一个保存数字的单元格
- *必须使用Number的完整包路径,否则有语法歧义
- *单元格位置是第二列,第一行,值为789.123
- */
- jxl.write.Number number = new jxl.write.Number(1,0,789.123);
- sheet.addCell(number);
- //写入数据并关闭文件
- book.write();
- book.close();
- }catch(Exception e)
- {
- System.out.println(e);
- }
- }
- }
编译执行后,会在当前位置产生一个Excel文件。
三、读取文件
以刚才我们创建的Excel文件为例,做一个简单的读取操作,程序代码如下:
- //读取Excel的类
- import java.io.*;
- import jxl.*;
- public class ReadXLS
- {
- public static void main(String args[])
- {
- try
- {
- Workbook book=
- Workbook.getWorkbook(new File(“测试.xls”));
-
- //获得第一个工作表对象
- Sheet sheet=book.getSheet(0);
- //得到第一列第一行的单元格
- Cell cell1=sheet.getCell(0,0);
- String result=cell1.getContents();
- System.out.println(result);
- book.close();
- }catch(Exception e)
- {
- System.out.println(e);
- }
- }
- }
程序执行结果:test
四、修改文件
利用jExcelAPI可以修改已有的Excel文件,修改Excel文件的时候,除了打开文件的方式不同之外,其他操作和创建Excel是一样的。下面的例子是在我们已经生成的Excel文件中添加一个工作表:
- //修改Excel的类,添加一个工作表
- import java.io.*;
- import jxl.*;
- import jxl.write.*;
- public class UpdateXLS
- {
- public static void main(String args[])
- {
- try
- {
- //Excel获得文件
- Workbook wb=Workbook.getWorkbook(new File(“测试.xls”));
-
- //打开一个文件的副本,并且指定数据写回到原文件
- WritableWorkbook book=
- Workbook.createWorkbook(new File(“测试.xls”),wb);
-
- //添加一个工作表
- WritableSheet sheet=book.createSheet(“第二页”,1);
- sheet.addCell(new Label(0,0,”第二页的测试数据”));
-
- book.write();
- book.close();
- }catch(Exception e)
- {
- System.out.println(e);
- }
- }
- }
执行结果如图:
高级操作
一、 数据格式化
在Excel中不涉及复杂的数据类型,能够比较好的处理字串、数字和日期已经能够满足一般的应用。
1、 字串格式化
字符串的格式化涉及到的是字体、粗细、字号等元素,这些功能主要由WritableFont和WritableCellFormat类来负责。假设我们在生成一个含有字串的单元格时,使用如下语句,为方便叙述,我们为每一行命令加了编号:
- WritableFont font1=
- new WritableFont(WritableFont.TIMES,16,WritableFont.BOLD); ①
- WritableCellFormat format1=new WritableCellFormat(font1); ②
- Label label=new Label(0,0,”data 4 test”,format1) ③
其中①指定了字串格式:字体为TIMES,字号16,加粗显示。WritableFont有非常丰富的构造子,供不同情况下使用,jExcelAPI的java-doc中有详细列表,这里不再列出。
②处代码使用了WritableCellFormat类,这个类非常重要,通过它可以指定单元格的各种属性,后面的单元格格式化中会有更多描述。
③处使用了Label类的构造子,指定了字串被赋予那种格式。
在WritableCellFormat类中,还有一个很重要的方法是指定数据的对齐方式,比如针对我们上面的实例,可以指定:
- //把水平对齐方式指定为居中
- format1.setAlignment(jxl.format.Alignment.CENTRE);
- //把垂直对齐方式指定为居中
- format1.setVerticalAlignment(jxl.format.VerticalAlignment.CENTRE);
二、单元格操作
Excel中很重要的一部分是对单元格的操作,比如行高、列宽、单元格合并等,所幸jExcelAPI提供了这些支持。这些操作相对比较简单,下面只介绍一下相关的API。
1、 合并单元格
- WritableSheet.mergeCells(int m,int n,int p,int q);
作用是从(m,n)到(p,q)的单元格全部合并,比如:
- WritableSheet sheet=book.createSheet(“第一页”,0);
//合并第一列第一行到第六列第一行的所有单元格
- sheet.mergeCells(0,0,5,0);
合并既可以是横向的,也可以是纵向的。合并后的单元格不能再次进行合并,否则会触发异常。
2、 行高和列宽
- WritableSheet.setRowView(int i,int height);
作用是指定第i+1行的高度,比如:
//将第一行的高度设为200
- sheet.setRowView(0,200);
- WritableSheet.setColumnView(int i,int width);
作用是指定第i+1列的宽度,比如:
//将第一列的宽度设为30
- sheet.setColumnView(0,30);
jExcelAPI还有其他的一些功能,比如插入图片等,这里就不再一一介绍,读者可以自己探索。
可以用Java读取Microsoft Excel文件。微软提供了一个Excel的ODBC驱动程序,因此我们就可以使用JDBC和Sun的JDBC-ODBC驱动来读取Excel文件了。
如果你有个Excel文件,名为Book1.xls(译者注:由于原文的例子我没有下载下来,所以我用了自己的例子),并且,该文件中有一个工作表(sheet)名为Sheet1
微软的ODBC驱动程序把工作表中的第一行作为列名(译者注:即字段名),工作表名作为数据库表名。
要通过JDBC访问工作表,我们还必须创建一个新的ODBC数据源,在Windows 2000系统上创建数据源的过程如下:
进入“控制面板” --> “管理工具” --> “数据源(ODBC)”,(译者注:打开后选择系统DSN),点击添加,在弹出窗口中选择“Driver do Microsoft Excel(*.xls)”
然后在数据源名处输入你一个名字Book1(译者注:相当于数据库名),然后点击“选择工作簿”,然后找到并选取你的Excel文件
点击确定后,系统数据源列表中会出现你设置的数据源名称,
现在数据表已经在数据源列表里了(译者注:点击确定完成配置)。
(译者注:我的例子中)现在如果我们想挑出test1列中的所有“测试”值,那就需要用以下的SQL查询:
SELECT test1 FROM [Sheet1$] WHERE test1='测试'
要注意的是工作表名后面跟了一个“$”符号,这个符号是不可缺少的。为什么?因为他的前后有方括号,因为“$”是SQL语句中的保留字。Life is never easy(译者注:作者发感慨了)。
下面是例子程序:
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.DriverManager;
public class ExcelReader {
public static void main( String[] args ) {
Connection c = null;
Statement stmnt = null;
try {
Class.forName( "sun.jdbc.odbc.JdbcOdbcDriver" );
c = DriverManager.getConnection( "jdbc:odbc:Book1", "", "" );
stmnt = c.createStatement();
String query = "SELECT test1 FROM [Sheet1$] WHERE test1='测试'";
ResultSet rs = stmnt.executeQuery( query );
System.out.println( "查得匹配'测试'的test1的记录为:" );
while( rs.next() ) {
System.out.println( rs.getString( "test1" ) );
}
}
catch( Exception e ) {
System.err.println( e );
}
finally {
try {
stmnt.close();
c.close();
}
catch( Exception e ) {
System.err.println( e );
}
}
}
}
在此程序中,主函数main() 建立了一个数据表的连接,并取出符合条件的记录。
(译者注:另外,我这里还有一段程序,是读取所有记录的程序,仅作参考):
import java.sql.Connection;
import java.sql.Statement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.DriverManager;
public class ExcelReader {
public static void main(String[] args){
Connection connection = null;
try{
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con = DriverManager.getConnection( "jdbc:odbc:Book1","","" );
Statement st = con.createStatement();
ResultSet rs = st.executeQuery( "SELECT * FROM [Sheet1$]" );
ResultSetMetaData rsmd = rs.getMetaData();
int numberOfColumns = rsmd.getColumnCount();
while (rs.next()) {
for (int i = 1; i <= numberOfColumns; i++) {
if(i>1) //用逗号分隔各列
System.out.print(", ");
String columnValue = rs.getString(i);
System.out.print(columnValue);
}
System.out.println("");
}
st.close();
con.close();
} catch(Exception ex) {
System.err.print("Exception: ");
System.err.println(ex.getMessage());
}
}
}
SQL中的单记录函数
1.ASCII
返回与指定的字符对应的十进制数;
SQL> select ascii('A') A,ascii('a') a,ascii('0') zero,ascii(' ') space from dual;
A A ZERO SPACE
--------- --------- --------- ---------
65 97 48 32
2.CHR
给出整数,返回对应的字符;
SQL> select chr(54740) zhao,chr(65) chr65 from dual;
ZH C
-- -
赵 A
3.CONCAT
连接两个字符串;
SQL> select concat('010-','88888888')||'转23' 高乾竞电话 from dual;
高乾竞电话
----------------
010-88888888转23
4.INITCAP
返回字符串并将字符串的第一个字母变为大写;
SQL> select initcap('smith') upp from dual;
UPP
-----
Smith
5.INSTR(C1,C2,I,J)
在一个字符串中搜索指定的字符,返回发现指定的字符的位置;
C1 被搜索的字符串
C2 希望搜索的字符串
I 搜索的开始位置,默认为1
J 出现的位置,默认为1
SQL> select instr('oracle traning','ra',1,2) instring from dual;
INSTRING
---------
9
6.LENGTH
返回字符串的长度;
SQL> select name,length(name),addr,length(addr),sal,length(to_char(sal)) from gao.nchar_tst;
NAME LENGTH(NAME) ADDR LENGTH(ADDR) SAL LENGTH(TO_CHAR(SAL))
------ ------------ ---------------- ------------ --------- --------------------
高乾竞 3 北京市海锭区 6 9999.99 7
7.LOWER
返回字符串,并将所有的字符小写
SQL> select lower('AaBbCcDd')AaBbCcDd from dual;
AABBCCDD
--------
aabbccdd
8.UPPER
返回字符串,并将所有的字符大写
SQL> select upper('AaBbCcDd') upper from dual;
UPPER
--------
AABBCCDD
9.RPAD和LPAD(粘贴字符)
RPAD 在列的右边粘贴字符
LPAD 在列的左边粘贴字符
SQL> select lpad(rpad('gao',10,'*'),17,'*')from dual;
LPAD(RPAD('GAO',1
-----------------
*******gao*******
不够字符则用*来填满
10.LTRIM和RTRIM
LTRIM 删除左边出现的字符串
RTRIM 删除右边出现的字符串
SQL> select ltrim(rtrim(' gao qian jing ',' '),' ') from dual;
LTRIM(RTRIM('
-------------
gao qian jing
11.SUBSTR(string,start,count)
取子字符串,从start开始,取count个
SQL> select substr('13088888888',3,8) from dual;
SUBSTR('
--------
08888888
12.REPLACE('string','s1','s2')
string 希望被替换的字符或变量
s1 被替换的字符串
s2 要替换的字符串
SQL> select replace('he love you','he','i') from dual;
REPLACE('H
----------
i love you
13.SOUNDEX
返回一个与给定的字符串读音相同的字符串
SQL> create table table1(xm varchar(8));
SQL> insert into table1 values('weather');
SQL> insert into table1 values('wether');
SQL> insert into table1 values('gao');
SQL> select xm from table1 where soundex(xm)=soundex('weather');
XM
--------
weather
wether
14.TRIM('s' from 'string')
LEADING 剪掉前面的字符
TRAILING 剪掉后面的字符
如果不指定,默认为空格符
15.ABS
返回指定值的绝对值
SQL> select abs(100),abs(-100) from dual;
ABS(100) ABS(-100)
--------- ---------
100 100
16.ACOS
给出反余弦的值
SQL> select acos(-1) from dual;
ACOS(-1)
---------
3.1415927
17.ASIN
给出反正弦的值
SQL> select asin(0.5) from dual;
ASIN(0.5)
---------
.52359878
18.ATAN
返回一个数字的反正切值
SQL> select atan(1) from dual;
ATAN(1)
---------
.78539816
19.CEIL
返回大于或等于给出数字的最小整数
SQL> select ceil(3.1415927) from dual;
CEIL(3.1415927)
---------------
4
20.COS
返回一个给定数字的余弦
SQL> select cos(-3.1415927) from dual;
COS(-3.1415927)
---------------
-1
21.COSH
返回一个数字反余弦值
SQL> select cosh(20) from dual;
COSH(20)
---------
242582598
22.EXP
返回一个数字e的n次方根
SQL> select exp(2),exp(1) from dual;
EXP(2) EXP(1)
--------- ---------
7.3890561 2.7182818
23.FLOOR
对给定的数字取整数
SQL> select floor(2345.67) from dual;
FLOOR(2345.67)
--------------
2345
24.LN
返回一个数字的对数值
SQL> select ln(1),ln(2),ln(2.7182818) from dual;
LN(1) LN(2) LN(2.7182818)
--------- --------- -------------
0 .69314718 .99999999
25.LOG(n1,n2)
返回一个以n1为底n2的对数
SQL> select log(2,1),log(2,4) from dual;
LOG(2,1) LOG(2,4)
--------- ---------
0 2
26.MOD(n1,n2)
返回一个n1除以n2的余数
SQL> select mod(10,3),mod(3,3),mod(2,3) from dual;
MOD(10,3) MOD(3,3) MOD(2,3)
--------- --------- ---------
1 0 2
27.POWER
返回n1的n2次方根
SQL> select power(2,10),power(3,3) from dual;
POWER(2,10) POWER(3,3)
----------- ----------
1024 27
28.ROUND和TRUNC
按照指定的精度进行舍入
SQL> select round(55.5),round(-55.4),trunc(55.5),trunc(-55.5) from dual;
ROUND(55.5) ROUND(-55.4) TRUNC(55.5) TRUNC(-55.5)
----------- ------------ ----------- ------------
56 -55 55 -55
29.SIGN
取数字n的符号,大于0返回1,小于0返回-1,等于0返回0
SQL> select sign(123),sign(-100),sign(0) from dual;
SIGN(123) SIGN(-100) SIGN(0)
--------- ---------- ---------
1 -1 0
30.SIN
返回一个数字的正弦值
SQL> select sin(1.57079) from dual;
SIN(1.57079)
------------
1
31.SIGH
返回双曲正弦的值
SQL> select sin(20),sinh(20) from dual;
SIN(20) SINH(20)
--------- ---------
.91294525 242582598
32.SQRT
返回数字n的根
SQL> select sqrt(64),sqrt(10) from dual;
SQRT(64) SQRT(10)
--------- ---------
8 3.1622777
33.TAN
返回数字的正切值
SQL> select tan(20),tan(10) from dual;
TAN(20) TAN(10)
--------- ---------
2.2371609 .64836083
34.TANH
返回数字n的双曲正切值
SQL> select tanh(20),tan(20) from dual;
TANH(20) TAN(20)
--------- ---------
1 2.2371609
35.TRUNC
按照指定的精度截取一个数
SQL> select trunc(124.1666,-2) trunc1,trunc(124.16666,2) from dual;
TRUNC1 TRUNC(124.16666,2)
--------- ------------------
100 124.16
36.ADD_MONTHS
增加或减去月份
SQL> select to_char(add_months(to_date('199912','yyyymm'),2),'yyyymm') from dual;
TO_CHA
------
200002
SQL> select to_char(add_months(to_date('199912','yyyymm'),-2),'yyyymm') from dual;
TO_CHA
------
199910
37.LAST_DAY
返回日期的最后一天
SQL> select to_char(sysdate,'yyyy.mm.dd'),to_char((sysdate)+1,'yyyy.mm.dd') from dual;
TO_CHAR(SY TO_CHAR((S
---------- ----------
2004.05.09 2004.05.10
SQL> select last_day(sysdate) from dual;
LAST_DAY(S
----------
31-5月 -04
38.MONTHS_BETWEEN(date2,date1)
给出date2-date1的月份
SQL> select months_between('19-12月-1999','19-3月-1999') mon_between from dual;
MON_BETWEEN
-----------
9
SQL>selectmonths_between(to_date('2000.05.20','yyyy.mm.dd'),to_date('2005.05.20','yyyy.mm.dd')) mon_betw from dual;
MON_BETW
---------
-60
39.NEW_TIME(date,'this','that')
给出在this时区=other时区的日期和时间
SQL> select to_char(sysdate,'yyyy.mm.dd hh24:mi:ss') bj_time,to_char(new_time
2 (sysdate,'PDT','GMT'),'yyyy.mm.dd hh24:mi:ss') los_angles from dual;
BJ_TIME LOS_ANGLES
------------------- -------------------
2004.05.09 11:05:32 2004.05.09 18:05:32
40.NEXT_DAY(date,'day')
给出日期date和星期x之后计算下一个星期的日期
SQL> select next_day('18-5月-2001','星期五') next_day from dual;
NEXT_DAY
----------
25-5月 -01
41.SYSDATE
用来得到系统的当前日期
SQL> select to_char(sysdate,'dd-mm-yyyy day') from dual;
TO_CHAR(SYSDATE,'
-----------------
09-05-2004 星期日
trunc(date,fmt)按照给出的要求将日期截断,如果fmt='mi'表示保留分,截断秒
SQL> select to_char(trunc(sysdate,'hh'),'yyyy.mm.dd hh24:mi:ss') hh,
2 to_char(trunc(sysdate,'mi'),'yyyy.mm.dd hh24:mi:ss') hhmm from dual;
HH HHMM
------------------- -------------------
2004.05.09 11:00:00 2004.05.09 11:17:00
42.CHARTOROWID
将字符数据类型转换为ROWID类型
SQL> select rowid,rowidtochar(rowid),ename from scott.emp;
ROWID ROWIDTOCHAR(ROWID) ENAME
------------------ ------------------ ----------
AAAAfKAACAAAAEqAAA AAAAfKAACAAAAEqAAA SMITH
AAAAfKAACAAAAEqAAB AAAAfKAACAAAAEqAAB ALLEN
AAAAfKAACAAAAEqAAC AAAAfKAACAAAAEqAAC WARD
AAAAfKAACAAAAEqAAD AAAAfKAACAAAAEqAAD JONES
43.CONVERT(c,dset,sset)
将源字符串 sset从一个语言字符集转换到另一个目的dset字符集
SQL> select convert('strutz','we8hp','f7dec') "conversion" from dual;
conver
------
strutz
44.HEXTORAW
将一个十六进制构成的字符串转换为二进制
45.RAWTOHEXT
将一个二进制构成的字符串转换为十六进制
46.ROWIDTOCHAR
将ROWID数据类型转换为字符类型
47.TO_CHAR(date,'format')
SQL> select to_char(sysdate,'yyyy/mm/dd hh24:mi:ss') from dual;
TO_CHAR(SYSDATE,'YY
-------------------
2004/05/09 21:14:41
48.TO_DATE(string,'format')
将字符串转化为ORACLE中的一个日期
49.TO_MULTI_BYTE
将字符串中的单字节字符转化为多字节字符
SQL> select to_multi_byte('高') from dual;
TO
--
高
50.TO_NUMBER
将给出的字符转换为数字
SQL> select to_number('1999') year from dual;
YEAR
---------
1999
51.BFILENAME(dir,file)
指定一个外部二进制文件
SQL>insert into file_tb1 values(bfilename('lob_dir1','image1.gif'));
52.CONVERT('x','desc','source')
将x字段或变量的源source转换为desc
SQL> select sid,serial#,username,decode(command,
2 0,'none',
3 2,'insert',
4 3,
5 'select',
6 6,'update',
7 7,'delete',
8 8,'drop',
9 'other') cmd from v$session where type!='background';
SID SERIAL# USERNAME CMD
--------- --------- ------------------------------ ------
1 1 none
2 1 none
3 1 none
4 1 none
5 1 none
6 1 none
7 1275 none
8 1275 none
9 20 GAO select
10 40 GAO none
53.DUMP(s,fmt,start,length)
DUMP函数以fmt指定的内部数字格式返回一个VARCHAR2类型的值
SQL> col global_name for a30
SQL> col dump_string for a50
SQL> set lin 200
SQL> select global_name,dump(global_name,1017,8,5) dump_string from global_name;
GLOBAL_NAME DUMP_STRING
------------------------------ --------------------------------------------------
ORACLE.WORLD Typ=1 Len=12 CharacterSet=ZHS16GBK: W,O,R,L,D
54.EMPTY_BLOB()和EMPTY_CLOB()
这两个函数都是用来对大数据类型字段进行初始化操作的函数
55.GREATEST
返回一组表达式中的最大值,即比较字符的编码大小.
SQL> select greatest('AA','AB','AC') from dual;
GR
--
AC
SQL> select greatest('啊','安','天') from dual;
GR
--
天
56.LEAST
返回一组表达式中的最小值
SQL> select least('啊','安','天') from dual;
LE
--
啊
57.UID
返回标识当前用户的唯一整数
SQL> show user
USER 为"GAO"
SQL> select username,user_id from dba_users where user_id=uid;
USERNAME USER_ID
------------------------------ ---------
GAO 25
58.USER
返回当前用户的名字
SQL> select user from dual;
USER
------------------------------
GAO
59.USEREVN
返回当前用户环境的信息,opt可以是:
ENTRYID,SESSIONID,TERMINAL,ISDBA,LABLE,LANGUAGE,CLIENT_INFO,LANG,VSIZE
ISDBA 查看当前用户是否是DBA如果是则返回true
SQL> select userenv('isdba') from dual;
USEREN
------
FALSE
SQL> select userenv('isdba') from dual;
USEREN
------
TRUE
SESSION
返回会话标志
SQL> select userenv('sessionid') from dual;
USERENV('SESSIONID')
--------------------
152
ENTRYID
返回会话人口标志
SQL> select userenv('entryid') from dual;
USERENV('ENTRYID')
------------------
0
INSTANCE
返回当前INSTANCE的标志
SQL> select userenv('instance') from dual;
USERENV('INSTANCE')
-------------------
1
LANGUAGE
返回当前环境变量
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
LANG
返回当前环境的语言的缩写
SQL> select userenv('lang') from dual;
USERENV('LANG')
----------------------------------------------------
ZHS
TERMINAL
返回用户的终端或机器的标志
SQL> select userenv('terminal') from dual;
USERENV('TERMINA
----------------
GAO
VSIZE(X)
返回X的大小(字节)数
SQL> select vsize(user),user from dual;
VSIZE(USER) USER
----------- ------------------------------
6 SYSTEM
60.AVG(DISTINCT|ALL)
all表示对所有的值求平均值,distinct只对不同的值求平均值
SQLWKS> create table table3(xm varchar(8),sal number(7,2));
语句已处理。
SQLWKS> insert into table3 values('gao',1111.11);
SQLWKS> insert into table3 values('gao',1111.11);
SQLWKS> insert into table3 values('zhu',5555.55);
SQLWKS> commit;
SQL> select avg(distinct sal) from gao.table3;
AVG(DISTINCTSAL)
----------------
3333.33
SQL> select avg(all sal) from gao.table3;
AVG(ALLSAL)
-----------
2592.59
61.MAX(DISTINCT|ALL)
求最大值,ALL表示对所有的值求最大值,DISTINCT表示对不同的值求最大值,相同的只取一次
SQL> select max(distinct sal) from scott.emp;
MAX(DISTINCTSAL)
----------------
5000
62.MIN(DISTINCT|ALL)
求最小值,ALL表示对所有的值求最小值,DISTINCT表示对不同的值求最小值,相同的只取一次
SQL> select min(all sal) from gao.table3;
MIN(ALLSAL)
-----------
1111.11
63.STDDEV(distinct|all)
求标准差,ALL表示对所有的值求标准差,DISTINCT表示只对不同的值求标准差
SQL> select stddev(sal) from scott.emp;
STDDEV(SAL)
-----------
1182.5032
SQL> select stddev(distinct sal) from scott.emp;
STDDEV(DISTINCTSAL)
-------------------
1229.951
64.VARIANCE(DISTINCT|ALL)
求协方差
SQL> select variance(sal) from scott.emp;
VARIANCE(SAL)
-------------
1398313.9
65.GROUP BY
主要用来对一组数进行统计
SQL> select deptno,count(*),sum(sal) from scott.emp group by deptno;
DEPTNO COUNT(*) SUM(SAL)
--------- --------- ---------
10 3 8750
20 5 10875
30 6 9400
66.HAVING
对分组统计再加限制条件
SQL> select deptno,count(*),sum(sal) from scott.emp group by deptno having count(*)>=5;
DEPTNO COUNT(*) SUM(SAL)
--------- --------- ---------
20 5 10875
30 6 9400
SQL> select deptno,count(*),sum(sal) from scott.emp having count(*)>=5 group by deptno ;
DEPTNO COUNT(*) SUM(SAL)
--------- --------- ---------
20 5 10875
30 6 9400
67.ORDER BY
用于对查询到的结果进行排序输出
SQL> select deptno,ename,sal from scott.emp order by deptno,sal desc;
DEPTNO ENAME SAL
--------- ---------- ---------
10 KING 5000
10 CLARK 2450
10 MILLER 1300
20 SCOTT 3000
20 FORD 3000
20 JONES 2975
20 ADAMS 1100
20 SMITH 800
30 BLAKE 2850
30 ALLEN 1600
30 TURNER 1500
30 WARD 1250
30 MARTIN 1250
30 JAMES 950
如何从一位菜鸟蜕变成为高手,灵活使用的SQL语句是必不可少的。本文收集了部分比较经典,常用的SQL语句供大家参考,希望对大家有所帮助。
说明:复制表(只复制结构,源表名:a 新表名:b)
SQL: select * into b from a where 1<>1
说明:拷贝表(拷贝数据,源表名:a 目标表名:b)
SQL: insert into b(a, b, c) select d,e,f from b;
说明:显示文章、提交人和最后回复时间
SQL: select a.title,a.username,b.adddate from table a,(select max(adddate) adddate from table where table.title=a.title) b
说明:外连接查询(表名1:a 表名2:b)
SQL: select a.a, a.b, a.c, b.c, b.d, b.f from a LEFT OUT JOIN b ON a.a = b.c
说明:日程安排提前五分钟提醒
SQL: select * from 日程安排 where datediff('minute',f开始时间,getdate())>5
说明:两张关联表,删除主表中已经在副表中没有的信息
SQL:
delete from info where not exists ( select * from infobz where info.infid=infobz.infid
说明:--
SQL:
SELECT A.NUM, A.NAME, B.UPD_DATE, B.PREV_UPD_DATE
FROM TABLE1,
(SELECT X.NUM, X.UPD_DATE, Y.UPD_DATE PREV_UPD_DATE
FROM (SELECT NUM, UPD_DATE, INBOUND_QTY, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE,'YYYY/MM') = TO_CHAR(SYSDATE, 'YYYY/MM')) X,
(SELECT NUM, UPD_DATE, STOCK_ONHAND
FROM TABLE2
WHERE TO_CHAR(UPD_DATE,'YYYY/MM') =
TO_CHAR(TO_DATE(TO_CHAR(SYSDATE, 'YYYY/MM') ¦¦ '/01','YYYY/MM/DD') - 1, 'YYYY/MM') Y,
WHERE X.NUM = Y.NUM (+)
AND X.INBOUND_QTY + NVL(Y.STOCK_ONHAND,0) <> X.STOCK_ONHAND B
WHERE A.NUM = B.NUM
说明:--
SQL:
select * from studentinfo where not exists(select * from student where studentinfo.id=student.id) and 系名称='"&strdepartmentname&"' and 专业名称='"&strprofessionname&"' order by 性别,生源地,高考总成绩
说明:
从数据库中去一年的各单位电话费统计(电话费定额贺电化肥清单两个表来源)
SQL:
SELECT a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy') AS telyear,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '01', a.factration)) AS JAN,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '02', a.factration)) AS FRI,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '03', a.factration)) AS MAR,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '04', a.factration)) AS APR,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '05', a.factration)) AS MAY,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '06', a.factration)) AS JUE,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '07', a.factration)) AS JUL,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '08', a.factration)) AS AGU,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '09', a.factration)) AS SEP,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '10', a.factration)) AS OCT,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '11', a.factration)) AS NOV,
SUM(decode(TO_CHAR(a.telfeedate, 'mm'), '12', a.factration)) AS DEC
FROM (SELECT a.userper, a.tel, a.standfee, b.telfeedate, b.factration
FROM TELFEESTAND a, TELFEE b
WHERE a.tel = b.telfax) a
GROUP BY a.userper, a.tel, a.standfee, TO_CHAR(a.telfeedate, 'yyyy')
说明:四表联查问题:
SQL: select * from a left inner join b on a.a=b.b right inner join c on a.a=c.c inner join d on a.a=d.d where .....
说明:得到表中最小的未使用的ID号
SQL:
SELECT (CASE WHEN EXISTS(SELECT * FROM Handle b WHERE b.HandleID = 1) THEN MIN(HandleID) + 1 ELSE 1 END) as HandleID
FROM Handle
WHERE NOT HandleID IN (SELECT a.HandleID - 1 FROM Handle a)
OC4J里配置数据源:
1.application.xml的<data-sources>元素必须指出data-sources.xml文件的文件名和路径,即:
<data-sources
path = "data-sources.xml"
/>
一般application.xml文件和data-sources.xml 文件都在j2ee/home/config/下。所以<data-sources>元素的path属性只包括data-sources.xml的文件名;
2.data-sources.xml文件中定义数据源:
<data-source
class="com.evermind.sql.DriverManagerDataSource"
name="OracleDS"
location="jdbc/OracleCoreDS"
xa-location="jdbc/xa/OracleXADS"
ejb-location="jdbc/OracleDS"
connection-driver="oracle.jdbc.driver.OracleDriver"
username="hr"
password="hr"
url="jdbc:oracle:thin:@myhost:1521:ORCL"
inactivity-timeout="30"
/>
class属性定义需要定义的数据源类型;
location、xa-location和ejb-location定义JNDI名字;
connection-driver指出连接驱动。
例如:
<data-source
class="com.evermind.sql.DriverManagerDataSource"
name="MyConnection"
location="jdbc/MyConnection"
connection-driver="oracle.jdbc.driver.OracleDriver"
username="portal"
password="pportalgis"
url="jdbc:oracle:thin:@172.18.2.6:1521:apps"
inactivity-timeout="30"
max-connections="50"
max-connect-attempts="2"
min-connections="4"
/>
2.程序调用:
Context env= new InitialContext();
DataSource pool= (DataSource)env.lookup("jdbc/MyConnection");
Connection conn=pool.getConnection();
oracle.jdbc.OracleConnection 分为:
getConnection(); //数据源中已定义用户名和密码
getConnection(String username, String password); //数据源中未定义用户名和密码
可以如下:
oracle.jdbc.OracleConnection conn =(oracle.jdbc.OracleConnection) pool.getConnection();
作为J2EE开发人员,我们似乎经常关注“后端机制(backend mechanics)”。我们通常会忘记,J2EE的主要成功之处在Web应用程序方面;许多原因使得人们喜欢利用Web开发应用程序,但主要还是因为其易于部署的特点允许站点以尽可能低的成本拥有上百万的用户。遗憾的是,在过去几年中,我们在后端投入了太多的时间,而在使我们的Web用户界面对用户自然和响应灵敏方面却投入不足。
本文介绍一种方法,Ajax,使用它可以构建更为动态和响应更灵敏的Web应用程序。该方法的关键在于对浏览器端的JavaScript、DHTML和与服务器异步通信的组合。本文也演示了启用这种方法是多么简单:利用一个Ajax框架(指DWR)构造一个应用程序,它直接从浏览器与后端服务进行通信。如果使用得当,这种强大的力量可以使应用程序更加自然和响应灵敏,从而提升用户的浏览体验。
该应用程序中所使用的示例代码已打包为单独的WAR文件,可供下载。
简介
术语Ajax用来描述一组技术,它使浏览器可以为用户提供更为自然的浏览体验。在Ajax之前,Web站点强制用户进入提交/等待/重新显示范例,用户的动作总是与服务器的“思考时间”同步。Ajax提供与服务器异步通信的能力,从而使用户从请求/响应的循环中解脱出来。借助于Ajax,可以在用户单击按钮时,使用JavaScript和DHTML立即更新UI,并向服务器发出异步请求,以执行更新或查询数据库。当请求返回时,就可以使用JavaScript和CSS来相应地更新UI,而不是刷新整个页面。最重要的是,用户甚至不知道浏览器正在与服务器通信:Web站点看起来是即时响应的。
虽然Ajax所需的基础架构已经出现了一段时间,但直到最近异步请求的真正威力才得到利用。能够拥有一个响应极其灵敏的Web站点确实激动人心,因为它最终允许开发人员和设计人员使用标准的HTML/CSS/JavaScript堆栈创建“桌面风格的(desktop-like)”可用性。
通常,在J2EE中,开发人员过于关注服务和持久性层的开发,以至于用户界面的可用性已经落后。在一个典型的J2EE开发周期中,常常会听到这样的话,“我们没有可投入UI的时间”或“不能用HTML实现”。但是,以下Web站点证明,这些理由再也站不住脚了:
所有这些Web站点都告诉我们,Web应用程序不必完全依赖于从服务器重新载入页面来向用户呈现更改。一切似乎就在瞬间发生。简而言之,在涉及到用户界面的响应灵敏度时,基准设得更高了。
定义Ajax
Adaptive Path公司的Jesse James Garrett这样定义Ajax:
Ajax不是一种技术。实际上,它由几种蓬勃发展的技术以新的强大方式组合而成。Ajax包含:
这非常好,但为什么要以Ajax命名呢?其实术语Ajax是由Jesse James Garrett创造的,他说它是“Asynchronous JavaScript + XML的简写”。
Ajax的工作原理
Ajax的核心是JavaScript对象XmlHttpRequest。该对象在Internet Explorer 5中首次引入,它是一种支持异步请求的技术。简而言之,XmlHttpRequest使您可以使用JavaScript向服务器提出请求并处理响应,而不阻塞用户。
在创建Web站点时,在客户端执行屏幕更新为用户提供了很大的灵活性。下面是使用Ajax可以完成的功能:
- 动态更新购物车的物品总数,无需用户单击Update并等待服务器重新发送整个页面。
- 提升站点的性能,这是通过减少从服务器下载的数据量而实现的。例如,在Amazon的购物车页面,当更新篮子中的一项物品的数量时,会重新载入整个页面,这必须下载32K的数据。如果使用Ajax计算新的总量,服务器只会返回新的总量值,因此所需的带宽仅为原来的百分之一。
- 消除了每次用户输入时的页面刷新。例如,在Ajax中,如果用户在分页列表上单击Next,则服务器数据只刷新列表而不是整个页面。
- 直接编辑表格数据,而不是要求用户导航到新的页面来编辑数据。对于Ajax,当用户单击Edit时,可以将静态表格刷新为内容可编辑的表格。用户单击Done之后,就可以发出一个Ajax请求来更新服务器,并刷新表格,使其包含静态、只读的数据。
一切皆有可能!但愿它能够激发您开始开发自己的基于Ajax的站点。然而,在开始之前,让我们介绍一个现有的Web站点,它遵循传统的提交/等待/重新显示的范例,我们还将讨论Ajax如何提升用户体验。
Ajax可用于那些场景?——一个例子:MSN Money页面
前几天,在浏览MSN Money页面的时候,有一篇关于房地产投资的文章引起了我的好奇心。我决定使用站点的“Rate this article”(评价本文)功能,鼓励其他的用户花一点时间来阅读这篇文章。在我单击vote按钮并等待了一会儿之后,整个页面被刷新,在原来投票问题所在的地方出现了一个漂亮的感谢画面。
而Ajax能够使用户的体验更加愉快,它可以提供响应更加灵敏的UI,并消除页面刷新所带来的闪烁。目前,由于要刷新整个页面,需要传送大量的数据,因为必须重新发送整个页面。如果使用Ajax,服务器可以返回一个包含了感谢信息的500字节的消息,而不是发送26,813字节的消息来刷新整个页面。即使使用的是高速Internet,传送26K和1/2K的差别也非常大。同样重要的是,只需要刷新与投票相关的一小节,而不是刷新整个屏幕。
让我们利用Ajax实现自己的基本投票系统。
原始的Ajax:直接使用XmlHttpRequest
如上所述,Ajax的核心是JavaScript对象XmlHttpRequest。下面的示例文章评价系统将带您熟悉Ajax的底层基本知识:http://tearesolutions.com/ajax-demo/raw-ajax.html。注:如果您已经在本地WebLogic容器中安装了ajax-demo.war,可以导航到http://localhost:7001/ajax-demo/raw-ajax.html,
浏览应用程序,参与投票,并亲眼看它如何运转。熟悉了该应用程序之后,继续阅读,进一步了解其工作原理细节。
首先,您拥有一些简单的定位点标记,它连接到一个JavaScriptcastVote(rank)函数。
function castVote(rank) {
var url = "/ajax-demo/static-article-ranking.html";
var callback = processAjaxResponse;
executeXhr(callback, url);
}
该函数为您想要与之通信的服务器资源创建一个URL并调用内部函数executeXhr,提供一个回调JavaScript函数,一旦服务器响应可用,该函数就被执行。由于我希望它运行在一个简单的Apache环境中,“cast vote URL”只是一个简单的HTML页面。在实际情况中,被调用的URL将记录票数并动态地呈现包含投票总数的响应。
下一步是发出一个XmlHttpRequest请求:
function executeXhr(callback, url) {
// branch for native XMLHttpRequest object
if (window.XMLHttpRequest) {
req = new XMLHttpRequest();
req.onreadystatechange = callback;
req.open("GET", url, true);
req.send(null);
} // branch for IE/Windows ActiveX version
else if (window.ActiveXObject) {
req = new ActiveXObject("Microsoft.XMLHTTP");
if (req) {
req.onreadystatechange = callback;
req.open("GET", url, true);
req.send();
}
}
}
如您所见,执行一个XmlHttpRequest并不简单,但非常直观。和平常一样,在JavaScript领域,大部分的工作量都花在确保浏览器兼容方面。在这种情况下,首先要确定XmlHttpRequest是否可用。如果不能用,很可能要使用Internet Explorer,这样就要使用所提供的ActiveX实现。
executeXhr()方法中最关键的部分是这两行:
req.onreadystatechange = callback;
req.open("GET", url, true);
第一行定义了JavaScript回调函数,您希望一旦响应就绪它就自动执行,而req.open()方法中所指定的“true”标志说明您想要异步执行该请求。
一旦服务器处理完XmlHttpRequest并返回给浏览器,使用req.onreadystatechange指派所设置的回调方法将被自动调用。
function processAjaxResponse() {
// only if req shows "loaded"
if (req.readyState == 4) {
// only if "OK"
if (req.status == 200) {
502 502'votes').innerHTML = req.responseText;
} else {
alert("There was a problem retrieving the XML data:
" +
req.statusText);
}
}
}
该代码相当简洁,并且使用了几个幻数,这使得难以一下子看出发生了什么。为了弄清楚这一点,下面的表格(引用自http://developer.apple.com/internet/webcontent/xmlhttpreq.html)列举了常用的XmlHttpRequest对象属性。
属性 | 描述 |
onreadystatechange | 每次状态改变所触发事件的事件处理程序 |
readyState | 对象状态值:
- 0 = 未初始化(uninitialized)
- 1 = 正在加载(loading)
- 2 = 加载完毕(loaded)
- 3 = 交互(interactive)
- 4 = 完成(complete)
|
responseText | 从服务器进程返回的数据的字符串形式 |
responseXML | 从服务器进程返回的DOM兼容的文档数据对象 |
status | 从服务器返回的数字代码,比如404(未找到)或200(就绪) |
statusText | 伴随状态码的字符串信息 |
现在processVoteResponse()函数开始显示出其意义了。它首先检查XmlHttpRequest的整体状态以保证它已经完成(readyStatus == 4),然后根据服务器的设定询问请求状态。如果一切正常(status == 200),就使用innerHTML属性重写DOM的“votes”节点的内容。
既然您亲眼看到了XmlHttpRequest对象是如何工作的,就让我们利用一个旨在简化JavaScript与Java应用程序之间的异步通信的框架来对具体的细节进行抽象。
Ajax: DWR方式
按照与文章评价系统相同的流程,我们将使用Direct Web Remoting(DWR)框架实现同样的功能。
假定文章和投票结果存储在一个数据库中,使用某种对象/关系映射技术来完成抽取工作。为了部署起来尽可能地简单,我们不会使用数据库进行持久性存储。此外,为使应用程序尽可能通用,也不使用Web框架。相反,应用程序将从一个静态HTML文件开始,可以认为它由服务器动态地呈现。除了这些简化措施,应用程序还应该使用Spring Framework关联一切,以便轻松看出如何在一个“真实的”应用程序中使用DWR。
现在应该下载示例应用程序并熟悉它。该应用程序被压缩为标准的WAR文件,因此您可以把它放置到任何一个Web容器中——无需进行配置。部署完毕之后,就可以导航到http://localhost:7001/ajax_demo/dwr-ajax.html来运行程序。
可以查看HTML 源代码,了解它如何工作。给人印象最深的是,代码如此简单——所有与服务器的交互都隐藏在JavaScript对象ajaxSampleSvc的后面。更加令人惊讶的是,ajaxSampleSvc服务不是由手工编写而是完全自动生成的!让我们继续,看看这是如何做到的。
引入DWR
如同在“原始的Ajax”一节所演示的那样,直接使用XmlHttpRequest创建异步请求非常麻烦。不仅JavaScript代码冗长,而且必须考虑服务器端为定位Ajax请求到适当的服务所需做的工作,并将结果封送到浏览器。
设计DWR的目的是要处理将Web页面安装到后端服务上所需的所有信息管道。它是一个Java框架,可以很轻松地将它插入到Web应用程序中,以便JavaScript代码可以调用服务器上的服务。它甚至直接与Spring Framework集成,从而允许用户直接向Web客户机公开bean。
DWR真正的巧妙之处是,在用户配置了要向客户机公开的服务之后,它使用反射来生成JavaScript对象,以便Web页面能够使用这些对象来访问该服务。然后Web页面只需接合到生成的JavaScript对象,就像它们是直接使用服务一样;DWR无缝地处理所有有关Ajax和请求定位的琐碎细节。
让我们仔细分析一下示例代码,弄清它是如何工作的。
应用程序细节:DWR分析
关于应用程序,首先要注意的是,它是一个标准的Java应用程序,使用分层架构(Layered Architecture)设计模式。使用DWR通过JavaScript公开一些服务并不影响您的设计。
下面是一个简单的Java服务,我们将使用DWR框架直接将其向JavaScript代码公开:
package com.tearesolutions.service;
public interface AjaxSampleSvc {
Article castVote(int rank);
}
这是一个被简化到几乎不可能的程度的例子,其中只有一篇文章可以投票。该服务由Spring管理,它使用的bean名是ajaxSampleSvc,它的持久性需求则依赖于ArticleDao。详情请参见applicationContext.xml。
为了把该服务公开为JavaScript对象,需要配置DWR,添加dwr.xml文件到WEB-INF目录下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE dwr PUBLIC
"-//GetAhead Limited//DTD Direct Web Remoting 0.4//EN"
"http://www.getahead.ltd.uk/dwr/dwr.dtd">
<dwr>
<allow>
<create creator="spring" javascript="ajaxSampleSvc">
<param name="beanName" value="ajaxSampleSvc" />
</create>
<convert converter="bean" match="com.tearesolutions.model.Article"/>
<exclude method="toString"/>
<exclude method="setArticleDao"/>
</allow>
</dwr>
dwr.xml文件告诉DWR哪些服务是要直接向JavaScript代码公开的。注意,已经要求公开Spring bean ajaxSampleSvc。DWR将自动找到由应用程序设置的SpringApplicationContext。为此,必须使用标准的servlet过滤器ContextLoaderListener来初始化Spring ApplicationContext。
DWR被设置为一个servlet,所以把它的定义添加到web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!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>
<display-name>Ajax Examples</display-name>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<servlet>
<servlet-name>ajax_sample</servlet-name>
<servlet-class>com.tearesolutions.web.AjaxSampleServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<description>Direct Web Remoter Servlet</description>
<servlet-class>uk.ltd.getahead.dwr.DWRServlet</servlet-class>
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>ajax_sample</servlet-name>
<url-pattern>/ajax_sample</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>dwr-invoker</servlet-name>
<url-pattern>/dwr/*</url-pattern>
</servlet-mapping>
</web-app>
做完这些之后,可以加载http://localhost:7001/ajax-demo/dwr,看看哪些服务可用。结果如下:
图3. 可用的服务
单击ajaxSampleSvc链接,查看有关如何在HTML页面内直接使用服务的示例实现。其中包含的两个JavaScript文件完成了大部分的功能:
<script type='text/javascript'
src='/ajax-demo/dwr/interface/ajaxSampleSvc.js'></script>
<script type='text/javascript'
src='/ajax-demo/dwr/engine.js'></script>
ajaxSampleSvc.js是动态生成的:
function ajaxSampleSvc() { }
ajaxSampleSvc.castVote = function(callback, p0)
{
DWREngine._execute(callback, '/ajax-demo/dwr',
'ajaxSampleSvc', 'castVote', p0);
}
现在可以使用JavaScript对象ajaxSampleSvc替换所有的XmlHttpRequest代码,从而重构raw-ajax.html文件。可以在dwr-ajax.html文件中看到改动的结果;下面是新的JavaScript函数:
function castVote(rank) {
ajaxSampleSvc.castVote(processResponse, rank);
}
function processResponse(data) {
var voteText = "Thanks for Voting!
"
+ "Current ranking: " + data.voteAverage
+ " out of 5
"
+ "Number of votes placed: "
+ data.numberOfVotes + "
";
502 502'votes').innerHTML = voteText;
}
惊人地简单,不是吗?由ajaxSampleSvc对象返回的Article域对象序列化为一个JavaScript对象,允许在它上面调用诸如numberOfVotes()和voteAverage()之类的方法。在动态生成并插入到DIV元素“votes”中的HTML代码内使用这些数据。
下一步工作
在后续文章中,我将继续有关Ajax的话题,涉及下面这些方面:
像许多技术一样,Ajax是一把双刃剑。对于一些用例,其应用程序其实没有必要使用Ajax,使用了反而有损可用性。我将介绍一些不适合使用的模式,突出说明Ajax的一些消极方面,并展示一些有助于缓和这些消极方面的机制。例如,对Netflix电影浏览器来说,Ajax是合适的解决方案吗?或者,如何提示用户确实出了一些问题,而再次单击按钮也无济于事?
在使用Ajax时,最初的文档DOM会发生一些变化,并且有大量的页面状态信息存储在客户端变量中。当用户跟踪一个链接到应用程序中的另一个页面时,状态就丢失了。当用户按照惯例单击Back按钮时,呈现给他们的是缓存中的初始页面。这会使用户感到非常迷惑!
使用JavaScript在客户端执行更多的工作时,如果事情不按预期方式进行,就需要一些调试工具来帮助弄清出现了什么问题。
结束语
本文介绍了Ajax方法,并展示了如何使用它来创建一个动态且响应灵敏的Web应用程序。通过使用DWR框架,可以轻松地把Ajax融合到站点中,而无需担心所有必须执行的实际管道工作。
特别感谢Getahead IT咨询公司的Joe Walker和他的团队开发出DWR这样神奇的工具。感谢你们与世界共享它!
下载
本文中演示的应用程序源代码可供下载:ajax-demo.war(1.52 MB)。
参考资料
原文出处
An Introduction To Ajax
http://dev2dev.bea.com/pub/a/2005/08/ajax_introduction.html
国际化是使程序具有足够的灵活性、能在世界上任何地区运行的过程。国际化所要求的必然结果是地方化――使一个程序能够运行在特定地区的过程。本文尝试用一个简单的例子来演示Java用户界面本地化。Java语言内核基于Unicode3.0(Java 1.4)提供了对不同国家和不同语言文字的内部支持,由于先天的原因,Java对于国际化的支持远远要比C/C++来的优越。
在我看来本地化必须满足以下的三个条件:
1、程序必须能读、写和操作本地化的文本。
2、程序在显示日期和时间、使数字格式化以及排序子串时,必须符合地方习惯。(通过java.text包里面的类可以实现这些要求)
3、所有用户可见的文本都能在运行时获得,而不是直接写入程序中。(通过java.util包里的ResourceBundle类和他的子类可以实现这些要求。)
实现这三个方面可以真正实现程序的国际化。
首先让我们来了解一下地区。地区代表一个地理上、政治上或文化上的区域。在Java中,地区由java.util.Locale类表示。地区常常以一种语言来定义,该语言则由其标准的小写双字母代码表示。(例如:en代表英国,fr代表法国,zh代表中国),但有时候语言是不能代表一个地区的,那就要在语言后面再加上一个国家或该国家的地域(例如:en_US代表美国,zh_TW)。Locale类保存着一个静态的默认地区,它可以用Locale.setDefault()和Locale.getDefault()来设置和查询。一个程序可以生成和使用任意数目的非默认Locale对象。
让我们再来看一下Unicode字符编码。Java使用Unicode的字符编码,其本身就是迈向国际化的一大步。Unicode编码其每个字符都占两个字节。用\u****的形式表示。Unicode的字符可以等价于其他编码的字符(例如:从\u0020到\u007E的字符等价于ASCII和ISO8859-1字符的0x20到0x7E)。
本文主要是对用户界面地方化,由于我使用的是资源束!所以有必要对资源束作一下解释。
为定义一束地方化的资源,你需要生成一个ResourceBundle(资源束)的子类并且提供handleGetObject()和getKeys()方法的定义。为了在程序中使用来自ResourceBundle的地方化资源,就需要先调用静态的getBundle()方法,用getBundle()获得一个ResourceBundle对象,然后再用getObject()方法去按照名字来查找资源。当然也可以使用getString()简单的把getObject()的返回值分配给一个String对象。GetBundle()方法采用basename_language_country_variait----没找到的话->basename_language_country----没找到的话->basename_language----没找到的话->basename(默认资源文件)的算法寻找合适的资源。如果以上都没找到的话,则会抛出一个MissingResourceException异常。
现在我们来看一个简单的例子,如何使Java程序用户界面地方化的。
首先我们的程序需要查找特定Locale对象关联的资源包,所以应该定义一个Local对象,来获取本地默认的地区!然后可以调用ResourceBundle的getBundle方法,并将locale对象作为参数传入。
清单一:
Locale locale = Locale.getDefault(); //获取地区:默认
//获取资源束。如未发现则会抛出MissingResourceException异常
ResourceBundle bundle = ResourceBundle.getBundle("Properties.Dorian",locale);
清单一中的”Properties.Dorian”代表Properties包下以Dorian命名的默认资源文件。这样就可以使用资源文件了!让我们来看看资源文件是如何定义的。
清单二:
# Dorian.properties是默认的"Dorian"资源束文件。
# 作为中国人,我用自己的地区作为默认
Title=\u4e2d\u56fd;
red.label=\u7ea2\u8272;
green.label=\u7eff\u8272;
blue.label=\u84dd\u8272;
清单三:
# 文件Dorian_en_US.properties,是美国地区的资源束
# 它覆盖了默认资源束
Title=America;
red.label=Red;
green.label=Green;
blue.label=Blue ;
清单一和二定义了一个默认资源文件,和美国地区的资源文件。其中等号左边的字符串表示主键,它们是唯一的。为了获得主键对应的值,你可以调用ResourceBundle类的getString方法,并将主键作为参数。此外,文件中以“#”号开头的行表示注释行。需要注意的是清单二中的“\u4e2d\u56fd”,它是字符“中国”的Unicode字符码。是使用Java自带的native2ascii工具转换的(native2ascii in.properties out.properties),这是为了不在程序界面中产生乱码。
清单四:
cmdRed.setText(bundle.getString("red.label"));
cmdBlue.setText (bundle.getString("blue.label"));
cmdGreen.setText (bundle.getString("green.label"));
清单二中的cmdRed、cmdBlue、cmdGreen 为按钮。bundle.getString("red.label")为得到资源文件中主键是red.label的值。
好了到此为止Java程序用户界面的本地化就是这么简单。不过,要提醒你的是在为用户界面事件编写事件监听器代码时,要格外小心。请看下面这段代码。
清单五:
public class MyApplet extends Japplet implements ActionListener{
public void init(){
JButton cancelButton=new JButton(“Cancel”);
CancelButton.addActionListener(this);
...
}
public void actionPerformed(ActionEvent e){
String s=e.getActionCommand();
if(arg.equals(“Cancel”);
doCancel();
else ……
}
}
如果你对清单五的代码不进行本地化,她就可能会运行的很好。但当你的按钮被本地化为中文时,“Cancel”变为了“取消”。这时就会出现你不愿意看到的问题。下面有三个方法可以消除这个潜在的问题!
1> 使用内部类而不使用独立的actionPerformed程序。
2> 使用引号而不使用标签来标识组件。
3> 使用name属性来标识组件
本例稍后的代码就是采用第一种方法来消除这个问题的。
清单六:完整的代码
//:MyNative.java
/**
Copyright (c) 2003 Dorian. All rights reserved
@(#)MyNative.java 2003-12-21
@author Dorian
@version 1.0.0
visit http://www.Dorian.com/Java/
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.*;
/**
这是一个将Java程序界面地方化的例子本例采用读取属性文件来达到目的
@see java.util.Locale;
@see java.util.ResourceBundle;
@see java.util.MissingResourceException;
*/
public class MyNative{
public static void main(String[] args){
JFrame frame = new MyNativeFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setResizable(false);
frame.setVisible(true); // Pop the window up.
}
}
class MyNativeFrame extends JFrame{
public MyNativeFrame(){
Locale locale = Locale.getDefault();//获取地区:默认
//获取资源束。如未发现则会抛出MissingResourceException异常
//"Properties.Dorian"为在Properties下以Dorian为文件名的默认属性文件
ResourceBundle bundle = ResourceBundle.getBundle("Properties.Dorian",locale);
setTitle(bundle.getString("Title"));//通过getString()的返回值来设置Title
setSize(WIDTH,HEIGHT); // Set the window size.
panel=new MyNativePanel();
Container contentPane=getContentPane();
contentPane.add(panel);
//通过获取资源束中*.label的值对三个按钮设置其Label
panel.setCmdRed(bundle.getString("red.label"));
panel.setCmdBlue(bundle.getString("blue.label"));
panel.setCmdGreen(bundle.getString("green.label"));
}
private MyNativePanel panel;
private static final int WIDTH=400;
private static final int HEIGHT=100;
}
class MyNativePanel extends JPanel{
public MyNativePanel(){
layout=new BorderLayout();
setLayout(layout);
txt=new JTextField(50);
add(txt,layout.CENTER);
cmdRed=new JButton();
cmdBlue=new JButton();
cmdGreen=new JButton();
panel.add(cmdRed);
panel.add(cmdBlue);
panel.add(cmdGreen);
add(panel,layout.SOUTH);
cmdRed.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = e.getActionCommand();
txt.setBackground(Color.red);
txt.setText(s);
}
});
cmdBlue.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
String s = e.getActionCommand();
txt.setBackground(Color.blue);
txt.setText(s);
}
});
Log4j基本使用方法
|
作者:佚名 来自:未知
Log4j由三个重要的组件构成:日志信息的优先级,日志信息的输出目的地,日志信息的输出格式。日志信息的优先级从高到低有ERROR、WARN、INFO、DEBUG,分别用来指定这条日志信息的重要程度;日志信息的输出目的地指定了日志将打印到控制台还是文件中;而输出格式则控制了日志信息的显示内容。
一、定义配置文件
其实您也可以完全不使用配置文件,而是在代码中配置Log4j环境。但是,使用配置文件将使您的应用程序更加灵活。Log4j支持两种配置文件格式,一种是XML格式的文件,一种是Java特性文件(键=值)。下面我们介绍使用Java特性文件做为配置文件的方法:
1.配置根Logger,其语法为:
log4j.rootLogger = [ level ] , appenderName, appenderName, …
其中,level 是日志记录的优先级,分为OFF、FATAL、ERROR、WARN、INFO、DEBUG、ALL或者您定义的级别。Log4j建议只使用四个级别,优先级从高到低分别是ERROR、WARN、INFO、DEBUG。通过在这里定义的级别,您可以控制到应用程序中相应级别的日志信息的开关。比如在这里定义了INFO级别,则应用程序中所有DEBUG级别的日志信息将不被打印出来。 appenderName就是指定日志信息输出到哪个地方。您可以同时指定多个输出目的地。
2.配置日志信息输出目的地Appender,其语法为:
log4j.appender.appenderName = fully.qualified.name.of.appender.class log4j.appender.appenderName.option1 = value1 … log4j.appender.appenderName.option = valueN
其中,Log4j提供的appender有以下几种: org.apache.log4j.ConsoleAppender(控制台), org.apache.log4j.FileAppender(文件), org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件), org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件), org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)
3.配置日志信息的格式(布局),其语法为:
log4j.appender.appenderName.layout = fully.qualified.name.of.layout.class log4j.appender.appenderName.layout.option1 = value1 … log4j.appender.appenderName.layout.option = valueN
其中,Log4j提供的layout有以下几种: org.apache.log4j.HTMLLayout(以HTML表格形式布局), org.apache.log4j.PatternLayout(可以灵活地指定布局模式), org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串), org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)
Log4J采用类似C语言中的printf函数的打印格式格式化日志信息,打印参数如下: %m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL %r 输出自应用启动到输出该log信息耗费的毫秒数 %c 输出所属的类目,通常就是所在类的全名 %t 输出产生该日志事件的线程名 %n 输出一个回车换行符,Windows平台为“\r\n”,Unix平台为“\n” %d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921 %l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main(TestLog4.java:10)
二、在代码中使用Log4j
1.得到记录器
使用Log4j,第一步就是获取日志记录器,这个记录器将负责控制日志信息。其语法为:
public static Logger getLogger( String name)
通过指定的名字获得记录器,如果必要的话,则为这个名字创建一个新的记录器。Name一般取本类的名字,比如:
static Logger logger = Logger.getLogger ( ServerWithLog4j.class.getName () )
2.读取配置文件
当获得了日志记录器之后,第二步将配置Log4j环境,其语法为:
BasicConfigurator.configure (): 自动快速地使用缺省Log4j环境。 PropertyConfigurator.configure ( String configFilename) :读取使用Java的特性文件编写的配置文件。 DOMConfigurator.configure ( String filename ) :读取XML形式的配置文件。
3.插入记录信息(格式化日志信息)
当上两个必要步骤执行完毕,您就可以轻松地使用不同优先级别的日志记录语句插入到您想记录日志的任何地方,其语法如下:
Logger.debug ( Object message ) ; Logger.info ( Object message ) ; Logger.warn ( Object message ) ; Logger.error ( Object message ) ;
|
众所周知,Internet的基本协议是TCP/IP协议,目前广泛采用的FTP、Archie Gopher等是建立在TCP/IP协议之上的应用层协议,不同的协议对应着不同的应用。
WWW服务器使用的主要协议是HTTP协议,即超文体传输协议。由于HTTP协议支持的服务不限于WWW,还可以是其它服务,因而HTTP协议允许用户在统一的界面下,采用不同的协议访问不同的服务,如FTP、Archie、SMTP、NNTP等。另外,HTTP协议还可用于名字服务器和分布式对象管理。
2.1 HTTP协议简介
HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。目前在WWW中使用的是HTTP/1.0的第六版,HTTP/1.1的规范化工作正在进行之中,而且HTTP-NG(Next Generation of HTTP)的建议已经提出。
HTTP协议的主要特点可概括如下:
1.支持客户/服务器模式。
2.简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。
由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
3.灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
4.无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
5.无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
2.2 HTTP协议的几个重要概念
1.连接(Connection):一个传输层的实际环流,它是建立在两个相互通讯的应用程序之间。
2.消息(Message):HTTP通讯的基本单位,包括一个结构化的八元组序列并通过连接传输。
3.请求(Request):一个从客户端到服务器的请求信息包括应用于资源的方法、资源的标识符和协议的版本号
4.响应(Response):一个从服务器返回的信息包括HTTP协议的版本号、请求的状态(例如“成功”或“没找到”)和文档的MIME类型。
5.资源(Resource):由URI标识的网络数据对象或服务。
6.实体(Entity):数据资源或来自服务资源的回映的一种特殊表示方法,它可能被包围在一个请求或响应信息中。一个实体包括实体头信息和实体的本身内容。
7.客户机(Client):一个为发送请求目的而建立连接的应用程序。
8.用户代理(User agent):初始化一个请求的客户机。它们是浏览器、编辑器或其它用户工具。
9.服务器(Server):一个接受连接并对请求返回信息的应用程序。
10.源服务器(Origin server):是一个给定资源可以在其上驻留或被创建的服务器。
11.代理(Proxy):一个中间程序,它可以充当一个服务器,也可以充当一个客户机,为其它客户机建立请求。请求是通过可能的翻译在内部或经过传递到其它的服务器中。一个代理在发送请求信息之前,必须解释并且如果可能重写它。
代理经常作为通过防火墙的客户机端的门户,代理还可以作为一个帮助应用来通过协议处理没有被用户代理完成的请求。
12.网关(Gateway):一个作为其它服务器中间媒介的服务器。与代理不同的是,网关接受请求就好象对被请求的资源来说它就是源服务器;发出请求的客户机并没有意识到它在同网关打交道。
网关经常作为通过防火墙的服务器端的门户,网关还可以作为一个协议翻译器以便存取那些存储在非HTTP系统中的资源。
13.通道(Tunnel):是作为两个连接中继的中介程序。一旦激活,通道便被认为不属于HTTP通讯,尽管通道可能是被一个HTTP请求初始化的。当被中继的连接两端关闭时,通道便消失。当一个门户(Portal)必须存在或中介(Intermediary)不能解释中继的通讯时通道被经常使用。
14.缓存(Cache):反应信息的局域存储。
2.3 HTTP协议的运作方式
HTTP协议是基于请求/响应范式的。一个客户机与服务器建立连接后,发送一个请求给服务器,请求方式的格式为,统一资源标识符、协议版本号,后边是MIME信息包括请求修饰符、客户机信息和可能的内容。服务器接到请求后,给予相应的响应信息,其格式为一个状态行包括信息的协议版本号、一个成功或错误的代码,后边是MIME信息包括服务器信息、实体信息和可能的内容。
许多HTTP通讯是由一个用户代理初始化的并且包括一个申请在源服务器上资源的请求。最简单的情况可能是在用户代理(UA)和源服务器(O)之间通过一个单独的连接来完成(见图2-1)。
图2-1
当一个或多个中介出现在请求/响应链中时,情况就变得复杂一些。中介由三种:代理(Proxy)、网关(Gateway)和通道(Tunnel)。一个代理根据URI的绝对格式来接受请求,重写全部或部分消息,通过URI的标识把已格式化过的请求发送到服务器。网关是一个接收代理,作为一些其它服务器的上层,并且如果必须的话,可以把请求翻译给下层的服务器协议。一个通道作为不改变消息的两个连接之间的中继点。当通讯需要通过一个中介(例如:防火墙等)或者是中介不能识别消息的内容时,通道经常被使用。 图2-2
上面的图2-2表明了在用户代理(UA)和源服务器(O)之间有三个中介(A,B和C)。一个通过整个链的请求或响应消息必须经过四个连接段。这个区别是重要的,因为一些HTTP通讯选择可能应用于最近的连接、没有通道的邻居,应用于链的终点或应用于沿链的所有连接。尽管图2-2是线性的,每个参与者都可能从事多重的、并发的通讯。例如,B可能从许多客户机接收请求而不通过A,并且/或者不通过C把请求送到A,在同时它还可能处理A的请求。
任何针对不作为通道的汇聚可能为处理请求启用一个内部缓存。缓存的效果是请求/响应链被缩短,条件是沿链的参与者之一具有一个缓存的响应作用于那个请求。下图说明结果链,其条件是针对一个未被UA或A加缓存的请求,B有一个经过C来自O的一个前期响应的缓存拷贝。
图2-3
在Internet上,HTTP通讯通常发生在TCP/IP连接之上。缺省端口是TCP 80,但其它的端口也是可用的。但这并不预示着HTTP协议在Internet或其它网络的其它协议之上才能完成。HTTP只预示着一个可靠的传输。
以上简要介绍了HTTP协议的宏观运作方式,下面介绍一下HTTP协议的内部操作过程。
首先,简单介绍基于HTTP协议的客户/服务器模式的信息交换过程,如图2-4所示,它分四个过程,建立连接、发送请求信息、发送响应信息、关闭连接。
图2-4
在WWW中,“客户”与“服务器”是一个相对的概念,只存在于一个特定的连接期间,即在某个连接中的客户在另一个连接中可能作为服务器。WWW服务器运行时,一直在TCP80端口(WWW的缺省端口)监听,等待连接的出现。
下面,讨论HTTP协议下客户/服务器模式中信息交换的实现。 1.建立连接 连接的建立是通过申请套接字(Socket)实现的。客户打开一个套接字并把它约束在一个端口上,如果成功,就相当于建立了一个虚拟文件。以后就可以在该虚拟文件上写数据并通过网络向外传送。
2.发送请求
打开一个连接后,客户机把请求消息送到服务器的停留端口上,完成提出请求动作。
HTTP/1.0 请求消息的格式为:
请求消息=请求行(通用信息|请求头|实体头) CRLF[实体内容]
请求 行=方法 请求URL HTTP版本号 CRLF
方 法=GET|HEAD|POST|扩展方法
U R L=协议名称+宿主名+目录与文件名
请求行中的方法描述指定资源中应该执行的动作,常用的方法有GET、HEAD和POST。不同的请求对象对应GET的结果是不同的,对应关系如下:
对象 GET的结果
文件 文件的内容
程序 该程序的执行结果
数据库查询 查询结果
HEAD——要求服务器查找某对象的元信息,而不是对象本身。
POST——从客户机向服务器传送数据,在要求服务器和CGI做进一步处理时会用到POST方法。POST主要用于发送HTML文本中FORM的内容,让CGI程序处理。
一个请求的例子为:
GET http://networking.zju.edu.cn/zju/index.htm HTTP/1.0
头信息又称为元信息,即信息的信息,利用元信息可以实现有条件的请求或应答 。
请求头——告诉服务器怎样解释本次请求,主要包括用户可以接受的数据类型、压缩方法和语言等。
实体头——实体信息类型、长度、压缩方法、最后一次修改时间、数据有效期等。
实体——请求或应答对象本身。
3.发送响应
服务器在处理完客户的请求之后,要向客户机发送响应消息。
HTTP/1.0的响应消息格式如下:
响应消息=状态行(通用信息头|响应头|实体头) CRLF 〔实体内容〕
状 态 行=HTTP版本号 状态码 原因叙述
状态码表示响应类型
1×× 保留
2×× 表示请求成功地接收
3×× 为完成请求客户需进一步细化请求
4×× 客户错误
5×× 服务器错误
响应头的信息包括:服务程序名,通知客户请求的URL需要认证,请求的资源何时能使用。
4.关闭连接
客户和服务器双方都可以通过关闭套接字来结束TCP/IP对话
1)安装 bea weblogic8.1 server版本。(server812_win32.exe)
2)在安装中一般的按默认值设置
3)安装完成后,在开始菜单中找到weblogic的安装目录下的“Configuration Wizard”,
点击进入,开始创建一个新的weblogic Configuration.一般的都可以采取默认值,其中要设置服务器密码(如果式第一次使用),完成后可运行“starweblogic.cmd”;
4)如果要简单的使用一个符合基本web应用结构的文件夹,可以拷贝到%weblogic_home%/user_projects\domains\mydomain\applications
5)重启startweblogc.cmd
6)在浏览器中输入:
http://localhost:7001/你的web应用的文件夹结构。
7)如果要配置weblogic服务器的一些系统信息。可以登陆
http://localhost:7001/console输入用户名和密码进行登陆配置,在其中可以进行许多的web应用的部署。
在weblogic的控制台部署一个web应用(WAR),1)我发现既可以直接如上面的那样把web的应用结构文件夹拷贝使用,也可以使用war包部署
2)首先使用java的jar命令来进行压缩(我发现weblogic不能识别jar包,不明白为什么)
3)jar命令很简单,详细,可以输入jar回车看jdk的中文帮助。
如:(不知道我得jdk环境出了什么问题,不能识别jar外部命令,只好使用引用路径)
D:\j2sdk1.4\bin\web>d:\j2sdk1.4\bin\jar cvf web.war *.*
//说明:使用jar命令把当前目录下的所有文件(必须有web-inf文件夹)压缩为web.war,其中cvf表示:
//创建一个新的存档/生成详细输出到标准输出上/指定存档文件名(即web.war)
4)拷贝该文件到weblogic_home%/user_projects\domains\mydomain\applications\,
5)登陆weblogic的控制台console,在左侧点击mydomain/deployment/web/application Modules点击后,在右侧
浏览到你的web.war文件,选中他,点击deploy,如果没有红色的提示,表示部署成功,反之,检查你的war文件是否正确。
6)部署中你要输入一个名字,用来管理。默认即可,重启服务器,在浏览器中输入:
http://localhost:70001/web/你的具体目录。
进行访问,如果能看到你的jsp说明一切ok。