Topic: JAVA学习日子分享

  Print this page

1.JAVA学习日子分享 Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-16 16:03

本人正在参加JAVA培训!把学习中的一些东西发上共享下!希望可以帮助JAVA爱号者!在以后的学习中大家共同进步

1. 同学的一个问题
他用javac(1.4)编译,用java(1.6)运行,出现不支持的类版本错误。我们用javac -version和java -version各看了一下版本,就发现了这个问题。然后查看path环境变量,发现他计算机上安装了oracle,oracle/bin排在了整个path的前面,调整path,让jdk1.6/bin排在最前面即可。
2. 由内存中一切皆二进制引出字符编码的讲解
大陆写的“中”到台湾显示不正常的原理分析,翻译软件的翻译原理,GBK-->“中”-->BIG5。讲解UTF-8编码和unicode编码,ASCII与Unicode码的转换规则,演示记事本显示字符时的趣味问题,分析乱码原因,GB2312码中也包含英文字符,如何识别GB2312码中的英文与汉字。最后课结束时讲了GB18030,如何支持?
3. xml文档中设置encoding属性的重要性
xml文档保存的编码类型和encoding指定的编码方式是两码事,前者表示xml文档内容的编码方式而后者是告诉解析器以什么编码方式来解析xml文档。二者必须一致,否则在浏览器中打开xml文档就会出现问题。默认情况下encoding属性的值是UTF-8。
沈继龙:以为指定了encoding="GBK",那文件就用GBK保存了,这正好理解反了。我是张,我戴顶帽子说明我是张,以便解析软件知道我是谁,如果我戴顶李的帽子,解析软件就认为我是李,显然就出了问题。
4. CDATA区
要小心的是XML文档是通过一个程序生成出来的,如下所示的一个jsp程序,对于用变量生成的信息,
要特别注意加上CDATA区。
<%@page pageEncoding="GBK"%>
<%@page contentType="text/xml;charset=UTF-8"%>
<?xml version="1.0" encoding="UTF-8"?>
<country>
<name>中国</name>
<info><![CDATA[${param.info}]]></info>
</country>
这个JSP文件涉及了两个编码:源文件是用什么码写的,程序执行后以什么码输出结果。
为了加深理解处理软件必须文件中的字符编码的情况,又演示了javac编译utf-8源文件的问题。
与CDATA区类似的一个小技巧:
<%@page pageEncoding="GBK"%>
<form>
<input type="hidden" name="email" value="${param.email}"/>
请输入用户名:<input type="text" name="name" />
</form>
如果给隐藏字段传递的参数是“zxx" a="b”,那么也会出问题,对于程序生成值时,一定要考虑值的特殊情况。
5. 编码转换
编码转换程序:
char [] codes = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
byte b = (byte)Integer.parseInt(args[0]);
System.out.print(codes[((b>>4) & 0x0f)]);
System.out.println(codes[(b & 0x0f)]);
得到字符的big5码
<%@page pageEncoding="GBK"%>
<%@page contentType="text/html;charset=GBK"%>//修改contentType="audio/x-mp3"说明头的作用
<%
String china="中一二";
for(int i=0;i<china.length();i++)
{
out.println(Integer.toHexString((int)china.charAtLight Bulb));
}
System.out.println();
byte[] bufGBK = china.getBytes("GBK");
for(int i=0;i<bufGBK.length;i++)
{
out.println(Integer.toHexString(bufGBK [i]));
}
byte[] buf = china.getBytes("Big5");
for(int i=0;i<buf.length;i++)
{
out.println(Integer.toHexString(buf[i]));
}
byte [] buf ={0xa4, 0xa4,0xa4,0x40,0xa4,0x47}
%>
输出big5码给浏览器:
<%
byte [] buf ={(byte)0xa4, (byte)0xa4,(byte)0xa4,(byte)0x40,(byte)0xa4,(byte)0x47};
response.getOutputStream().write(buf);
%>
6. 区分中文英文的程序代码
buf[] = new byte[1024];
int len = System.in.read(buf);
boolean halfChinese = false;
for(int i=0;i<len;i++)
{
if(halfChinese)
{
//buf[i-1] + buf[i]合并
System.out.write('[');
Systen.out.write(buf[i-1]);
Systen.out.write(buf[i]);
System.out.write(']');
halfChinese = false;
continue;
}
if((buf[i] & 0x80) == 0)
{
//为什么必须用write???
System.out.write('[');
Systen.out.write(buf[i]);
System.out.write(']');
}
else
{
halfChinese = true;
//等下一个,暂时不处理
/*
System.out.write('[');
Systen.out.write(buf[i++]);
Systen.out.write(buf[i]);
System.out.write(']');
*/
}
}
System.out.write();方法要用flush();刷新缓存,才能正常显示。
我写的代码,但还有地方没弄明白:为什么去掉了if()判断是否有'\r','\n'后,显示的结果不正常。
import java.io.*;
class TestInputChinese {
public static void main(String[] args) {
byte[] buf = new byte[1024];
int len = 0;
try {
len = System.in.read(buf);
}catch(IOException e) {
e.printStackTrace();
}
change(buf, len);
}
public static void change(byte[] b, int len) {
for( int i=0; i<len; i++ ) {
if(b[i] == '\r' || b[i] == '\n' ) {
continue;
}
if((b[i] & 0x80) == 0 ) {
System.out.write('[');
System.out.write(b[i]);
System.out.write(']');
} else {
System.out.write('[');
System.out.write(b[i++]);
System.out.write(b[i]);
System.out.write(']');
}
}
System.out.flush();
}
}

2.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-17 13:51

1. 由内存中一切皆二进制引出字符编码的讲解
大陆写的“中”到台湾显示不正常的原理分析,翻译软件的翻译原理,GBK-->“中”-->BIG5。讲解UTF-8编码和unicode编码,ASCII与Unicode码的转换规则,演示记事本显示字符时的趣味问题,分析乱码原因,GB2312码中也包含英文字符,如何识别GB2312码中的英文与汉字。最后讲了GB18030,如何支持?
2. 讲解了xml文档的编码问题。
讲解<?xml version="1.0"?>文档声明时,强调了version的重要性,例如,qq通讯协议的操作码刚开始是一个字节,后来随着新需求不断被发掘出来,发现需要用两个操作码了,要想平滑过渡,就非常需要这个版本了,新的软件就可以识别老和新通讯协议了。
沈继龙:以为指定了encoding="GBK",那文件就用GBK保存了,这正好理解反了。我是张,我戴顶帽子说明我是张,以便解析软件知道我是谁,如果我戴顶李的帽子,解析软件就认为我是李,显然就出了问题。
3. 接着讲解了CDATA区的作用
<country>
  <![CDATA[
  if(x<y)
  {
  }
  ]]>
</country>
要小心的是XML文档是通过一个程序生成出来的,如下所示的一个jsp程序,对于用变量生成的信息,要特别注意加上CDATA区。
<%@page pageEncoding="GBK"%>
<%@page contentType="text/xml;charset=UTF-8"%>
<?xml version="1.0" encoding="UTF-8"?>
<country>
    <name>中国</name>
    <info><![CDATA[${param.info}]]></info>
</country>
这个JSP文件涉及了两个编码:源文件是用什么码写的,程序执行后以什么码输出结果。
为了加深理解处理软件必须文件中的字符编码的情况,又演示了javac编译utf-8源文件的问题。
4. <%@page contentType="text/html;charset=GBK"%>//修改contentType="audio/x-mp3"说明头的作用
5.最后做了一个识别中英文字符的JAVA程序
  class Ce
{
  public static void main(String args[]) throws Exception
  {
    byte[] buf = new byte[1024];
    int len = System.in.read(buf);
    for(int i=0;i<len;i++)
    {
  /*使用&运算符,让buf[i]与8的二进制码进行与运算,如果最高位为0,则buf[i]为英文,否则为中文*/
if((buf[i]& 0x80) == 0)
      {
        if(buf[i]=='\r' || buf[i]=='\n')
          continue;
        System.out.write('(');
        System.out.write(buf[i]);
        System.out.write(')');
      }
      else
      {
        System.out.write('(');
        System.out.write(buf[i]);
        System.out.write(buf[++i]);
        System.out.write(')');
      }
      System.out.flush();
    }
  }
}

3.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-18 14:07

1. XML文档声明
在一个xml文档中必须包含一个文档声明,该声明必须位于文档的第一行,这个声明表示该文档是一个xml文档,以及遵循的是哪个xml版本的规范。
<?xml version="1.0" ?>
在< 和 ? 和 xml 之间、? 和 > 之间不能有空格,在第二个?前可有没有,也可以有一个或多个空格。
XML目前只有一个版本,就是1.0
<?xml version="1.0" encoding="GBK" ?>
encoding属性是用来指明文档的字符编码方式。
默认编码方式是两种unicode编码(UTF-8,UTF-16),如果文档中的字符是以UTF-8或UTF-16作为编码,则可以不用设置这个属性
2. XML标记的规范
标记名称中可以包含字母数字以及其他一些可见字符,还必须遵守一些规律:
区分大小写;
不能以数字或下划线开头;
不能以字母组合xml,XML,Xml等开头;
不能包含空格;
名称中间不能包含(:)冒号;
还有一些建议:
不要使用;
不要用减号(-),应该以下划线代替;
名称空间中可以使用非英文字符;
属性值必须用单引号或双引号引起来。
注释:<!-- -->
注意:注释也不能出现在声明语句的前面,注释不能嵌套使用。
注释中不能出现连续的2个减号,例如:
<!---------------------------------->这是不行的
<!-- ============================ -->这样可以
CDATA区
CDATA区是指不想被解析程序解析的一片原始数据区
格式:<![CDATA[ 数据
]]>
与CDATA区类似的一个小技巧:
<%@page pageEncoding="GBK"%>
<form>
<input type="hidden" name="email" value="${param.email}"/>
请输入用户名:<input type="text" name="name" />
</form>
如果给隐藏字段传递的参数是“zxx" a="b”,那么也会出问题,这时候就应该用CDATA区,对于程序生成值时,一定要考虑值的特殊情况。
4. JSP文件涉及了两个编码
<%@page pageEncoding="GBK"%>
源文件是用什么码写的,这里是GBK
<%@page contentType="text/xml;charset=UTF-8"%>
程序执行后以什么码输出结果,这里是UTF-8
java程序中的字节码都是Unicode码,当用javac编译原文件时就涉及到一个编码转换的过程,javac编译时可以指定编码:
javac -encoding UTF-8 Test.java
告诉javac,源文件是UTF-8编码,如果不写-encoding参数,则用操作系统默认的编码。
5. 十进制转十六进制编码转换程序
public class CodeTest
{
public static void main(String args[])
{
char c[] = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
byte b = (byte)Integer.parseInt(args[0]);
//b在位移时会先自动转换成int后再位移,这是取出高四位
System.out.print(c[(b>>4) & 0x0f]);
System.out.println(c[b & 0x0f]);//取出低4位
}
}
比如输入的是150
b=二进制的 10010110
移位时自动转换为int型 11111111 11111111 11111111 10010110
位移四位取高位 11111111 11111111 11111111 11111001
与0x0f 00001111
就得到高4位 1001
6. ContentType头
告诉浏览器文件为什么格式,例如:
text/html 为网页格式的文件
audio/x-mp3 为音频浏览器会自动打开音频播放器等等。。。
7. 区分文本中的中英文字符程序
public class EnCnTest
{
public static void main(String args[])
{
byte buf[] = args[0].getBytes();
boolean halfChinese = false;
for(int i=0;i<buf.length;i++)
{
if(halfChinese)
{
byte ch[] = {buf[i-1],buf[i]};
System.out.println("索引"+(i-1)+"位置为中文("+new String(ch)+")");
halfChinese = false;
continue;
}
if((buf[i] & 0x80) == 0)
{
System.out.println("索引"+i+"位置是英文("+(char)buf[i]+")");
}
else
{
halfChinese = true;
}
}
}
}

