发布新日志

  • sprintf的用法

    2007-08-30 16:49:21

    最近不知道sprintf的用法,特意查上,收藏,一起共享

    在将各种类型的数据构造成字符串时,sprintf 的强大功能很少会让你失望。由于sprintf 跟printf 在用法上几乎一样,只是打印的目的地不同而已,前者打印到字符串中,后者则直接在命令行上输出。这也导致sprintf 比printf 有用得多。

    sprintf 是个变参函数,定义如下:
    int sprintf( char *buffer, const char *format [, argument] ... );
    除了前两个参数类型固定外,后面可以接任意多个参数。而它的精华,显然就在第二个参数:
    格式化字符串上。


    printf 和sprintf 都使用格式化字符串来指定串的格式,在格式串内部使用一些以“%”开头的格式说明符(format specifications)来占据一个位置,在后边的变参列表中提供相应的变量,最终函数就会用相应位置的变量来替代那个说明符,产生一个调用者想要的字符串。

    格式化数字字符串
    sprintf 最常见的应用之一莫过于把整数打印到字符串中,所以,spritnf 在大多数场合可以替代
    itoa。

    如:
    //把整数123 打印成一个字符串保存在s 中。
    sprintf(s, "%d", 123); //产生"123"
    可以指定宽度,不足的左边补空格:
    sprintf(s, "%8d%8d", 123, 4567); //产生:" 123 4567"
    当然也可以左对齐:
    sprintf(s, "%-8d%8d", 123, 4567); //产生:"123 4567"
    也可以按照16 进制打印:
    sprintf(s, "%8x", 4567); //小写16 进制,宽度占8 个位置,右对齐
    sprintf(s, "%-8X", 4568); //大写16 进制,宽度占8 个位置,左对齐

    这样,一个整数的16 进制字符串就很容易得到,但我们在打印16 进制内容时,通常想要一种左边补0 的等宽格式,那该怎么做呢?很简单,在表示宽度的数字前面加个0 就可以了。
    sprintf(s, "%08X", 4567); //产生:"000011D7"
    上面以”%d”进行的10 进制打印同样也可以使用这种左边补0 的方式。


    这里要注意一个符号扩展的问题:比如,假如我们想打印短整数(short)-1 的内存16 进制表示形式,在Win32 平台上,一个short 型占2 个字节,所以我们自然希望用4 个16 进制数字来打印它:
    short si = -1;
    sprintf(s, "%04X", si);
    产生“FFFFFFFF”,怎么回事?因为spritnf 是个变参函数,除了前面两个参数之外,后面的参数都不是类型安全的,函数更没有办法仅仅通过一个“%X”就能得知当初函数调用前参数压栈时被压进来的到底是个4 字节的整数还是个2 字节的短整数,所以采取了统一4 字节的处理方式,导致参数压栈时做了符号扩展,扩展成了32 位的整数-1,打印时4 个位置不够了,就把32 位整数-1 的8 位16 进制都打印出来了。

    如果你想看si 的本来面目,那么就应该让编译器做0 扩展而不是符号扩展(扩展时二进制左边补0 而不是补符号位):
    sprintf(s, "%04X", (unsigned short)si);
    就可以了。或者:
    unsigned short si = -1;
    sprintf(s, "%04X", si);


    sprintf 和printf 还可以按8 进制打印整数字符串,使用”%o”。注意8 进制和16 进制都不会打
    印出负数,都是无符号的,实际上也就是变量的内部编码的直接的16 进制或8 进制表示。

    控制浮点数打印格式
    浮点数的打印和格式控制是sprintf 的又一大常用功能,浮点数使用格式符”%f”控制,默认保
    留小数点后6 位数字,比如:
    sprintf(s, "%f", 3.1415926); //产生"3.141593"
    但有时我们希望自己控制打印的宽度和小数位数,这时就应该使用:”%m.nf”格式,其中m 表
    示打印的宽度,n 表示小数点后的位数。比如:
    sprintf(s, "%10.3f", 3.1415626); //产生:" 3.142"
    sprintf(s, "%-10.3f", 3.1415626); //产生:"3.142 "
    sprintf(s, "%.3f", 3.1415626); //不指定总宽度,产生:"3.142"

    注意一个问题,你猜
    int i = 100;
    sprintf(s, "%.2f", i);
    会打出什么东东来?“100.00”?对吗?自己试试就知道了,同时也试试下面这个:
    sprintf(s, "%.2f", (double)i);
    第一个打出来的肯定不是正确结果,原因跟前面提到的一样,参数压栈时调用者并不知道跟i相对应的格式控制符是个”%f”。而函数执行时函数本身则并不知道当年被压入栈里的是个整数,于是可怜的保存整数i 的那4 个字节就被不由分说地强行作为浮点数格式来解释了,整个乱套了。不过,如果有人有兴趣使用手工编码一个浮点数,那么倒可以使用这种方法来检验一下你手工编排的结果是否正确。

    字符/Ascii 码对照
    我们知道,在C/C++语言中,char 也是一种普通的scalable 类型,除了字长之外,它与short,
    int,long 这些类型没有本质区别,只不过被大家习惯用来表示字符和字符串而已。(或许当年该把
    这个类型叫做“byte”,然后现在就可以根据实际情况,使用byte 或short 来把char 通过typedef 定义出来,这样更合适些)于是,使用”%d”或者”%x”打印一个字符,便能得出它的10 进制或16 进制的ASCII 码;反过来,使用”%c”打印一个整数,便可以看到它所对应的ASCII 字符。以下程序段把所有可见字符的ASCII 码对照表打印到屏幕上(这里采用printf,注意”#”与”%X”合用时自动为16 进制数增加”0X”前缀):
    for(int i = 32; i < 127; i++) {
    printf("[ %c ]: %3d 0x%#04X\n", i, i, i);
    }


    连接字符串
    sprintf 的格式控制串中既然可以插入各种东西,并最终把它们“连成一串”,自然也就能够连
    接字符串,从而在许多场合可以替代strcat,但sprintf 能够一次连接多个字符串(自然也可以同时
    在它们中间插入别的内容,总之非常灵活)。比如:
    char* who = "I";
    char* whom = "CSDN";
    sprintf(s, "%s love %s.", who, whom); //产生:"I love CSDN. "
    strcat 只能连接字符串(一段以’\0’结尾的字符数组或叫做字符缓冲,null-terminated-string),但有时我们有两段字符缓冲区,他们并不是以’\0’结尾。比如许多从第三方库函数中返回的字符数组,从硬件或者网络传输中读进来的字符流,它们未必每一段字符序列后面都有个相应的’\0’来结尾。如果直接连接,不管是sprintf 还是strcat 肯定会导致非法内存操作,而strncat 也至少要求第一个参数是个null-terminated-string,那该怎么办呢?我们自然会想起前面介绍打印整数和浮点数时可以指定宽度,字符串也一样的。比如:
    char a1[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G'};
    char a2[] = {'H', 'I', 'J', 'K', 'L', 'M', 'N'};
    如果:
    sprintf(s, "%s%s", a1, a2); //Don't do that!
    十有八九要出问题了。是否可以改成:
    sprintf(s, "%7s%7s", a1, a2);
    也没好到哪儿去,正确的应该是:
    sprintf(s, "%.7s%.7s", a1, a2);//产生:"ABCDEFGHIJKLMN"
    这可以类比打印浮点数的”%m.nf”,在”%m.ns”中,m 表示占用宽度(字符串长度不足时补空格,超出了则按照实际宽度打印),n 才表示从相应的字符串中最多取用的字符数。通常在打印字符串时m 没什么大用,还是点号后面的n 用的多。自然,也可以前后都只取部分字符:
    sprintf(s, "%.6s%.5s", a1, a2);//产生:"ABCDEFHIJKL"
    在许多时候,我们或许还希望这些格式控制符中用以指定长度信息的数字是动态的,而不是静态指定的,因为许多时候,程序要到运行时才会清楚到底需要取字符数组中的几个字符,这种动态的宽度/精度设置功能在sprintf 的实现中也被考虑到了,sprintf 采用”*”来占用一个本来需要一个指定宽度或精度的常数数字的位置,同样,而实际的宽度或精度就可以和其它被打印的变量一样被提供出来,于是,上面的例子可以变成:
    sprintf(s, "%.*s%.*s", 7, a1, 7, a2);
    或者:
    sprintf(s, "%.*s%.*s", sizeof(a1), a1, sizeof(a2), a2);
    实际上,前面介绍的打印字符、整数、浮点数等都可以动态指定那些常量值,比如:
    sprintf(s, "%-*d", 4, 'A'); //产生"65 "
    sprintf(s, "%#0*X", 8, 128); //产生"0X000080","#"产生0X
    sprintf(s, "%*.*f", 10, 2, 3.1415926); //产生" 3.14"


    打印地址信息
    有时调试程序时,我们可能想查看某些变量或者成员的地址,由于地址或者指针也不过是个32 位的数,你完全可以使用打印无符号整数的”%u”把他们打印出来:
    sprintf(s, "%u", &i);
    不过通常人们还是喜欢使用16 进制而不是10 进制来显示一个地址:
    sprintf(s, "%08X", &i);
    然而,这些都是间接的方法,对于地址打印,sprintf 提供了专门的”%p”:
    sprintf(s, "%p", &i);
    我觉得它实际上就相当于:
    sprintf(s, "%0*x", 2 * sizeof(void *), &i);
    利用sprintf 的返回值
    较少有人注意printf/sprintf 函数的返回值,但有时它却是有用的,spritnf 返回了本次函数调用
    最终打印到字符缓冲区中的字符数目。也就是说每当一次sprinf 调用结束以后,你无须再调用一次
    strlen 便已经知道了结果字符串的长度。如:
    int len = sprintf(s, "%d", i);
    对于正整数来说,len 便等于整数i 的10 进制位数。
    下面的是个完整的例子,产生10 个[0, 100)之间的随机数,并将他们打印到一个字符数组s 中,
    以逗号分隔开。
    #include
    #include
    #include
    int main() {
    srand(time(0));
    char s[64];
    int ōffset = 0;
    for(int i = 0; i < 10; i++) {
    offset += sprintf(s + offset, "%d,", rand() % 100);
    }
    s[offset - 1] = '\n';//将最后一个逗号换成换行符。
    printf(s);
    return 0;
    }
    设想当你从数据库中取出一条记录,然后希望把他们的各个字段按照某种规则连接成一个字
    符串时,就可以使用这种方法,从理论上讲,他应该比不断的strcat 效率高,因为strcat 每次调用
    都需要先找到最后的那个’\0’的位置,而在上面给出的例子中,我们每次都利用sprintf 返回值把这
    个位置直接记下来了。


    使用sprintf 的常见问题
    sprintf 是个变参函数,使用时经常出问题,而且只要出问题通常就是能导致程序崩溃的内存访
    问错误,但好在由sprintf 误用导致的问题虽然严重,却很容易找出,无非就是那么几种情况,通
    常用眼睛再把出错的代码多看几眼就看出来了。


    ?? 缓冲区溢出
    第一个参数的长度太短了,没的说,给个大点的地方吧。当然也可能是后面的参数的问
    题,建议变参对应一定要细心,而打印字符串时,尽量使用”%.ns”的形式指定最大字符数。


    ?? 忘记了第一个参数
    低级得不能再低级问题,用printf 用得太惯了。//偶就常犯。:。(


    ?? 变参对应出问题
    通常是忘记了提供对应某个格式符的变参,导致以后的参数统统错位,检查检查吧。尤
    其是对应”*”的那些参数,都提供了吗?不要把一个整数对应一个”%s”,编译器会觉得你
    欺她太甚了(编译器是obj 和exe 的妈妈,应该是个女的,:P)。

    strftime
    sprnitf 还有个不错的表妹:strftime,专门用于格式化时间字符串的,用法跟她表哥很像,也
    是一大堆格式控制符,只是毕竟小姑娘家心细,她还要调用者指定缓冲区的最大长度,可能是为
    了在出现问题时可以推卸责任吧。这里举个例子:
    time_t t = time(0);
    //产生"YYYY-MM-DD hh:mm:ss"格式的字符串。
    char s[32];
    strftime(s, sizeof(s), "%Y-%m-%d %H:%M:%S", localtime(&t));
    sprintf 在MFC 中也能找到他的知音:CString::Format,strftime 在MFC 中自然也有她的同道:
    CTime::Format,这一对由于从面向对象哪里得到了赞助,用以写出的代码更觉优雅。

  • Tomcat+Jsp经典配置(转)

    2007-08-30 16:16:53

    Tomcat+Jsp经典Tomcat下JSP、Servlet和JavaBean环境的配置

    经常看到jsp的初学者问tomcat下如何配置jsp、servlet和bean的问题,于是总结了一下如何tomcat下配置jsp、servlet和ben,希望对那些初学者有所帮助。
    一、开发环境配置
    第一步:下载j2sdk和tomcat:到sun官方站(http://java.sun.com/j2se/1.5.0/download.jsp)下载j2sdk,注意下载版本为Windows Offline Installation的SDK,同时最好下载J2SE 1.5.0 Documentation,然后到tomcat官方站点(http://jakarta.apache.org/site/downloads/downloads_tomcat-5.cgi)下载tomcat(下载最新5.5.9版本的tomcat);
    第二步:安装和配置你的j2sdk和tomcat:执行j2sdk和tomcat的安装程序,然后按默认设置进行安装即可。
    1.安装j2sdk以后,需要配置一下环境变量,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的j2sdk安装在c:\j2sdk1.5.0):
    JAVA_HOME=c:\j2sdk1.5.0
    classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;(.;一定不能少,因为它代表当前路径)
    path=%JAVA_HOME%\bin
    接着可以写一个简单的java程序来测试J2SDK是否已安装成功:
    public class Test{
    public static void main(String args[]){
    System.out.println("This is a test program.");
    }
    }
    将上面的这段程序保存为文件名为Test.java的文件。
    然后打开命令提示符窗口,cd到你的Test.java所在目录,然后键入下面的命令
    javac Test.java
    java Test
    此时如果看到打印出来This is a test program.的话说明安装成功了,如果没有打印出这句话,你需要仔细检查一下你的配置情况。
    2.安装Tomcat后,在我的电脑->属性->高级->环境变量->系统变量中添加以下环境变量(假定你的tomcat安装在c:\tomcat):
    CATALINA_HOME=c:\tomcat
    CATALINA_BASE=c:\tomcat
    然后修改环境变量中的classpath,把tomat安装目录下的common\lib下的(可以根据实际追加)servlet.jar追加到classpath中去,修改后的classpath如下:
    classpath=.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tools.jar;%CATALINA_HOME%\common\lib\servlet.jar;
    接着可以启动tomcat,在IE中访问http://localhost:8080,如果看到tomcat的欢迎页面的话说明安装成功了。
    第三步:建立自己的jsp app目录
    1.到Tomcat的安装目录的webapps目录,可以看到ROOT,examples, tomcat-docs之类Tomcat自带的的目录;
    2.在webapps目录下新建一个目录,起名叫myapp;
    3.myapp下新建一个目录WEB-INF,注意,目录名称是区分大小写的;
    4.WEB-INF下新建一个文件web.xml,内容如下:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!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>My Web Application</display-name>
    <descrīption>
    A application for test.
    </descrīption>
    </web-app>
    5.在myapp下新建一个测试的jsp页面,文件名为index.jsp,文件内容如下:
    <html><body><center>
    Now time is: <%=new java.util.Date()%>
    </center></body></html>
    6.重启Tomcat
    7.打开浏览器,输入http://localhost:8080/myapp/index.jsp 看到当前时间的话说明就成功了。
    第四步:建立自己的Servlet:
    1.用你最熟悉的编辑器(建议使用有语法检查的java ide)新建一个servlet程序,文件名为Test.java,文件内容如下:
    package test;
    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 Test extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
    PrintWriter ōut=response.getWriter();
    out.println("<html><body><h1>This is a servlet test.</h1></body></html>");
    out.flush();
    }
    }
    2 .编译
    将Test.java放在c:\test下,使用如下命令编译:
    C:\Test>javac Test.java
    然后在c:\Test下会产生一个编译后的servlet文件:Test.class
    3 .将结构test\Test.class剪切到%CATALINA_HOME%\webapps\myapp\WEB-INF\classes下,也就是剪切那个test目录到classes目录下,如果classes目录不存在,就新建一个。 现在webapps\myapp\WEB-INF\classes下有test\Test.class的文件目录结构
    4 .修改webapps\myapp\WEB-INF\web.xml,添加servlet和servlet-mapping
    编辑后的web.xml如下所示,红色为添加的内容:
    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!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>My Web Application</display-name>
    <descrīption>
    A application for test.
    </descrīption>
    <servlet>
    <servlet-name>Test</servlet-name>
    <display-name>Test</display-name>
    <descrīption>A test Servlet</descrīption>
    <servlet-class>test.Test</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>Test</servlet-name>
    <url-pattern>/Test</url-pattern>
    </servlet-mapping>
    </web-app>
    这段话中的servlet这一段声明了你要调用的Servlet,而servlet-mapping则是将声明的servlet"映射"到地址/Test上
    5 .好了,重启动Tomcat,启动浏览器,输入http://localhost:8080/myapp/Test 如果看到输出This is a servlet test.就说明编写的servlet成功了。
    注意:修改了web.xml以及新加了class,都要重启Tomcat
    第四步:建立自己的Bean:
    1.用你最熟悉的编辑器(建议使用有语法检查的java ide)新建一个java程序,文件名为TestBean.java,文件内容如下:
    package test;
    public class TestBean{
    private String name = null;
    public TestBean(String strName_p){
    this.name=strName_p;
    }
    public void setName(String strName_p){
    this.name=strName_p;
    }
    public String getName(){
    return this.name;
    }
    }
    2 .编译
    将TestBean.java放在c:\test下,使用如下命令编译:
    C:\Test>javac TestBean.java
    然后在c:\Test下会产生一个编译后的bean文件:TestBean.class
    3 .将TestBean.class文件剪切到 %CATALINA_HOME%\webapps\myapp\WEB-INF\classes\test下,
    4 .新建一个TestBean.jsp文件,文件内容为:
    <%@ page import="test.TestBean" %>
    <html><body><center>
    <%
    TestBean testBean=new TestBean("This is a test java bean.");
    %>
    Java bean name is: <%=testBean.getName()%>
    </center></body></html>
    5 .好了,重启Tomcat,启动浏览器,输入http://localhost:8080/myapp/TestBean.jsp 如果看到输出Java bean name is: This is a test java bean.就说明编写的Bean成功了。
    这样就完成了整个Tomcat下的jsp、servlet和javabean的配置。接下来需要做的事情就是多看书、多读别人的好代码,自己多动手写代码以增强自己在这方面开发的能力了。

    jvm应填写到
    c:\j2sdk\bin

    给你一个简单的配置::::

    JSP环境配置心得
    首先要说的是,使用jdk+tomcat完全可以配置我们的jsp服务器,不再需要其实任何东东,有很多文章介绍了Apache,其实根本用不着,一般的学习调试tomcat完全可以胜任了。
    安装jdk后,tomcat在安装之前会自动找到jdk的安装路径,一路点击"下一步",经过一段时间的文件复制,最后"close",完成comcat的安装。
    您最好去下载一个版本较高的tomcat,比如4.1以上的,因为它不需要设置太多的系统变量,右击"我的电脑",选择"属性"->"高级"->"环境变量"->"系统变量",新建一个TOMCAT_HOME,值设置成你的tomcat所在的路径,比如:D:\Program Files\Apache Group\Tomcat 5.5,配置完成。
    从开始菜单中找到tomcat选项,一般打开顺序是:开始->程序->Apache Tomcat 5.5,选择"Start Tomcat",让jsp服务器开始运行,此时会打开一个类似Dos的窗口,会显示一些相关的信息。
    如果您使用代理上网,一定要先撤掉代理,不然您的jsp程序永远也得不到执行。如果不是代理的,这一步就跳过了。
    打开浏览器,在地址栏中输入:http://localhost:8080,如果看到有老虎(我也不知道是老虎还是猫)的画面,恭喜您,您成功了一半。
    先来享受一下成功的喜悦吧,请输入下面的代码:
    <html>
    <head>
    <title>First Page</title>
    </head>
    <body>
    <H3>Today is: h
    <%= new java.util.Date() %>
    </H3>
    </body>
    </html>
    将该程序保存为:First.jsp,放到Tomcat的ROOT目录下,然后在浏览器的地址栏中输入:http://localhost:8080/First.jsp,(First.jsp跟我们保存的文件名的大小写要一致)回车,如果不出意外,应该可以看到形如Today is: h Fri Apr 11 08:32:38 CST 2003 的结果。
    注意:ROOT是tomcat的默认虚拟目录,如果要改成自己的虚拟目录怎么办呢?请继续往下看吧。
    要改成自己的虚拟目录,就要请出server.xml来了,该文件是一个配置文件,在Tomcat\conf目录下,使用任何文本编辑软件都能打开它,我们先找到下面一句:
    <Connector className="org.apache.coyote.tomcat4.CoyoteConnector"
    port="8080" minProcessors="5" maxProcessors="75"
    enableLookups="true" redirectPort="8443"
    acceptCount="100" debug="0" connectionTimeout="20000"
    useURIValidationHack="false" disableUploadTimeout="true" />
    这里的port="8080"就是端口,我们完全可以用别的端口来代替,但不能是被系统占用的端口(0--1023),这里简单提一下。
    下面我们再往下找,会发现以下的语句:
    </Context>
    </Host>
    我们就应该找到这两个语句,如果不懂E文,您就认定这两个语句好了。然后我们将该语句更改如下:
    </Context>
    <Context path="/myjsp" debug="0" docBase="e:/myjsp" reloadable="true">
    </Context>
    </Host>
    这里的path="/myjsp"就是我们就配置的虚拟目录了,以后在地址栏中输入http://localhost:8080/myjsp即可。而docBase="e:/myjsp" 则是机器本地路径,他们通过这个语句形成一个映射关系,其它照抄。
    将上面的First.jsp文件放到e:/myjsp目录下,输入http://localhost:8080/myjsp/First.jsp,是不是有一种喜上眉梢的感觉?
    在论坛里我见得最多的就是很多人不知道javaBean文件放到哪里,老实说开始我也不知道,更令人不解的是,十个人有九种不同的说法,这更让我们茫然。其实这问题也不是我们想像的那么复杂,我们以一个例子说明:
    先建立一个java程序,代码如下:
    package hall;
    public class SimpleBean {
    private String message = "No message specified";
    public String getMessage() {
    return(message);
    }
    public void setMessage(String message) {
    this.message = message;
    }
    }
    保存为SimpleBean.java,编译后会生成一个包,其实就相当于一个目录,也就是SimpleBean.class会存放在hall目录中,暂且保存起来,将来备用。
    再输入以下代码:
    <HTML>
    <HEAD>
    <TITLE>Reusing JavaBeans in JSP</TITLE>
    </HEAD>
    <BODY>
    <CENTER>
    <TABLE BORDER=5>
    <TR><TH CLASS="TITLE">
    Reusing JavaBeans in JSP</TABLE>
    </CENTER>
    <P>
    <jsp:useBean id="test" class="hall.SimpleBean" />
    <jsp:setProperty name="test" property="message" value="Hello WWW" />
    <H1>Message: <I>
    <jsp:getProperty name="test" property="message" />
    </I></H1>
    </BODY>
    保存在我们刚才建立的虚拟目录e:/myjsp下面,并命名为:BeanTest.jsp。
    现在我们应该将hall(包)目录放在哪儿呢?别急,我们先在e:/myjsp下建立一个文件夹WEB-INF,然后再在WEB-INF下建立一个classes文件夹,最后将hall目录放到classes下,当然,hall下的字节码文件SimpleBean.class也一并要移过来,而SimpleBean.java就和BeanTest.jsp放到同一目录吧(可以不需要放的,自己试试)。
    好了,大功告成了,重新启动机器(如果您试了好多次都不行,这一步一定要做),在浏览器中输入:http://localhost:8080/myjsp/BeanTest.jsp,您看到了什么?呵,别告诉我您什么都没看到,那肯定是您设置的问题了。
    好了,文章写完了,我也只是一只菜鸟,所以有写的不准备的地方请多多指教。祝您jsp之旅一路顺风!!!
    Java学习 - 技术文章中心
    初学者问的诸如:《怎样配置环境变量》《怎样运行Servlet》啊?这样的问题太多了,现在我写一个初学者入门必读,以便对初学者有指导作用!
    首先是下载工具:
    我建议初学者用Editplus+JDK,我觉得如果用例如JB,Eclipse,JCreator,虽然刚开始的时候比较方便,但是确使初学者门不知道怎样配置环境变量,
    从而难以达到知其然,知其所以然的地步
    可以通过如下地址下载:
    Editplus(最新版本是v2.11):http://count.skycn.com/softdown.php?id=3641&url=http://sc-http.skycn.net/down/epp211a_cn.exe(要照注册码就自己找吧,网上很多的)
    JDK(最新版本是Java2sdk1_5_0):http://192.18.97.54/ECom/EComTicketServlet/BEGIN30AA3B63E5C2F61C8C26F84B78970A98/-2147483648/926882595/1/627578/627410/926882595/2ts+/westCoastFSEND/jdk-1.5.0_04-oth-JPR/jdk-1.5.0_04-oth-JPR:3/jdk-1_5_0_04-windows-i586-p.exe(这是For Windows)
    然后就是安装JDK,我是把它装到从c:\JDK目录下面:
    然后就是CLASSPATH的问题了:
    正如操作系统利用PATH来搜索可执行程序一样,Java运行环境也会遍历CLASSPATH来查找类,即便是HelloWorld这样简单的程序,JVM也会遍历
    CLASSPATH定义的每一个路径,直到找到相应的文件为止。
    相信大家用的系统不是2k就是XP,然后就应当如下设置Path:
    我的电脑->属性->高级->环境变量
    然后在环境变量的Path后面追加: C:\JDK\bin;.;C:\JDK\lib
    也可以这样配置:C:\JDK\bin;.;C:\JDK\lib\dt.jar;C:\JDK\lib\tools.jar
    ★记住:环境变量中的 . 切记不能少,它表示当前路径,如果少掉出现的错误等会就说!
    dt.jar是关于运行环境的类库,tools.jar是关于一些工具的类库
    如果没有配置:C:\JDK\bin,则会出现 " javac´ 不是内部或外部命令,也不是可运行的程序或批处理文件。"这样的错误。
    然后下面就该写程序了:
    首先是(HelloWorld.java),打开Editplus,新建一个Java文件,请照着如下输入,要一字不漏,并且分清大小写:
    public class HelloWorld{
    public static void main(String[] args){
    System.out.println("Hello,World!");
    }
    }
    然后把这个文件保存(ctrl + s)到HelloWorld.java,记住大小写一定要分清,是HelloWorld.java不是helloworld.java或者其它的
    下面就该运行了,开始->运行->cmd
    在控制台中把目录切换到当前目录:
    javac HelloWorld.java
    java HelloWorld
    你就会在控制台上看见输出的Hello,World!(没出来?我把电脑吃了:))
    javac是编译命令,它把HelloWorld.java编译成HelloWorld.class
    java就是解释命令,JVM把HelloWorld.class解释执行.
    在这个时候:
    1。如果出现Exception in thread "main" java.lang.NoClassDefFoundError: HelloWorld
    那就是你在环境变量中没有加上那个.(dot)
    2。如果出现Exception in thread "main" java.lang.NoSuchMethodError: main
    或者HelloWorld.java:1: Public class helloworld must be defined in a file called
    "HelloWorld.java".
    那就是你没有分清大小写的写入这个HelloWorld,或者保存得时候没有保存为HelloWorld.java
    这个名字一定要跟public class的名字一样
    对于环境变量的问题就说到这里,下面我先所说怎么在Editplus里面编译和运行,在Tools->参数设置->配置用户工具
    1.添加工具(添加应用程序)
    菜单文字:Compile Java Program
    程序:C:\JDK\bin\javac.exe
    参数:文件名称
    初始目录:文件目录
    2.添加工具(添加应用程序)
    菜单文字:Run Java Program
    程序:C:\JDK\bin\java.exe
    参数:文件名称(不含扩展名)
    初始目录:文件目录
    工具组名称可以随便添,比如Debug Java Program
    然后在Tools的下拉菜单中,你就会看见Compile Java Program以及Run Java Program这两个选项,以后你就可以利用ctrl + 1编译和ctrl +2运行程序了

    下面就讨论Servlet的运行:
    首先要运行Servlet,则需要JSP/Servlet container,我建议初学者用Tomcat
    Tomcat(最新版本5.5):http://apache.justdn.org/jakarta/tomcat-5/v5.5.9/bin/jakarta-tomcat-5.5.9.exe然后把这个压缩包解压到:
    C:\Tomcat
    然后再配置环境变量:
    添加三个系统变量:
    JAVA_HOME: C:\JDK
    TOMCAT_HOME: C:\Tomcat
    CLASSPATH: %JAVA_HOME%\lib;%TOMCAT_HOME%\lib
    Tomcat的环境变量就配置完毕了,下面检验Tomcat是否能够运行:
    在控制台中转到C:\Tomcat\bin这个目录,运行startup,然后回出现一个窗口,连跳一大串东西,最后表示Server已经运行
    在浏览器中输入http://localhost:8080,出现欢迎界面,则表示Tomcat没问题了
    然后和上面一样,写入你的第一个Servlet
    import java.io.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    public class HelloWorld extends HttpServlet
    {
    public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException
    {
    response.setContentType("text/html");
    PrintWriter ōut = response.getWriter();
    out.println("<html><head><title>");
    out.println("This is my first Servlet");
    out.println("</title></head><body>");
    out.println("<h1>Hello,World!</h1>");
    out.println("</body></html>");

    }
    }
    然后照样用javac HelloWorld.java来编译这个文件,如果出现无法import javax.servlet.*
    那么就是应该把C:\Tomcat\common\lib里面的servlet.jar(根据实际来看)文件拷贝到C:\JDK\jre\lib\ext中,再次编译,就没有问题了!
    然后在Tomcat目录里面的C:\Tomcat\webapps\ROOT里面按如下的文件结构:
    ROOT\index.html
    ROOT\welcom.jsp
    ROOT\WEB-INF\lib\MyServlet.jar(如果你的servlet的.class打成了.jar文件,则放在lib下面)
    ROOT\WEB-INF\classes\HelloWorld.class(把上面生成的HelloWorld.class文件放在这个里面)
    然后在浏览器中输入http://localhost:8080/servlet/HelloWorld,于是Server众望所归的报错了:Error 404--Not Found
    怎么回事呢?
    Servlet必须使用C:\Tomcat\webapps\ROOT\WEB-INF这个目录下面的web.xml文件进行注册,用EP打开这个web.xml文件,
    在里面加入
    <servlet>
    <servlet-name>HelloWorld</servlet-name>
    <servlet-class>HelloWorld</servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <url-pattern>/servlet/helloworld</url-pattern>
    </servlet-mapping>
    这样的结构
    <servlet>
    <servlet-name>HelloWorld</servlet-name>
    <servlet-class>HelloWorld</servlet-class>
    </servlet>
    表示指定包含的servlet类.
    而以下的结构
    <servlet-mapping>
    <servlet-name>HelloWorld</servlet-name>
    <url-pattern>/servlet/HelloWorld</url-pattern>
    </servlet-mapping>
    表示指定HelloServlet应当映射到哪一种URL模式。
    在修改web.xml完毕过后,重新启动Server,然后再输入http://localhost:8080/servlet/HelloWorld,那么偌大一个Hello,World!等着你呢,恭喜你
    摆平了:)

Open Toolbar