CGI是最早的动态编程技术,并且这是一个标准,可以使用任何的语言实现,但是Java对CGI程序的实现就是Servlet,也就是说Servlet就是一个CGI程序编程。传统的CGI采用的是多进程的方式进行处理的,所以来讲性能会很差,但是Servlet不太一样,Servlet使用的是Java多线程来进行处理,也就是说每一次的用户请求发送过来后都会启动一个线程进行处理。
但是Servlet程序是利用Java类的结构实现的,并且最早出现的技术就是Servlet,可是Servlet对于WEB开发人员的技术要求比较高,所以刚开始出现时并不容易被人所掌握,后来SUN受到了微软ASP(ASP+COM)技术的启发,才产生了JSP(JSP+JavaBean(DAO))技术。
虽然JSP是通过Servlet改良而得来的,但并不意味着Servlet程序就没有任何的用处了,相反,它在所有的开发之中用处非常的大,而且也非常的重要。
1 开发第一个Servlet程序
Servlet程序是以类的形式定义的,所以如果要想使用一个Servlet程序,那么必须将程序生成的*.class
文件放在WEB-INF/classes目录下。Servlet的安全性是非常高。但是开发起来比较麻烦。
1、任何一个Servlet程序类都必须继承HttpServlet父类;
首先观察HttpServlet类的定义结构:
public abstract class HttpServlet
extends GenericServlet
发现HttpServlet是一个抽象类,所以这个类如果要使用必须有子类,同时在这个类里面没有任何的抽象方法(实现意义:使用这个类必须要有子类,而且子类可以根据自己的需要选择性的覆写方法)。
既然JSP程序的功能是处理用户请求的,那么Servlet也一定是处理用户请求的,所以可以覆写HttpServlet类中提供的如下两个方法:
(1)处理GET请求:protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
(2)处理POST请求:protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
现在可以发现在doGet()
或doPost()
方法上都接收了HttpServletRequest与HttpServletResponse两个接口实例,那么就表示这些方法可以接受用户的请求,同时可以针对于请求进行回应。
如果要利用Servlet程序输出HTML代码,那么必须取得客户端的输出流.
(1)取得字符打印流:public PrintWriter getWriter() throws IOException
package org.lks.demo;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;
import java.io.IOException;
//必须是public class, 因为要被外部所访问
public class HelloServlet extends HttpServlet{
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{
resp.setCharacterEncoding("UTF-8");
PrintWriter out = resp.getWriter();
out.print("<html>");
out.print("<head>");
out.print("<title>第一个Servlet程序</title>");
out.print("</head>");
out.print("<body>");
out.print("<h1>Hello World!</h1>");
out.print("</body>");
out.print("</html>");
out.close();
}
}
Servlet程序是不需要主方法的,所有的程序代码最终一定是放在服务器上执行。
3、由于所有生成的类都必须保存在WEB-INF/classes目录中,所以可以直接在此目录下打包编译,这样生成的包.类
就会自动保存在所需要的目录下了;
(1)打包编译:java -d . HelloServlet.java
;
但是这个时候如果没有任何的配置,就有可能出现如下的错误提示:
HelloServlet.java:5: 错误: 程序包javax.servlet.http不存在
import javax.servlet.http.HttpServletResponse;
^
HelloServlet.java:6: 错误: 程序包javax.servlet不存在
import javax.servlet.ServletException;
发现此时javax.servlet与javax.servlet.http两个包都不存在。JDK实际上包含的只是Java SE的支持,而JSP是属于JAVA EE的范畴,所以JDK在编译Servlet的时候就会出现缺少开发包的情况。
Servlet的开发包保存在了TOMCAT_HOME/lib/servlet-api.jar文件里面。那么如果要想引用这个jar文件需要配置CLASSPATH属性了。
SET CLASSPATH=.;D:\Program Files\Tomcat\apache-tomcat-9.0.13\lib\servlet-api.jar;
4、但是必须遗憾的告诉大家的是,此时Servlet还是不能够运行,Servlet程序是放在WEB容器下执行的,所以如果要想运行Servlet还必须配置web.xml文件,也就是说为一个Servlet定义一个它的访问路径。
<!-- 表示要进行Servlet类的配置-->
<servlet>
<!-- 主要是配置在此文件中使用的关联名称 -->
<servlet-name>MyHello</servlet-name>
<!--所有的Servlet程序一定要保存在CLASSPATH下-->
<servlet-class>org.lks.demo.HelloServlet</servlet-class>
</servlet>
<!--配置Servlet的映射路径-->
<servlet-mapping>
<!-- 主要是配置在此文件中使用的关联名称 -->
<sevlet-name>MyHello</servlet-name>
<!--定义映射路径-->
<url-pattern>/hello.do</url-pattern>
</servlet-mapping>
此时配置的是一个根目录的映射路径,所以直接在根路径下就可以访问/hello.do
。
通过以上的一段配置可以发现所有的Servlet程序要想运行必须依靠web.xml文件的配置支持,同时Servlet与JSP相比,JSP更加适合于输出,但是Servlet的最大优点是安全,而且使用原始Java编写,调用程序的时候更加的方便。
5、在任何的Servlet程序里面最大的特色还在于,可以为一个Servlet配置多个路径。
<servlet-mapping>
<servlet-name>MyHello</servlet-name>
<url-pattern>/hhy.bd</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>MyHello</servlet-name>
<url-pattern>/testdemo/*</url-pattern>
</servlet-mapping>
在Servlet配置上*
绝对是一个特色。
2 利用MyEclipse开发
Servlet依然属于Java程序,所以此程序依然要在src目录下建立,而且所有的类必须有包。
随后进入到web.xml文件的映射配置的窗口界面。
Name选项实际上配置的就是Servlet中在web.xml文件里的<servlet-name>
的内容。
URL:表示配置的映射路径。
而后询问用户要在建立的Servlet中覆写哪些方法,本次就先覆写doGet()方法。
范例:查看web.xml文件
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>org.lks.demo.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/HelloServlet</url-pattern>
</servlet-mapping>
可以看到此时已经自动生成了Servlet的配置信息。
范例:定义程序类
package org.lks.demo;
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;
@SuppressWarnings("serial")
public class HelloServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">");
out.println("<HTML>");
out.println(" <HEAD><TITLE>A Servlet</TITLE></HEAD>");
out.println(" <BODY>");
out.print(" This is ");
out.print(this.getClass());
out.println(", using the GET method");
out.println(" </BODY>");
out.println("</HTML>");
out.flush();
out.close();
}
}
一个完整的Servlet就可以直接使用了。
总结:
(1)Sevlet是一个纯粹的Java编写的动态WEB程序;
|————Servlet类必须继承HttpServlet这个父类,而且要按照规则覆写里面的方法。
(2)任何的Servlet程序类如果需要被使用,必须在web.xml文件里进行配置;
|————<servlet>
元素配置的Servlet程序类,而<servlet-mapping>
元素配置的是映射路径;
(3)Servlet1与JSP相比,不适合于进行页面信息的输出。