4.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-19 13:33

1. 字符编码的讲解
SCII与Unicode码的转换规则,演示记事本显示字符时的趣味问题,分析乱码原因,GB2312码中也包含英文字符,如何识别GB2312码中的英文与汉字。最后课结束时讲了GB18030。
2. xml文档的作用举例
<world>                                 }
<country>
</country>
<country>
  <name>中国</name>
  <chairman></chairman>
  <provinces>
    <province>
      <name>湖北</name>
      <chairman></chairman>
      <cities>
        <city>
      </cities>
    </province>
    <province>
      <name>湖南</name>
    </province>
    <province>
      <name>北京</name>
    </province>
  </provinces>
</country>
</world>
分析该内部原理:
World类{
//这里引出了对泛型的讲解                      ArraList<Country> countrys = new ArrayList<Country>;
  //为什么world元素下面要加countries元素                  countrys.add(new Country())
}
3. 编码转换程序
    char [] codes = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
    byte b = (byte)Integer.parseInt(args[0]);
    System.out.print(codes[((b>>4) & 0x0f)]);
    System.out.println(codes[(b & 0x0f)]);  
得到字符的big5码
<%@page pageEncoding="GBK"%>
<%@page contentType="text/html;charset=GBK"%>//修改contentType="audio/x-mp3"说明头的作用
<%
  String china="中一二";
  for(int i=0;i<china.length();i++)
  {
    out.println(Integer.toHexString((int)china.charAtLight Bulb));
  }
  System.out.println();
  byte[] bufGBK = china.getBytes("GBK");
  for(int i=0;i<bufGBK.length;i++)
  {
    out.println(Integer.toHexString(bufGBK [i]));
  }
  byte[] buf = china.getBytes("Big5");
  for(int i=0;i<buf.length;i++)
  {
    out.println(Integer.toHexString(buf[i]));
  }
  byte [] buf ={0xa4, 0xa4,0xa4,0x40,0xa4,0x47}
%>
输出big5码给浏览器:
<%
  byte [] buf ={(byte)0xa4, (byte)0xa4,(byte)0xa4,(byte)0x40,(byte)0xa4,(byte)0x47};
  response.getOutputStream().write(buf);
%>

5.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-21 14:53

1. 换皮肤问题
换肤问题,“内容与表现相分离”。一套内容,多套表现。xml文档提供内容,该怎么样显示,由css或xsl定义。以后尽量采用 DIV + CSS 模式。
一个简单的换皮肤例子:
<HTML>
  <HEAD>
    <META HTTP-EQUIT="Content-Type" content="text/html,charset=GBK" />
    <LINK rel="stylesheet" href="red.css" type="text/css" id="skin" />
    <title>换肤</title>
    <script>
      function chickSkin(name) {
        document.getElementById("skin").href=name;
        return false;
      }
    </script>
  </HEAD>
  <body>
    <span class="info">aaaaaa</span><br>
    <span class="info">bbbbbb</span><br>
    <span class="info">cccccc</span><br>
    <a href="#" onclick="return chickSkin('red.css')">红色</a>
    <a href="#" onclick="return chickSkin('green.css')">绿色</a>
  </body>
</HTML>
Css 代码如下:
red.css
.info {
  color:red;
  txt-decoration="none";
}
green.css
.info {
  color:green;
}
CSS中可以用 txt-decoration="none";去掉超连接的下划线。
小知识:
更改浏览器打开时的编码为GBK可以在<head></head>标签对内加入:<meta http-equiv="Content-Type" content="text/html;charset=GBK">
2. 浏览器与web服务器互交的过程
讲述了浏览器与web服务器互交的过程,分析程序:
import java.net.*;
import java.io.*;
public class HttpServer
{
  public static void main(String [] args) throws Exception
  {
    ServerSocket serverSocket = new ServerSocket(Integer.parseInt(args[0]));
    while(true)
    {
      Socket socket = serverSocket.accept();
      new Thread(new Server(socket)).start();
    }
  }  
}  
class Server implements Runnable
{
      Socket s = null;
      public Server(Socket s)
      {
        this.s = s;
      }
      public void run()
      {
        try
        {
          InputStream ips = s.getInputStream();
          BufferedReader br = new BufferedReader(new InputStreamReader(ips));
          String line = br.readLine();
          //GET /a.html HTTP/1.1
          String firstLine = line;
          while(/*(line == null) || */!"".equals(line))
          {
            System.out.println(line);
            line = br.readLine();
          }
          String parts [] = firstLine.split(" +");
          /*StringTokenizer st = new StringTokenizer(firstLine);
          while(st.hasMoreToken())
          {
            st.nextToken();
          }*/
          System.out.println(parts[1]);
          File f = new File("d:\\webcontent",parts[1].substring(1));
          FileInputStream fis = new FileInputStreamRose;
          OutputStream ops = s.getOutputStream();
          copyStream(fis,ops);
          br.close();
          ops.close();
          fis.close();
          s.close();
        }catch(Exception e){e.printStackTrace();}
      }
      void copyStream(InputStream fis,OutputStream ops) throws Exception
      {
          byte [] buf = new byte[1024];
          int len = 0;
          while((len=fis.read(buf)) != -1)
          {
            ops.write(buf,0,len);
          }
      }
}

6.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-22 15:46

小知识点:
CSS中可以用 txt-decoration="none";去掉超连接的下划线。
更改浏览器打开时的编码为GBK可以在<head></head>标签对内加入:
模拟请求头<meta http-equiv="Content-Type" content="text/html;charset=GBK">
2. DTD实体定义
<!ENTITY copyright SYSTEM http://www.it315.org.copyright.xml >
有SYSTEM关键子,那就表示别名对应的是xml文件的内容,否则,表示别名对应的是这个串本身。SYSTEM对应的是PUBLIC  一个表示系统,一个表示公共

7.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-23 13:42

1. 又遇乱码问题
在分析conf\server.xml时,如果在里面添加中文注释,那么startup.bat启动服务器则会出现错误。是因为编码问题,如果文件中出现中文,则文件读取错误,因为xml默认是以unicode编码存的。添加声明<?xml version="1.0" enconding="GB2312"?>或文件另存为编码为UTF-8则启动正常。
2. 怎样在telnet命令行窗口中显示本地回显
用ctrl+”]”然后按回车,再输入命令,telnet就可以本地回显。
3. 讲解Tomcat中的server.xml
(1)在分析conf\server.xml时,如果在里面添加中文注释,那么startup.bat启动服务器则会出现错误.是因为编码问题,如果文件中出现中文,则文件读取错误,因为xml默认是以unicode编码存的.添加声明<?xml version="1.0" encondin="GB2312"?>或文件另存为编码为UTF-8则启动正常。
(2)server.xml是给java执行的,所以在添盘符路径时可以不用\\来表示\,而java程序是给javac看的,编译器需要用\\来转意表示\,否则编译器会报错。
<Host></Host>之间添加<Context path="/abc" docBase="e:abc\"/> path代表浏览器中的目录,docBase代表path的设置中对应本地磁盘的目录。
(3)当用startup.bat启动tomcat时,如果server.xml配置有错误,那么startup.bat将闪一下就消失了,如果想让命令窗口停住,好方便查看错误信息,则用如下方法修改:修改catalina.bat,找到里面的:
:doStart
shift
if not "%OS%" == "Windows_NT" goto noTitle
set _EXECJAVA=start %_RUNJAVA%
goto gotTitle
:noTitle
set _EXECJAVA=start %_RUNJAVA%
:gotTitle
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy
goto execCmd
将上面set _EXECJAVA=start %_RUNJAVA% 中的start去掉,就可以让命令行出错后不消失。set _EXECJAVA=start %_RUNJAVA% 的意识是重新启动一个命令行窗口。去掉start后,则不会再重新启动窗口,就达到了使命令行停住的效果。要在命令行中启动startup.bat才能看到效果。
4. 配置虚拟子目录的三种方法
1.使用server.xml文件中的<context>元素。
2.在某个特定的目录中的xml文件中包含<Context>元素
例如:Tomcat5.x中主目录/conf/cat/localhost/manager.xml中的<Context>元素
3.<Host>元素的appBase属性所设置的应用程序基准目录中含有WEB-INF/web.xml文件的子目录会自动被映射成虚拟子目录。
4.<Host>元素的appBase属性所设置的应用程序基准目录中的war文件,这个war文件的名称也会自动被映射成虚拟子目录。
5. 其它知识点
将一个WAR的压缩包放到webapps目录下时,服务器会自动解压这个压缩文件。
Web.xml文件中
<welcome-file-list>
<welcome-file>a.html</welcome-file>
</welcome-file-list>
<welcome-file>内放如想要直接显示的页面(比如说欢迎页面),如果设置了该属性则站点下默认的网页就是a.html。

8.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-24 13:37

1. 首先让大家解压安装tomcat,然后介绍和演示批处理文件的作用,接着执行bin目录下的startup.bat,结果出错,根据错误信息,我们知道要配置JAVA_HOME,可以在批处理文件中配置。
2测试Tomcat通过后,要求大家修改服务器的端口号为80,并加上注释,大家加完注释后,服务器就启动不了了。解决办法:加xml声明,或将文件保存为UTF-8。
3. 通过telnet localhost 8005关闭服务器的方式来演示如何打开telnet的本地回显***能。
4. 学员启动一个tomcat实例后,再启动tomcat,启动不了,找不出错误来,正好借用这个来说明如何修改catalina.bat,让错误可以停留下来,看错误信息。在讲解过程中演示了使用ActivePort软件看端口号。
5. 介绍Tomcat的体系结构设计原理,系统***能是通过xml配置出来的,大家要理解这种思想,接着讲解并要求大家使用server.xml文件中的<Context>元素配置好一个虚拟目录,分析了配置文件中的’\’不用写成’\\’的原理。
server.xml是给java执行的,所以在添盘符路径时可以不用\\来表示\,而java程序是给javac看的,编译器需要用’\\’来转意表示’\’,否则编译器会报错。
6. 讲解了war包的发布与如何做war包
jar -cvf webcontent.war webcontent/abc.html xyz/def.xml很好地说明jar命令要在结果中保留目录信息
7. 分析了有时候要设置CATALINA_HOME环境变量,有时候又可以不设置的情况
8. 设置WEB站点的根目录
配置conf/server.xml文件,在Host元素中添加Context,path属性值为空,将docBase的值指定为根目录的名字:
   <!-- 下面是将webapps目录中的目录指定成为根目录的方法. -->
   <!-- <Context path="" docBase="xx" reloadable="true" /> -->
9. 建立虚拟子目录的方法
  A: 配置conf/server.xml文件,在Host元素中添加Context:
<!--配置当前主机的虚拟目录,使用Context元素,它有两个属性:path和docBase;path代表虚拟目录的名称,docBase指定本地目录。
注意:斜杠的方向,docBase里指定目录时只要一个斜杠,因为这个文件是给
java.exe程序看的,所以指定目录是不能用双斜杠如下例:
   <!-- <Context path="/w2" docBase="D:\www" /> -->
B. 在webapps目录中新建一个子目录,并在这个子目录里再新建一个WEB-INF目录,注意WEB-INF需大写
  C. 在conf文件夹,找到当前引擎中的当前主机文件夹,
   在当前主机文件夹内新建一个xml文档,这个xml的文件名,就是该虚拟目录的名字
   例:conf/<Engine name>/<Host name>/xy.xml ,xy 即是这个虚拟目录的名字
   该xml文件内容例:<Context docBase="d:\www" /> ,不需写path属性
发现 : 使用此方法 , 在虚拟目录文件夹中 , 建立一个WEB-INF文件夹中.放置一个web.xml文件,即:可为此虚拟目录单独进行WEB配置。
10. 配置默认首页,conf/web.xml
   修改<welcome-file-list>元素中的<welcome-file>index.html</welcome-file> 。conf/web.xml中的welcom-file-list文件应用于主机内所有WEB程序。
如需对每个WEB程序单独配置默认首页,则应在要配置的WEB程序中新建一个web.xml,将此xml文件放入WEB-INF文件夹中
11. 讲解了SSL(安全套接字),公钥,私钥,认证证书
讲解配置支持SSL协议的Tomcat,先说配置原理(tomcat只要加一个连接器,但这个连接器还需要在外部为它提供一些参数,即证书),对称加密与非对称加密,数据完整性校验、 数字签名,再引出数字证书,再讲解keytool产生证书。SSL会话原理:先非对称加密传递对称加密所用的密码,然后双方用这个密码对称加密和解密数据。我们只给服务器安装证书即可,SSL会话过程中的加密处理是浏览器与服务器自动完成的。

9.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: yunshao110
Posted on: 2007-10-25 07:51

太棒了 呀

10.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: yunshao110
Posted on: 2007-10-25 07:54

太棒了 呀

11.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-25 14:21

呵呵!谢谢关注啊!!希望对你有帮助!

12.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-25 14:27

1. 重要网站
http://jakarta.apache.org
2. Tomcat服务器的配置文件(server.xml)
E:\tomcat6\conf\server.xml
(1)关闭tomcat元素
<Server port="8005" shutdown="SHUTDOWN">用于关闭tomcat服务器
(2)修改TOMCAT端口号
在服务器配置文件中的 <Connector port="8080" protocol="HTTP/1.1" maxThreads="150" connectionTimeout="20000" redirectPort="8443" /> 修改便可。
(3)要注意的问题
问题:如果在server.xml文件中加入中文,则服务器加载不起来了,
原因:是xml文件中没有设置编码
办法:第一行加入<?xml version="1.0" encoding="GB2312" ?>
当Tomcat启动出错的时候,一闪就过去了,说明在startup批处理文件中用dos的start命令启动了一个新窗口
在catalina.bat中找到下面这段代码:
========================================================
:doStart
shift
if not "%OS%" == "Windows_NT" goto noTitle
set _EXECJAVA=start "Tomcat" %_RUNJAVA%
goto gotTitle
:noTitle
set _EXECJAVA=start %_RUNJAVA%
=========================================================
将红色字符串删掉就可以看到错误
3. GlobalNamingResources元素
<GlobalNamingResources>
<!-- Editable user database that can also be used by
UserDatabaseRealm to authenticate users
-->
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
服务器端创建对象供给Servlet或JSP使用,例如数据库连接池对象
4. Service元素
<Service name="Catalina">
5. Engine元素
<Engine name="Catalina" defaultHost="localhost">
在一个服务器引擎上可以通过在这个元素里增加子元素<Host>来配置多个主机,
在<Host>元素中配置<Context>子元素可以增加多个站点(Web应用程序)
5. 配置一个站点(Web应用程序)
<Context path="/TestApp" docBase="e:\TestApp" />
参数path是用于浏览器访问的站点根目录
参数docBase是对应的硬盘上的物理目录
tomcat默认部署目录:tomcat/webapps/
6. 配置元素里的斜杠问题
在配置文件里的路径不用双斜杠
java源程序中的路径用双斜杠,是用于给编译器javac的,编译器会把双斜杠转换为单斜杠
而配置文件中的路径是给虚拟机java的,会直接读取单斜杠
7. 查看端口占用情况
netstat -na 但不知道端口被谁占用
可以用ActivePort.exe软件查看
netstat -na | findstr 3306
查找指定端口有没有被占用
8. 设置默认根目录
==========================================================
默认根目录,浏览器访问网站时,不用再写目录名
方法一: 在server.xml中加入
<Context path="" docBase="e:\TestApp" />
方法二: 把工程放入webapps下,并一定要起名为ROOT
==========================================================
方法三: conf\Catalina\localhost\*.xml

Catalina是对应的引擎,有多少个引擎,在这就有多少个目录
Localhost 对应的是站点,有多少个站点,就有多少个目录,这个目录中又有多个xml配置文件,每个配置文件都对应一个Web应用程序。
在xml文件中写入<Context docBase="e:\test">元素,虚拟目录名字属性(path)不用写,虚拟目录名就是这个xml的文件名。
方法三在tomcat5.5中操作成***,在6中不推荐使用,但是也可以根据server.xml配置文件中的引擎,站点,web应用程序结构手工写入目录文件结构
9. 将项目打成war包
打成包的项目放到webapps下面不用解压,tomcat会将项目自动解压展开
打包后会自动生成META-INF文件夹
进入要打包的文件夹:jar -cvf webcontent.war .(点代表当前目录)
或者不进入文件夹:jar -cvf webcontent.war -C webcontent .
-C 代表改变目录
10. conf/web.xml通用配置文件
为所有的web应用程序进行配置,通用配置文件
配置默认网页(欢迎页面)
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
如果没找到对应的网页则打印文件列表报错
11. 批处理实例
batch 批
@echo hehe 加@的作用是不会让echo命令显示出来
或者直接设置@echo off ,整个批处理文件就不会显示命令
变量要用双引号引起来 "%OS%"
12. 连接器
https协议支持加密,默认端口号为443
要支持https协议,需要加入连接器
在tomcat/conf/server.xml中存在一个元素:(默认被注释掉)
<Connector port="8443" protocol="HTTP/1.1" SSLEnabled="true"
maxThreads="150" scheme="https" secure="true"
clientAuth="false" sslProtocol="TLS" />
必须为这个连接器申请一个证书,这个证书由专门的机构颁发审核
产生一个证书用JAVA_HOME/bin/keytool命令 查帮助文档,再将这个加入到连接器<Connector>元素
13. 对称加密和非对称加密
对称加密: 加密密码和解秘密密码相同
非对称加密:加密密码和解密密码不同,共钥加密的数据可以被私钥解密,私钥加密的数据也能被公钥解密,发钥的必须是个权威机构(CA)
根据要传输的数据计算出一个16位的128bit的一个数值,只要内容被改动一点,这个值就会被改变(很大的改变)
数字签名,数字证书
15. SSL会话原理
将密码进行非对称加密,SSL会话过程中的加密处理是浏览器与服务器自动完成的

13.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-26 14:21

1. 分析server.xml时得出的知识点
(1)如果在server.xml里面添加中文注释,那么用startup.bat启动服务器则会出现错误。是因为编码问题,如果文件中出现中文,则文件读取错误,因为xml默认是以unicode编码存的,添加声明<?xml version="1.0" encondin="GB2312"?>或文件另存为编码为UTF-8则启动正常。
(2)server.xml是给java执行的,所以在添盘符路径时可以不用\\来表示\,而java程序是给javac看的,编译器需要用\\来转意表示\,否则编译器会报错.
2.解决用startup.bat启动tomcat时一闪而过的办法
当用startup.bat启动tomcat时,如果server.xml配置有错误,那么startup.bat将闪一下就消失了,如果想让命令窗口停住,好方便查看错误信息,则用如下方法修改:修改catalina.bat,找到里面的:
:doStart
shift
if not "%OS%" == "Windows_NT" goto noTitle
set _EXECJAVA=start %_RUNJAVA%
goto gotTitle
:noTitle
set _EXECJAVA=start %_RUNJAVA%
:gotTitle
if not ""%1"" == ""-security"" goto execCmd
shift
echo Using Security Manager
set SECURITY_POLICY_FILE=%CATALINA_BASE%\conf\catalina.policy
goto execCmd
将上面set _EXECJAVA=start %_RUNJAVA% 中的start去掉,就可以让命令行出错后不消失。set _EXECJAVA=start %_RUNJAVA% 的意识是重新启动一个命令行窗口。去掉start后,则不会再重新启动窗口,就达到了使命令行停住的效果。要在命令行中启动startup.bat才能看到效果。
3. 设置网站的默认网页
在要发布的网站的WEB-INF的目录下编写web.xml.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 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"
version="2.4">
<welcome-file-list>
<welcome-file>a.html</welcome-file>
</welcome-file-list>
</web-app>
<welcome-file>内放如想要直接显示的页面(比如说欢迎页面),则在打开网页时,只要输入文件夹的名字,就可以自动显示网页。

14.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-28 14:17

已经在传智播客上了近2个月了,对JAVA有了更深入的了解,在日后我会把我的心得陆续的献给大家!希望大家多多的支持我 啊

15.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-28 14:21

1. Servlet的注册和运行
在web.xml里面,添加
<servlet>
  <servlet-name>wzh</servlet-name>
  <servlet-class>MyFirst</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>wzh</servlet-name>
<url-pattern>/first/a.html</url-pattern>
</servlet-mapping>
<servlet-name>可以随便填写<servlet-class>要与classes文件夹内的.class内的文件同名.在写<url-pattern>的时候要注意目录结构.。里面的/first/a.html是接在当前目录(应用程序的根目录)下的。所以在地址栏中访问时,一定要加上放在webapps里那个目录的名字.如http://localhost:8080/xml/first/a.html
还可以在<servlet>中设置<load-on-startup>元素,该元素的作用是指在web应用启动的时候指定了servlet被加载的顺序,它的值必须是一个整数。如果它的值是一个负整数或是这个元素不存在,那么容器会在该servlet被调用的时候,加载这个servlet 。如果值是正整数或零,容器在配置的时候就加载并初始化这个servlet,容器必须保证值小的先被加载。如果值相等,容器可以自动选择先加载谁。
2. 类装载
如果要想让一个sevlet被多个程序装载,可以把这个servlet放在common里,把原来.class文件打成jar放在lib,原来的.class放在class目录下。因为程序起来后,会自动找上面的类装载器,如果找到,那么就可以使用。所以放在common里就可以实现。程序就算自己有也会向上找,上面的找到了就不会返回来,所以这时如果用程序获得类装载器的名字,那得到的是上面的类装载器的名字。(这和sun公司在servlet规范中的建议是不一样的,Sun建议,如果下面的可以找到servlet则不用再向上找)
3. 模版方法设计模式
下面是一个模板方法设计模式的伪代码
Class abstract BaseServlet
{
service() throws IOException,ServletException
{
  try
  {
    doService()
  }
  catch(SqlException e)
  {
    throw new IOExceptionEnvelope;
  }
}
  public abstract void doSevice();
}
YourServlet extends BaseServlet
{
  public doService()
  {
    ....
  }
}
小知识:
response.getWriter().println();输出流默认是ISO8859-1,如果想输出中文,则必须要显示调用response.setCharacterEncoding("gb2312");

16.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-29 14:29

1. tomcat类加载器
.class文件中并不是字节码,是类装载器在加载到内存中时将.class文件中的内容转换为字节码。
Class clazz = Class.forName("Student");
//创建出一份Student类的字节码对象
Student st = clazz.new Instance();
//用这份字节码创建出这个对象
System.class和对象.getClass()这两个方法也可以获得一个类字节码,都是由ClassLoader来做的。
tomcat5.5有很多加载器:
server/lib或classes目录,为服务器启动时要加载类的类加载器,这个目录下有Servlet API定义的接口的实现类。
common目录是通用类加载器,应用程序和容器要使用的jar往往都放在该目录下,如果要多个应用程序都能装载某个Servlet,应把Servlet的字节码放到common目录中,但多个应用程序会创建多个此Servlet的对象。
各个web应用程序下的WEB-INF下的classes或lib目录下的是针对单个应用程序的类加载器。
2. JAVA类加载器
根加载器是BootStrap 是由C语言写的,他加载其他加载器
AppClassLoader加载classpath目录存放的类
jdk/jre/lib/ext java虚拟机的ExtClassLoader类加载器找这个目录
(1)得到类加载器
通过this.getClass().getClassLoader().getClass().getName()就可以得到一个类加载器。
(2)加载一个类的过程
getClass()方法获取一个类的字节码,这个类字节码也是CLASS类的一个对象,类加载器ClassLoader用于将类的字节码加载到内存中,然后再由这个类的字节码来创建这个类的实例。getClassLoader用于返回加载这个类的类加载器。

17.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-10-30 13:25

1. 学习了HTTP信息头,知道了很多文件的类型是如何被服务器识别,并做出相应的反应的。
HTTP消息头
①  通用信息头
即能用于请求消息中,也能用于响应信息中,但与被传输的实体内容没有关系的信息头,如Data,Pragma
主要: Cache-Control , Connection , Data , Pragma , Trailer , Transfer-Encoding , Upgrade
②  请求头
用于在请求消息中向服务器传递附加信息,主要包括客户机可以接受的数据类型,压缩方法,语言,以及客户计算机上保留的Cookie信息和发出该请求的超链接源地址等.
主要: Accept , Accept-Encoding , Accept-Language , Host ,
③  响应头
用于在响应消息中向客户端传递附加信息,包括服务程序的名称,要求客户端进行认证的方式,请求的资源已移动到新地址等.
主要: Location , Server , WWW-Authenticate(认证头)
④ 实体头
用做实体内容的元信息,描述了实体内容的属性,包括实体信息的类型,长度,压缩方法,最后一次修改的时间和数据的有效期等.
主要: Content-Encoding , Content-Language , Content-Length , Content-Location , Content-Type
2.Content-Type的作用
服务器告诉浏览器它发送的数据属于什么文件类型,文件类型的定义在web.xml文件中的MIME标签。
并借助text/html和text/plain的对比实验加深印象,前者会让浏览器把接收到的实体内容以HTML格式解析,后者会让浏览器以普通文本解析.
要实现文件下载,我们只需要设置两个特殊的相应头,它们是什么头?
----Content-Type:application/octet-stream
----Content-Disposition:attachment;filename=aaa.zip
3.Content-Disposition 的作用
当Content-Type 的类型为要下载的类型时 , 这个信息头会告诉浏览器这个文件的名字和类型。
在讲解这个内容时,张老师同时讲出了解决中文文件名乱码的解决方法,能用的是使用getBytes() , 实际上应使用email的附件名编码方法对文件名进行编码,但IE支持这种作法(其它浏览器支持) , 使用javax.mail.internet.*包的MimeUtility.encodeWord("中文.txt")的方法进行编码。
带中文名称的附件文件名到底该如何编写,参看邮件中的中文附件名的形式。
用MimeUtility.decodeText编码中文文件名后,IE浏览器显示不正常,而FireFox中没有问题。
解决中文文件名乱码的几种方式的内部原理:
  //response.setHeader("Content-Type","application/octet-stream");
  //response.setHeader("Content-Disposition","attachment;filename=\"=?gb2312?B?SmF2YcXg0bUudHh0?=\"");
  //response.setHeader("Content-Disposition","attachment;filename="+ MimeUtility.encodeWord("中文.txt"));
    response.setHeader("Content-Disposition",
    new String("attachment;filename=中文.txt".getBytes("GB2312"),"iso8859-1")  
  Wink;
setContentType("text/html;charset=gbk")只对response.getWriter().println输出的实体内容起作用,不对response.setHeader方法输出的内容起作用,response.setHeader方法总是按iso8859-1输出。
4. 由一个具有多个图的网页的访问过程讲解了http 1.0的缺点,讲解了Http 1.1的优点。
  HTTP1.1 支持持久连接
5. tomcat5.5首页已经使用了xhtml,特别如下一段内容:
<style type="text/css">
/*<![CDATA[*/
body {
   }
/*]]>*/
</style>
首先由xml解析器解析出每个元素的信息,然后由下游程序对每个元素进行处理。重点分析了其中的/*<![CDATA[*/的问题。
6. POST请求方式:
POST /servlets-examples/servlet/RequestParamExample HTTP/1.1
Host:
Content-Type: application/x-www-form-urlencoded
Content-Length: 28
firstname=zxx&lastname=abc
7. 怎么把MimeUtility所属的jar文件安装到当前Web应用程序中
  将JAR文件放在当前WEB应用程序的WEB-INF\lib目录下
8. 下面的代码说明jsp翻译成class时的编码问题。
<%=
  "a中文".length()
%>
为什么上面的输出值为5?改成下面的则输出3
<%@ page pageEncoding="gbk"%>
<%=
  "a中文".length()
%>
---------归根到底是编码的问题 , 上面的代码,因为没有添加该文件的编码说明 , WEB应用程序在将jsp翻译成class文件时 , 把该字符串的内容默认当成了UTF-8翻译,因为一个汉字在UTF-8中占两个字节,长度就变成了5 , 而下面的一个因为加了编码说明 , Tomcat 就把一个汉字当成一个字符来计算,得到结果为3。

18.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: wwww6662003
Posted on: 2007-11-01 07:47

很不错,支持一下

19.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-04 13:53

呵呵!谢谢大家支持我!!这俩天跟北京的同学玩了。。。昨天去的故宫!(呵,因为旺季过去了,现在才40元!)玩的很开心~~今天放假!上来看看大家!!

20.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-04 13:56

1. 浏览器会在web.xml中查找<mime-mapping>中<extension>中定义的要浏览的扩展名,再根据<mime-type>中指定的类型打开。
<mime-mapping>
<extension>abs</extension>
<mime-type>audio/x-mpeg</mime-type>
</mime-mapping>
2. 用JSP做了几个例子,说明请求头、响应头的作用
(1)Authorization头的例子
Authorization的作用是当客户端访问受口令保护时,服务器端会发送401状态码和WWW-Authenticate响应头,要求客户机使用Authorization来应答。
<%@ page pageEncoding="GBK" contentType="text/html;charset=utf-8" import="java.util.*,java.text.*" %>
<%=DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.CHINA).format(new Date())
%>
<%
  response.setStatus(401);
  response.setHeader("WWW-Authenticate", "Basic realm=\"Tomcat Manager Application\"");
%>
(2)Content-Disposition扩展头的例子
加上Content-Type头就可以实现文件下载。
<%@ page pageEncoding="GBK" contentType="text/html;charset=utf-8" import="java.util.*,java.text.*" %>
<%=DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.CHINA).format(new Date())
%>
<%
  response.setHeader("Content-Type","video/x-msvideo");
  response.setHeader("Content-Disposition", "attachment;filename=aaa.doc");
%>
Content-Type中指定的类型是当点击保存后,文件的保存类型。
Content-Disposition中指定的类型是文件的扩展名,并且弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的,点保存后,文件以filename的值命名,保存类型以Content中设置的为准。
(4)下载的文件名为中文时乱码的解决办法
如果下载的文件名中有中文那么要怎么修改?
<%@ page pageEncoding="GBK" contentType="text/html;charset=utf-8" import="java.util.*,java.text.*" %>
<%=DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.CHINA).format(new Date())
%>
<%
  response.setHeader("Content-Type","application/x-cpio");
  //response.setHeader("Content-Disposition", "attchment;filename=\"=?gb2312?B?0MK9qCDOxLG+zsS1tS50eHQ=?=\"");
  response.setHeader("Content-Disposition", new String("attachment;filename=中文.txt".getBytes("gb2312"),"ISO8859-1"));
  //response.setHeader("Content-Disposition","attachment;filename="+ MimeUtility.encodeWord("中文.txt"));
%>
这个是比较流行的方法,但比较正统的是用outlook新建一个带有中文附件的邮件,然后看这个邮件的源代码,找到:
Content-Disposition: attachment;
filename="=?gb2312?B?0MK9qCDOxLG+zsS1tS50eHQ=?="
用这个filename原理上就可以显示中文名附件,但是现在IE并不支持,如果换成FIREFOX就可以正常显示。
filename后面的内容可以用javax.mail.internet*包中有方法可以实现:MimeUtility.encodeWord()
如filename="+ MimeUtility.encodeWord("中文.txt"));
(5)jsp翻译成class时的编码问题
<%=
  "a中文".length()
%>
为什么上面的输出值为5?改成下面的则输出3
<%@ page pageEncoding="gbk"%>
<%=
  "a中文".length()
%>
原因:
因为上面的代码没有添加该文件的编码说明 , WEB应用程序在将jsp翻译成class文件时 , 把该字符串的内容按默认的保存方式指定的编码ASCII码来算的,在UTF-8中,原ASCII字符占一个字节,汉字占两个字节,对应两个字符,长度就变成了5 , 而下面的是GBK编码, 一个汉字和一个英文都对应一个字符,得到结果就为3。
(6)小知识点
referer头是可以让服务器了解和追踪发出本次请求的起源的URL地址。request.getHeader("referer")
xml默认是utf-8编码,JSP默认是ISO8859-1编码。
ContentType中的charset=gbk对头中内容不起作用。它只对response.getwriter().println输出的实体内容起作用。

21.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-05 15:15

1. 由一个具有多个图的网页的访问过程讲解了http 1.0的缺点,讲解了Http 1.1的优点。
2. 要实现文件下载,我们只需要设置两个特殊的相应头,它们是什么头?如果文件名带中文,该如何解决?
两个头:Content-Disposition扩展头和Content-Type
文件是中文的解决办法:参看邮件中的中文附件名的形式。
解决中文文件名乱码的几种方式的内部原理:
  //response.setHeader("Content-Type","application/octet-stream");
  //response.setHeader("Content-Disposition","attachment;filename=\"=?gb2312?B?SmF2YcXg0bUudHh0?=\"");
  //response.setHeader("Content-Disposition","attachment;filename="+ MimeUtility.encodeWord("中文.txt"));
    response.setHeader("Content-Disposition",
    new String("attachment;filename=中文.txt".getBytes("GB2312"),"iso8859-1")  
  Wink;
3. jsp翻译成class时的编码问题
记事本中代码块1:
<%=
  "a中文".length()
%>
代码块2:
<%@ page pageEncoding="gbk"%>
<%=
  "a中文".length()
%>
为什么上面的输出值为5,改成下面的则输出3?
因为上面的代码没有添加该文件的编码说明 , WEB应用程序在将jsp翻译成class文件时 , 把该字符串的内容按默认的保存方式指定的编码ASCII码来算的,在UTF-8中,原ASCII字符占一个字节,汉字占两个字节,对应两个字符,长度就变成了5 , 而下面的是GBK编码, 一个汉字和一个英文都对应一个字符,得到结果就为3.

22.缓存问题 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-07 15:49

一、servlet的service()方法
回顾Servlet的生命周期,通过查看源代码了解init()及service()方法的设计思想;
问:
(1)我们在编写Servlet类时,为什么不覆盖它的service()方法,通常覆盖doGet()之类的方法?
如果用覆盖servlet的service()方法,那么servlet在处理表单提交时,就会去调用父类的service方法,父类的service方法会根据提交的方式做出判断,然后调用对应的doXX()方法。如果是覆盖doGet()之类的方法,servlet就会根据提交的方式直接调用相应的doXX()方法。
(2)如果要覆盖service()方法,通常会覆盖下列方法中的哪一个方法?
service(HttpServletRequest req, HttpServletResponse resp)
service(ServletRequest req, ServletResponse res)

二、浏览器缓存内幕及解决方案
在下面三种不同的情况下,浏览器的缓存情况不同:
1).Servlet没有覆盖getLastModified方法,响应消息中无LastModified头字段,在浏览器缓存的文档无“上次修改时间”.
2).有getLastModified方法,响应消息中有LastModified头字段,但返回时间晚于缓存文档“上次修改时间”
3).有getLastModified方法,响应消息中有LastModified头字段,但返回时间早于等于缓存文档“上次修改时间”
后退、前进、转到(手工输入后按回车) 通过超链接访问 刷新
1)不发请求,直接使用缓存 发出请求 发出请求
2)不发请求,直接使用缓存 不发请求 发出请求,返回200
3)不发请求,直接使用缓存 不发请求 发出请求,返回304
2、如何禁止Servlet的缓存?(张老师JavaWeb书第236页)
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
3、如何禁止JSP页面的缓存?
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");

<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">

4、如何禁止静态页面的缓存?(张老师JavaWeb书第238页)
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
静态页面被禁止后,刷新浏览器返回304
JSP页面被禁止后,刷新浏览器返回200
三、初始化参数
1、相对于单个Servlet:P178
在web.xml文件中配置
<servlet>
<servlet-name>ReadInitParam</servlet-name>
<servlet-class>servlet.ReadInitParam</servlet-class>
<init-param>
  <param-name>dbname</param-name>
  <param-value>mysql</param-value>
</init-param>
</servlet>
访问方法为:
getServletConfig().getInitParameter("keyname")
2、相对于整个Web应用程序:P201
在web.xml文件中配置
<context-param>
  <param-name>company</param-name>
  <param-value>itcast.cn</param-value>
</context-param>
访问方法为:
getServletContext().getInitParameter("keyname")

四、资源文件(.properties)的访问
1、使用Properties类来访问:
Properties prop = new Properties();

//方法一
//InputStream is = new FileInputStream("db.properties");
//db.properties要放在启动tomcat的bin目录中

//方法二
//InputStream is = new FileInputStream(this.getServletContext().getRealPath("/") + "WEB-INF/classes/config/db.properties");
//db.properties可以放在web工程的任意目录

//方法三
//InputStream is = this.getServletContext().getResourceAsStream("WEB-INF/classes/config/db.properties");
//db.properties可以放在web工程的任意目录,相对于工程的上下文路径

//方法四
//InputStream is = this.getClass().getClassLoader().getResourceAsStream("/config/db.properties");
InputStream is = ReadProp.class.getClassLoader().getResourceAsStream("/config/db.properties");
//db.properties只能放在类路径即classes目录中
prop.load(is);
is.close();
//读取key对应的value
prop.getProperty("keyname")

2、使用ResourceBundle类来访问:
//也只能放在类路径下
ResourceBundle rb = ResourceBundle.getBundle("config/db");
//读取key对应的value
rb.getString("keyname")

23.Re:JAVA学习日子分享--路径问题 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-07 15:53

一、迭代一个Properties类型对象的几种方法
第一种:
import java.io.*;
import java.util.Enumeration;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ReadProp extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
  InputStream is = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
    Properties p = new Properties();
    p.load(is);
    is.close();
    Enumeration e = p.elements();
    while(e.hasMoreElements()) {
      String key = (String)e.nextElement();
      out.println(key + "<br>");
    }
    out.flush();
    out.close();
  }
}
第二种:
Enumeration e1 = p.propertyNames();
    while(e1.hasMoreElements()) {
      String key = (String)e1.nextElement();
      out.println(key + ":" + p.getProperty(key) + "<br>");
    }
第三种:
Enumeration e = p.keys();
    while(e.hasMoreElements()) {
      String key = (String)e.nextElement();
      out.println(key + ":" + p.getProperty(key) + "<br>");
    }
第四种:
Set set = p.keySet();
    Iterator it = set.iterator();
    while(it.hasNext()) {
      String key = (String)it.next();
      out.println(key + "=======" + p.getProperty(key) + "<br>");
    }

第五种
Set set = p.entrySet();
    Iterator it = set.iterator();
    while(it.hasNext()) {
      Map.Entry entry = (Entry) it.next();
      out.println(entry.getKey() + ":::::" + entry.getValue() + "<br>");
    }

二、一个显示所有访问者的IP及访问次数的Servlet
运用的知识点如下:
1、存储IP使用什么类型比较好?这个变量定义在哪里比较好?
2、复习了HashMap的迭代知识
代码如下:
用HashMap统计IP的访问次数
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class IpList extends HttpServlet {
  private Map map = new HashMap();
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setContentType("text/html");
    PrintWriter out = response.getWriter();
    String ip = request.getRemoteAddr();
    int time = 0;
    if(map.containsKey(ip)) {
      time = Integer.parseInt((String) map.get(ip));
    }
    time++;
    map.put(ip, Integer.valueOf(time).toString());
    Set ipset = map.keySet();
    Iterator iter = ipset.iterator();
    while(iter.hasNext()) {
      String ip1 = (String)iter.next();
      out.println(ip1 + ":" + map.get(ip1) + "<br>");
    }
    out.flush();
    out.close();
  }
}
三、servlet的线程安全问题
servlet是多线程的,所以有多个线程访问同一个对象时要考虑线程安全。
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletThread extends HttpServlet {
  private int count = 0;
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    synchronized (this) {
      count++;
      try {
        Thread.sleep(500);
      } catch (Exception e) {
        // TODO: handle exception
      }
      System.out.println(count + "访问" + Thread.currentThread());
    }
  }
}
http://www.itcast.cn


24.JSP乱码和out内置对象 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-08 09:33

一、深入out对象(张老师(深入JAVA web开发内幕)书P241)
1、getOutputStream
返回ServletOutputStream类型的out对象,属于字节输出流
2、getWriter
返回PrintWriter类型的对象,属于字符输出流
切记:同一个servlet程序向客户端输出内容时,只能选其一使用,不可同时都用。
两种头字段
Content-Length:n   向客户端输出前知道内容的大小
Transfer-Encoding:chunked  以下两种情况会出现:
A、输出的内容刚好装满缓冲区
B、手工执行过刷新(flush)操作
3. 案例
案例1:实现动态文件下载
Response.setContentType("application/x-msdownload");
Response.addHeader("Content-Disposition", "attachment;filename=xx.ext");
使用两种类型的out对象都可以实现文本类型的文件下载;
但其它二进制文件只能使用ServletOutputStream类型的out对象来输出文件内容。

案例2:输出图片
Response.setContentType("image/jpeg"); //显示图片
要实现图片下载,头字段的设置还是
Response.setContentType("application/x-msdownload");
Response.addHeader("Content-Disposition”, “attachment;filename=xx.jpg");

4、JSP内置的out对象
属于JspWriter类型的对象
(1)弄清缓冲区的概念,它对out对象输出内容顺序的影响(和printwriter比较)
Printwriter先输出,out对象后输出
(2)弄清回车换行对jsp执行的影响
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
   request.getRequestDispatcher("input.html").forward(request, response);
/*转发到静态资源会出错,因为先执行这句代码后,系统默认用outputstream输出静态页,而最后jsp的out对象最后输出换行和回车时,又要调用writer,所以会出错。
*/
   response.sendRedirect("/Test/input.html"); //不会出错
%>
下面是servlet里面的代码,不会出错
PrintWriter out = response.getWriter();
out.print("wrong!");
request.getRequestDispatcher("input.html").forward(request,response);
原因在于defaultservlet内部输出的时候会先判断是否调用过response.getWriter(),
如果已经调用过,就直接用PrintWriter来输出

二、中文输出问题
设置页面发送的编码要在定义的输出流前面
1、Servlet的中文输出问题:
response.setLocale(new java.util.Locale("zh", "CN")); //在tomcat5下无效
response.setCharacterEncoding("gb2312");//设置PrintWriter的编码
response.setContentType("text/html;charset=utf-8");//可增加Content-Type头字段

2、HTML静态页面中文输出问题:
<meta http-equiv="content-type" contentType="text/html; charset=GB18030">
注意:charset=GB18030最好和文件的编码一致

3、下载文本文件输出中文问题:
response.setContentType("application/x-msdownload;charset=gb2312");
//方法一
response.addHeader("Content-Disposition",attachment;filename=x.txt");
//response.setCharacterEncoding("gb2312");
//方法二
PrintWriter out = response.getWriter();
out.print("中国人民");

4、传参时的中文问题:
(1) get方式提交
String name = request.getParameter("name");
name = new String(name.getBytes("iso8859-1"), "gb2312");
//对get和post方式都有效,并且get方式必须用此方法
配置server.xml文件的Connector元素
<Connector port="8080" maxHttpHeaderSize="8192"
maxThreads="150" minSpareThreads="25" maxSpareThreads="75"
enableLookups="false" redirectPort="8443" acceptCount="100"
connectionTimeout="20000" disableUploadTimeout="true" />
添加两个属性
useBodyEncodingForURI="true",可以按照post方式处理
或者URIEncoding="gb2312",可以直接request.getParameter("name")而不会有问题
但不建议大家使用,因为移植到另一个服务器这些参数可能并不提供了.

(2)post方式提交
request.setCharacterEncoding("gb2312");
//只对实体内容有效,也就是只对post方式提交有效
String name = request.getParameter("name");

5、jsp文件的中文输出问题:
<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>
注意这个参数很有作用,
1) 可以设置文件的编码
2) 可以设置输出内容的Content-Type
3) 修改以后文件的存储编码也跟着改变
http://www.itcast.cn

25.Re:JAVA学习日子分享--路径问题 [Re: fhdking] Copy to clipboard
Posted by: JJ_JJ
Posted on: 2007-11-09 01:23

学习java的日子怎么能少了 http://www.java2s.com
的帮忙!超级好用得好站!看了就知道啦!

26.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-09 17:57

呵呵!谢谢楼上的分享!让我们一起努力吧!!!
http://www.itcast.cn 这里也有好多资料可以供大家下载哟!

27.include和forward方法 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-12 10:21

一、include方法
正常
request.getRequestDispatcher("chinese.html").include(request, response);
正常
response.setContentType("text/html;charset=gb18030");
PrintWriter out = response.getWriter();
request.getRequestDispatcher("chinese.html").include(request, response);
出乱码
PrintWriter out = response.getWriter();
request.getRequestDispatcher("chinese.html").include(request, response);
因为使用了PrintWrite但没有设置编码格式,导致页面的编码方式与服务器响应的编码格式不一致。
抛出异常
response.setContentType("text/html;charset=gb18030");
request.getRequestDispatcher("chinese.html").include(request, response);
PrintWriter out = response.getWriter();
out.println("包含");
因为include方法使用的是getOutputStream方法,下面的语句又使用了getWriter()方法,而在一个servlet程序中只能有一个输出方法,所以抛异常.

二、forward方法
下面的代码导致异常发生
response.setContentType("text/html;charset=gb18030");
PrintWriter out = response.getWriter();
out.println("前");
out.flush(); //导致异常发生
request.getRequestDispatcher("chinese.html").forward(request, response);

Forward方法前后的输出都会被忽略,如下代码的"前"和"后"都不会被输出
response.setContentType("text/html;charset=gb18030");
PrintWriter out = response.getWriter();
out.println("前");
request.getRequestDispatcher("chinese.html").forward(request, response);
out.println("后");

Forward方法双方的响应头都会有效
response.addDateHeader("Expires", 0); //设置了Expires响应头
request.getRequestDispatcher("chinese.html").forward(request, response);
//设置了Content-Type响应头

如下代码没有问题
response.setContentType("text/html;charset=utf-8");
//response.setContentType("text/html;charset=gb18030");
PrintWriter out = response.getWriter();
request.getRequestDispatcher("chinese.html").forward(request, response);

中文显示有问题
//当前chinese.html的编码是gb18030
response.setContentType("text/html;charset=utf-8");
request.getRequestDispatcher("chinese.html").forward(request, response);

中文显示没有问题
//当前chinese.html的编码是utf-8
response.setContentType("text/html;charset=utf-8");
request.getRequestDispatcher("chinese.html").forward(request, response);

三、URL的编码问题(张老师java web开发内幕一书P361)
处理参数的servlet代码如下:
String name = request.getParameter("name");
name = new String(name.getBytes("iso8859-1"), "GB2312");
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println(name);
1、浏览器的地址栏直接传中文参数:没有问题
http://localhost:8080/Test/ChineseReceive?name=中国

2、通过请求转发传参:出现问题
request.getRequestDispatcher("ChineseReceive?name=中国").forward(request, response);
解决方法:
request.getRequestDispatcher("ChineseReceive?name=" + java.net.URLEncoder.encode("中国", "gb2312")).forward(request, response);
  
3、通过请求重定向传参:出现问题
response.sendRedirect("ChineseReceive?name=中国");
解决方法:
response.sendRedirect("ChineseReceive?name=" + java.net.URLEncoder.encode("中国", "gb2312"));

四、各种传递参数的表单元素
<form name="f1" id="f1" action="" method="get">
text
name1:<input type="text" name="name" value="zhangsan"><br>
name2:<textarea rows="5" cols="80" name="info"></textarea><br>
checkbox
<input type="checkbox" name="favor" value="swim">swim<br>
<input type="checkbox" name="favor" value="read">read<br>
radio
<input type="radio" name="sex" value="male">male<br>
<input type="radio" name="sex" value="female">female<br>
hidden
<input type="hidden" name="hid" value="iii"><br>
select
<select name="source" multiple>
  <option>1</option>
  <option selected>2</option>
  <option selected>3</option>
</select><br>
button
<input type="button" name="btn" value="button1"><br>
<input type="submit" name="btn" value="submit1"><br>
<input type="submit" name="btn" value="submit2"><br>
<input type="reset">
</form>

28.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: 王勇
Posted on: 2007-11-17 18:05

好厉害啊,这么多啊.是不是觉得很累啊.

29.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-19 15:06

呵呵!累是累啊!可是来参加培训!不是学的越多越好么!要不以后出去找不到工作!那可就真累了!!

30.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-19 15:17

培训第十五天,Mysql第一天:
一 . 安装与配置MYSQL
二 . 常用mysql命令行命令
1 .mysql的启动与停止
启动MYSQL服务 net start mysql
停止MYSQL服务 net stop mysql
2 . netstat –na | findstr 3306 查看被监听的端口 , findstr用于查找后面的端口是否存在
3 . 在命令行中登陆MYSQL控制台 , 即使用 MYSQL COMMEND LINE TOOL
    语法格式 mysql –user=root –password=123456 db_name
       或 mysql –uroot –p123456 db_name
4 . 进入MYSQL命令行工具后 , 使用status; 或\s 查看运行环境信息
5 . 切换连接数据库的语法 : use new_dbname;

  
6 . 显示所有数据库 : show databases;

7 . 显示数据库中的所有表 : show tables;

8 . 显示某个表创建时的全部信息 : show create table table_name;

9 . 查看表的具体属性信息及表中各字段的描述
  Describe table_name; 缩写形式 : desc table_name;
三 。 MySql中的SQL语句
1 . 数据库创建 : Create database db_name;
数据库删除 : Drop database db_name; 删除时可先判断是否存在,写成 : drop database if exits db_name
  
2 . 建表 : 创建数据表的语法 : create table table_name (字段1 数据类型 , 字段2 数据类型);
   例 : create table mytable (id int , username char(20));
   删表 : drop table table_name; 例 : drop table mytable;

8 . 添加数据 : Insert into 表名 [(字段1 , 字段2 , ….)] values (值1 , 值2 , …..);
如果向表中的每个字段都插入一个值,那么前面 [ ] 括号内字段名可写也可不写
   例 : insert into mytable (id,username) values (1,’zhangsan’);

9 . 查询 : 查询所有数据 : select * from table_name;
查询指定字段的数据 : select 字段1 , 字段2 from table_name;
例 : select id,username from mytable where id=1 order by desc;多表查询语句------------参照第17条实例

10 . 更新指定数据 , 更新某一个字段的数据(注意,不是更新字段的名字)
Update table_name set 字段名=’新值’ [, 字段2 =’新值’ , …..][where id=id_num] [order by 字段 顺序]
例 : update mytable set username=’lisi’ where id=1;
Order语句是查询的顺序 , 如 : order by id desc(或asc) , 顺序有两种 : desc倒序(100—1,即从最新数据往后查询),asc(从1-100),Where和order语句也可用于查询select 与删除delete

11 . 删除表中的信息 :
    删除整个表中的信息 : delete from table_name;
  删除表中指定条件的语句 : delete from table_name where 条件语句 ; 条件语句如 : id=3;
  
12 . 创建数据库用户
一次可以创建多个数据库用户如:
CREATE USER username1 identified BY ‘password’ , username2 IDENTIFIED BY ‘password’….

13 . 用户的权限控制:grant
  库,表级的权限控制 : 将某个库中的某个表的控制权赋予某个用户
  Grant all ON db_name.table_name TO user_name [ indentified by ‘password’ ];

14 . 表结构的修改
(1)增加一个字段格式:
alter table table_name add column (字段名 字段类型); ----此方法带括号
(2)指定字段插入的位置:
alter table table_name add column 字段名 字段类型 after 某字段;
删除一个字段:
alter table table_name drop字段名;
(3)修改字段名称/类型
alter table table_name change 旧字段名 新字段名 新字段的类型;
(4)改表的名字
alter table table_name rename to new_table_name;
(5)一次性清空表中的所有数据
truncate table table_name; 此方法也会使表中的取号器(ID)从1开始

15 . 增加主键,外键,约束,索引。。。。(使用方法见17实例)
① 约束(主键Primary key、唯一性Unique、非空Not Null)
② 自动增张 auto_increment
③外键Foreign key-----与reference table_name(col_name列名)配合使用,建表时单独使用
④ 删除多个表中有关联的数据----设置foreign key 为set null ---具体设置参考帮助文档

16 . 查看数据库当前引擎
  SHOW CREATE TABLE table_name;
  修改数据库引擎
  ALTER TABLE table_name ENGINE=MyISAM | InnoDB;

17 . SQL语句运用实例:
--1 建users表
create table users (id int primary key auto_increment,nikename varchar(20) not null unique,password varchar(100) not null,address varchar(200), reg_date timestamp not null default CURRENT_TIMESTAMP);

--2 建articles表,在建表时设置外键
create table articles (id int primary key auto_increment,content longtext not null,userid int,constraint foreign key (userid) references users(id) on delete set null);

-----------------------------------------------------------------------
--2.1 建articles表,建表时不设置外键
  create table articles (id int primary key auto_increment,content longtext not null,userid int);
--2.2 给articles表设置外键
  alter table articles add constraint foreign key (userid) references users(id) on delete set null;
------------------------------------------------------------------------

--3. 向users表中插入数据,同时插入多条
insert into users (id,nikename,password,address) values (1,'lyh1','1234',null),(10,'lyh22','4321','湖北武汉'),(null,'lyh333','5678','北京海淀');

--4. 向article中插入三条数据
insert into articles (id,content,userid) values (2,'hahahahahaha',11),(null,'xixixixixix',10),(13,'aiaiaiaiaiaiaiaiaiaiaiaia',1),(14,'hohoahaoaoooooooooo',10);

--5. 进行多表查询,选择users表中ID=10的用户发布的所有留言及该用户的所有信息
select articles.id,articles.content,users.* from users,articles where users.id=10 and articles.userid=users.id order by articles.id desc;

--6. 查看数据库引擎类型
show create table users;

--7. 修改数据库引擎类型
alter table users engine=MyISAM; ---因为users表中ID被设置成外键,执行此句会出错

--8. 同表查询,已知一个条件的情况下.查询ID号大于用户lyh1的ID号的所有用户
select a.id,a.nikename,a.address from users a,users b where b.nikename='lyh1' and a.id>b.id;
------也可写成
select id,nikename,address from users where id>(select id from users where nikename='lyh1');

9. 显示年龄比领导还大的员工:
select a.name from users a,users b where a.managerid=b.id and a.age>b.age;

查询编号为2的发帖人: 先查articles表,得到发帖人的编号,再根据编号查users得到的用户名。
接着用关联查询.
select * from articles,users得到笛卡儿积,再加order by articles.id以便观察
  
使用select * from articles,users where articles.id=2 筛选出2号帖子与每个用户的组合记录

再使用select * from articles,users where articles.id=2 and articles.userid=users.id选出users.id等于2号帖的发帖人id的记录.
  
只取用户名:select user where user.id=(select userid from articles where article.id =2)

找出年龄比小王还大的人:假设小王是28岁,先想找出年龄大于28的人
select * from users where age>(select age from users where name='xiaowang');
*****要查询的记录需要参照表里面的其他记录:
select a.name from users a,users b where b.name='xiaowang' and a.age>b.age

表里的每个用户都想pk一下.select a.nickname,b.nickname from users a,users b where a.id>b.id ;

更保险的语句:select a.nickname,b.nickname from (select * from users order by id) a,(se
lect * from users order by id) b where a.id>b.id ;

再查询某个人发的所有帖子.
select b.* from articles a , articles b where a.id=2 and a.userid=b.userid

说明: 表之间存在着关系,ER概念的解释,用access中的示例数据库演示表之间的关系.只有innodb引擎才支持foreign key,mysql的任何引擎目前都不支持check约束。
四、字符集出现错误解决办法
出现的问题:
mysql> update users
-> set username='关羽'
-> where userid=2;
ERROR 1366 (HY000): Incorrect string value: '\xB9\xD8\xD3\xF0' for column 'usern
ame' at row 1
向表中插入中文字符时,出现错误。

mysql> select * from users;
+--------+----------+
| userid | username |
+--------+----------+
| 2 | ???? |
| 3 | ???? |
| 4 | ?í?ù |
+--------+----------+
3 rows in set (0.00 sec)
表中的中文字符位乱码。
解决办法:
使用命令:
mysql> status;
--------------
mysql Ver 14.12 Distrib 5.0.45, for Win32 (ia32)

Connection id: 8
Current database: test
Current user: root@localhost
SSL: Not in use
Using delimiter: ;
Server version: 5.0.45-community-nt MySQL Community Edition (GPL)
Protocol version: 10
Connection: localhost via TCP/IP
Server characterset: latin1
Db characterset: latin1
Client characterset: gbk
Conn. characterset: gbk
TCP port: 3306
Uptime: 7 hours 39 min 19 sec
Threads: 2 Questions: 174 Slow queries: 0 Opens: 57 Flush tables: 1 Open ta
bles: 1 Queries per second avg: 0.006
--------------
查看mysql发现Server characterset,Db characterset的字符集设成了latin1,所以出现中文乱码。

mysql> show tables;
+----------------+
| Tables_in_test |
+----------------+
| users |
+----------------+
1 row in set (0.00 sec)

更改表的字符集。
mysql> alter table users character set GBK;
Query OK, 3 rows affected (0.08 sec)
Records: 3 Duplicates: 0 Warnings: 0

查看表的结构:
mysql> show create users;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use near 'users
' at line 1
mysql> show create table users;
+-------+-----------------------------------------------------------------------
------------------------------------------------------------------------------+
| Table | Create Table
|
+-------+-----------------------------------------------------------------------
------------------------------------------------------------------------------+
| users | CREATE TABLE `users` (
`userid` int(11) default NULL,
`username` char(20) character set latin1 default NULL
) ENGINE=InnoDB DEFAULT CHARSET=gbk |
+-------+-----------------------------------------------------------------------
------------------------------------------------------------------------------+
1 row in set (0.00 sec)

mysql> desc users;
+----------+----------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+----------+------+-----+---------+-------+
| userid | int(11) | YES | | NULL | |
| username | char(20) | YES | | NULL | |
+----------+----------+------+-----+---------+-------+
2 rows in set (0.02 sec)

这时向表中插入中文然后有错误。
mysql> insert into users values(88,'中文');
ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column 'usern
ame' at row 1
mysql> insert into users values(88,'中文');
ERROR 1366 (HY000): Incorrect string value: '\xD6\xD0\xCE\xC4' for column 'usern
ame' at row 1

还要更改users表的username的字符集。
mysql> alter table users modify username char(20) character set gbk;
ERROR 1366 (HY000): Incorrect string value: '\xC0\xEE\xCB\xC4' for column 'usern
ame' at row 1
mysql> alter table users modify username char(20) character set gbk;
ERROR 1366 (HY000): Incorrect string value: '\xC0\xEE\xCB\xC4' for column 'usern
ame' at row 1

因为表中已经有数据,所以更改username字符集的操作没有成***
清空users表中的数据
mysql> truncate table users;
Query OK, 3 rows affected (0.01 sec)

从新更改user表中username的字符集
mysql> alter table users modify username char(20) character set gbk;
Query OK, 0 rows affected (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 0

这时再插入中文字符,插入成***。
mysql> insert into users values(88,'中文');
Query OK, 1 row affected (0.01 sec)

mysql> select * from users;
+--------+----------+
| userid | username |
+--------+----------+
| 88 | 中文 |
+--------+----------+
1 row in set (0.00 sec)
mysql>

北京传智播客http://www.itcast.cn

31.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-20 11:05

培训日记(利用session自动登录)

培训第十七天:
一、复习Cookie
二、复习关于Session的知识
1、Session究竟何时产生?
(1)Servlet:调用request.getSession(true)时产生
(2)JSP: 设置page指令,session="true"时产生

2、如何控制Session的产生?
最好在用户成***登陆以后才为这次会话产生Session对象
(1)Servlet,最好在检测用户登陆的那个Servlet里面才使用 request.getSession(true);其它的Servlet都只使用request.getSession(false)
(2)JSP,最好设置page指令,session=”false”
如果设置了session="false",如果在后面的程序中再出现session,一样会出错。
request.getSession(true) request.getSession()等价于 request.getSession(true)
request.getSession(false)
当请求消息中有包含SessionId的Cookie头字段时,两个方法都返回这个SessionId对应的session对象
当请求消息中没有包含SessionId的Cookie头字段时,或者不存在这个SessionId对应的session对象,则前一个方法创建一个session对象返回,后一个方法不创建session对象,直接返回null

三、网站自动登录
index.jsp ------->Longin --------> welcome.jsp
(1)客户端
Index.jsp
   判断请求信息中是否有cookie头字段,如果里面存有用户信息,则直接转向到welcome.jsp。代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="GB18030" session="false"%>
<jsp:directive.page import="utils.CookieUtil" />
<%
  String path = request.getContextPath();
  String basePath = request.getScheme() + "://"
      + request.getServerName() + ":" + request.getServerPort()
      + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <%  
      if (CookieUtil.getCookicValue(request, "user") != null) {
      HttpSession s = request.getSession();
      s.setAttribute("user", CookieUtil.getCookicValue(request,
      "user"));
      response.sendRedirect("welcome.jsp");
    }
  %>
  <body>
    <form name="form1" action="Login" method="POST">
      <table border="0">
        <tr>
          <td>
            用户名:
          </td>
          <td>
            <input type="text" name="name" id="name">
          </td>
        </tr>
        <tr>
          <td>
            密码:
          </td>
          <td>
            <input type="password" name="password" id="password">
          </td>
        </tr>
        <tr>
          <td colspan="2" align="center">
            <input type="checkbox" name="remember">
            记住我的信息
          </td>
        </tr>
        <tr>
          <td colspan="2" align="center">
            <input type="submit" value="登录">
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>

Welcome.jsp
从session对象中取出用户名,并打印欢迎词
<%@ page language="java" import="java.util.*" pageEncoding="GB18030" session="false"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'welcome.jsp' starting page</title>

  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  <meta http-equiv="description" content="This is my page">
</head>
<%
  HttpSession s = request.getSession(false);
  String name = (String)s.getAttribute("user");
%>
<body>
欢迎您<%=name %>
<a href="Logout">注销登录</a>
</body>
</html>


(2)服务器端
Login(登录的servlet)
该程序负责:
检查用户名和密码是否正确,如果正确的话,要产生一个session,并把用户信息存到session里面
如果用户选择要求记住登陆信息,则产生Set-Cookie头字段,把用户的信息保存到浏览器的cookie中去
然后转向到welcome.jsp
如果不正确的话,则转向到index.jsp,要求用户重新输入有关信息登录
程序代码如下:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Login extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setCharacterEncoding("GB18030");
  
    String name= request.getParameter("name");
    String password = request.getParameter("password");
    String checkbox = request.getParameter("remember");
    
    if("wzh".equals(name) && "123".equals(password)) {
      HttpSession session = request.getSession(true);
      
      session.setAttribute("user", name);
      if("on".equals(checkbox)) {
        Cookie cookie = new Cookie("user", name);
        cookie.setMaxAge(24*3600);
        response.addCookie(cookie);
      }
      response.sendRedirect("welcome.jsp");
    } else {
      response.sendRedirect("index.jsp");
    }
  }
}

logout (注销的servlet)
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Logout extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    HttpSession session = request.getSession();
    if(session != null) {
      session.removeAttribute("user");
      Cookie cookie = new Cookie("user", null);
      cookie.setMaxAge(0);
      response.addCookie(cookie);
    }
    response.setContentType("text/html;charset=GB18030");
    PrintWriter out = response.getWriter();
    out.print("用户已经安全推出<br>");
    out.print("<a href='index.jsp' >重新登录</a>");
  }
}

http://www.itcast.cn

32.培训日记(利用session自动登录) [Re: fhdking] Copy to clipboard
Posted by: fhdking
Posted on: 2007-11-21 11:05

http://www.itcast.cn
一、复习Cookie
二、复习关于Session的知识
1、Session究竟何时产生?
(1)Servlet:调用request.getSession(true)时产生
(2)JSP: 设置page指令,session="true"时产生

2、如何控制Session的产生?
最好在用户成***登陆以后才为这次会话产生Session对象
(1)Servlet,最好在检测用户登陆的那个Servlet里面才使用 request.getSession(true);其它的Servlet都只使用request.getSession(false)
(2)JSP,最好设置page指令,session=”false”
如果设置了session="false",如果在后面的程序中再出现session,一样会出错。
request.getSession(true) request.getSession()等价于 request.getSession(true)
request.getSession(false)
当请求消息中有包含SessionId的Cookie头字段时,两个方法都返回这个SessionId对应的session对象
当请求消息中没有包含SessionId的Cookie头字段时,或者不存在这个SessionId对应的session对象,则前一个方法创建一个session对象返回,后一个方法不创建session对象,直接返回null
三、网站自动登录
index.jsp ------->Longin --------> welcome.jsp
(1)客户端
Index.jsp
   判断请求信息中是否有cookie头字段,如果里面存有用户信息,则直接转向到welcome.jsp。代码如下:
<%@ page language="java" import="java.util.*" pageEncoding="GB18030" session="false"%>
<jsp:directive.page import="utils.CookieUtil" />
<%
  String path = request.getContextPath();
  String basePath = request.getScheme() + "://"
      + request.getServerName() + ":" + request.getServerPort()
      + path + "/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>My JSP 'index.jsp' starting page</title>
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
  </head>
  <%  
      if (CookieUtil.getCookicValue(request, "user") != null) {
      HttpSession s = request.getSession();
      s.setAttribute("user", CookieUtil.getCookicValue(request,
      "user"));
      response.sendRedirect("welcome.jsp");
    }
  %>
  <body>
    <form name="form1" action="Login" method="POST">
      <table border="0">
        <tr>
          <td>
            用户名:
          </td>
          <td>
            <input type="text" name="name" id="name">
          </td>
        </tr>
        <tr>
          <td>
            密码:
          </td>
          <td>
            <input type="password" name="password" id="password">
          </td>
        </tr>
        <tr>
          <td colspan="2" align="center">
            <input type="checkbox" name="remember">
            记住我的信息
          </td>
        </tr>
        <tr>
          <td colspan="2" align="center">
            <input type="submit" value="登录">
          </td>
        </tr>
      </table>
    </form>
  </body>
</html>
Welcome.jsp

从session对象中取出用户名,并打印欢迎词
<%@ page language="java" import="java.util.*" pageEncoding="GB18030" session="false"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'welcome.jsp' starting page</title>

  <meta http-equiv="pragma" content="no-cache">
  <meta http-equiv="cache-control" content="no-cache">
  <meta http-equiv="expires" content="0">
  <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
  <meta http-equiv="description" content="This is my page">
</head>
<%
  HttpSession s = request.getSession(false);
  String name = (String)s.getAttribute("user");
%>
<body>
欢迎您<%=name %>
<a href="Logout">注销登录</a>
</body>
</html>

(2)服务器端
Login(登录的servlet)
该程序负责:
检查用户名和密码是否正确,如果正确的话,要产生一个session,并把用户信息存到session里面
如果用户选择要求记住登陆信息,则产生Set-Cookie头字段,把用户的信息保存到浏览器的cookie中去
然后转向到welcome.jsp
如果不正确的话,则转向到index.jsp,要求用户重新输入有关信息登录
程序代码如下:
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Login extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    response.setCharacterEncoding("GB18030");
  
    String name= request.getParameter("name");
    String password = request.getParameter("password");
    String checkbox = request.getParameter("remember");
    
    if("wzh".equals(name) && "123".equals(password)) {
      HttpSession session = request.getSession(true);
      
      session.setAttribute("user", name);
      if("on".equals(checkbox)) {
        Cookie cookie = new Cookie("user", name);
        cookie.setMaxAge(24*3600);
        response.addCookie(cookie);
      }
      response.sendRedirect("welcome.jsp");
    } else {
      response.sendRedirect("index.jsp");
    }
  }
}

logout (注销的servlet)
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class Logout extends HttpServlet {
  public void doGet(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    doPost(request, response);
  }
  public void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {
    HttpSession session = request.getSession();
    if(session != null) {
      session.removeAttribute("user");
      Cookie cookie = new Cookie("user", null);
      cookie.setMaxAge(0);
      response.addCookie(cookie);
    }
    response.setContentType("text/html;charset=GB18030");
    PrintWriter out = response.getWriter();
    out.print("用户已经安全推出<br>");
    out.print("<a href='index.jsp' >重新登录</a>");
  }
}

四、利用Session防止表单重复提交

流程:
  input.jsp -------> Receive
  jsp <------ servlet

input.jsp
产生一个很随机的数,把它放到hidden表单域
把这个随机数存到session当中

Receive
取出hidden域里的数和session里的数比较
如果相同,则保存用户提交的数据,并且把session里存的数字去掉
如果不相同,就拒绝保存。

http://www.itcas.cn

33.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: ws5696611
Posted on: 2007-12-26 19:09

楼主发帖辛苦啦。我是个JAVA在学者,也考虑进个培训班,看看这些贴,觉得培训学到的东西还不少,应该说很值得。

34.Re:JAVA学习日子分享 [Re: fhdking] Copy to clipboard
Posted by: g007
Posted on: 2008-01-14 15:26

好多东西啊 还不错把


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923