servlet技术
servlet概念
Servlet(Server Applet)是Java Servlet的简称,称为小服务程序或服务连接器,用Java编写的服务器端程序,具有独立于平台和协议的特性,主要功能在于交互式地浏览和生成数据,生成动态Web内容。
狭义的Servlet是指Java语言实现的一个接口,广义的Servlet是指任何实现了这个Servlet接口的类,一般情况下,人们将Servlet理解为后者。Servlet运行于支持Java的应用服务器中。从原理上讲,Servlet可以响应任何类型的请求,但绝大多数情况下Servlet只用来扩展基于HTTP协议的Web服务器。
最早支持Servlet标准的是JavaSoft的Java Web Server,此后,一些其它的基于Java的Web服务器开始支持标准的Servlet
Servlet 是在服务器上运行的小程序。这个词是在 Java applet的环境中创造的,Java applet 是一种当作单独文件跟网页一起发送的小程序,它通常用于在客户端运行,结果得到为用户进行运算或者根据用户互作用定位图形等服务。
历程
服务器上需要一些程序,常常是根据用户输入访问数据库的程序。这些通常是使用公共网关接口(Common Gateway Interface,CGI)应用程序完成的。然而,在服务器上运行 Java,这种程序可使用 Java 编程语言实现。在通信量大的服务器上,JavaServlet 的优点在于它们的执行速度更快于 CGI 程序。各个用户请求被激活成单个程序中的一个线程,而无需创建单独的进程,这意味着服务器端处理请求的系统开销将明显降低。
实现过程
最早支持 Servlet 技术的是 JavaSoft 的 Java Web Server。此后,一些其它的基于 Java 的 Web Server 开始支持标准的 Servlet API。Servlet 的主要功能在于交互式地浏览和修改数据,生成动态 Web 内容。这个过程为:
- 客户端发送请求至服务器端;
- 服务器将请求信息发送至 Servlet;
- Servlet生成响应内容并将其传给服务器。响应内容动态生成,通常取决 于客户端的请求;
- 服务器将响应返回给客户端。
Servlet 看起来像是通常的 Java 程序。Servlet 导入特定的属于 Java Servlet API 的包。因为是对象字节码,可动态地从网络加载,可以说 Servlet 对 Server 就如同 Applet对 Client 一样,但是,由于 Servlet 运行于 Server 中,它们并不需要一个图形用户界面。从这个角度讲,Servlet 也被称为 FacelessObject。
一个 Servlet 就是 Java 编程语言中的一个类,它被用来扩展服务器的性能,服务器上驻留着可以通过“请求-响应”编程模型来访问的应用程序。虽然 Servlet 可以对任何类型的请求产生响应,但通常只用来扩展 Web 服务器的应用程序。
helloservlet
**Servlet接口不在JavaSE中,需要因为servlet-api依赖
1、定义一个类实现Servlet接口
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope> scope=provider表示该jar包在编译阶段使用,并不会打包到应用中
</dependency>
**`
1、定义一个类实现Servlet接口
```java
public class HelloServlet implements Servlet { //所谓的Servlet就是直接或者间接的实现Servlet接口
@Override
public void init(ServletConfig config) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest req, ServletResponse res) throws
ServletException, IOException { // Servlet组件用于对外提供服务的方法
//接收用户提交数据,不管是使用get还是post提交
String username=req.getParameter("username");
if(username==null ||username.trim().length()<1)
username="Servlet";
String message="Hello "+username+"!";
//使用rep生成针对客户端请求的响应信息
PrintWriter pw=res.getWriter();
pw.println("<h2>"+message+"</h2>");//生成html文档
pw.flush();
pw.close();
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
Servlet—tomcat
/*
Servlet---tomcat
Servlet接口:默认单实例多线程的方式
public void init(ServletConfig config) throws ServletException;用于执行Servlet的初始化操作
在Servlet对象创建完成后自动调用,在整个servlet对象的生命周期中运行且只运行一次
ServletConfig用于当前Servlet的配置信息
<init-param>
<param-name>name</param-name>
<param-value>zhangsan</param-value>
</init-param>
public String getServletName();用于获取当前Servlet配置的名称
<servlet-name>test1</servlet-name>
ServletContext getServletContext();用于获取当前应用的上下文对象,用于实现跨用户数据共享
getInitParameter(String name);获取对应name名称的配置值
<init-param>
<param-name>width</param-name>
<param-value>140</param-value>
</init-param>
Enumeration<String> getInitParameterNames()获取获取当前Servlet所有的初始化参数名称---Iterator
public void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
以多线程的方式对外提供服务,一个用于请求对应一个线程执行service方法
servlet响应执行完成后,并不会立即销毁;而是常驻内存
自动加载
<servlet>
<servlet-name>test1</servlet-name>
<servlet-class>com.yan.TestServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
public void destroy();用于销毁回收Servlet对象前的资源回收操作
关闭服务器和当前Servlet被调度销毁
为了简化开发GenericServlet抽象父类,主要用于非标协议应用开发
针对web应用提供了父类HttpServlet,主要用于http协议应用开发
service方法
Servlet对象常驻内存,针对不同的用户使用不同的线程执行service
HttpServletRequest
getMethod():String获取当前请求对应的方法 get/post
getRemoteAddr():String 获取客户端的IP地址
request.getRequestURL():StringBuffer 获取请求地址
request.getQueryString():String 获取请求参数
用户提交的数据
getParameter("name"):String 例如?name=zhangsan
getParamterValues("name"):String[]
用户代理额外传递的数据 请求头
request.getHeader("请求头名称"):String
request.getIntHeader("请求头名称"):int
request.getDateHeader():long
编程2个页面之间传递数据 attribute---map
request.setAttribute("name",Object); getAttribute removeAttribute
要求:必须是请求转发,如果重定向则数据丢失
request.setAttribute("now",new Date());
request.getRequestDispatcher("test1.do").forward(request,response);
Object obj=request.getAttribute("now");
请求转发: 当前页面和跳转页面共享request和response对象
request.getRequestDispatcher("test1.do").forward(request,response);
HttpServletResponse
*/
service方法实际上是由tomcat服务器负责调用执行,服务器调用方法时会传入两个参数,一个req用于封装所有的用户请求信息,一个res用于封装服务器向客户端的响应信息
req.getParameter用于获取用户提交的数据,例如get请求 hello.do?
username=zhangsan&age=1
res.setContentType用于告知客户端的浏览器,如何处理响应信息
res.setContentType(“text/html;charset=utf-8”);
遵循一个MIME协议(多用途互联网邮件协议),其中text表示是一个文本文档,html表示是一个 html格式的文档文档
res.getWriter用于获取向客户端输出数据的输出流,在编码中向输出流中写出数据,实际上就是向客户端输出的内容
2、在web应用的核心配置文件web.xml中将Servlet和一个URL地址建立对应关系,当用户请求对应的URL地址时则触发Servlet运行
Servlet类中没有main方法,所以程序的执行是由服务器按照规则进行调用的
由客户端对特定路径发起请求触发执行
**<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 将Servlet类和一个名称建立对应关系 -->
<servlet>
<servlet-name>helloServlet</servlet-name>
<servlet-class>com.yan.action.HelloServlet</servlet-class>
</servlet>
<!-- 将一个地址和名称建立对应关系 -->
<servlet-mapping>
<servlet-name>helloServlet</servlet-name>
<url-pattern>/hello.do</url-pattern>
</servlet-mapping>
</web-app>
**
3、启动Tomcat服务器
4、在浏览器中输入请求URL地址 http://localhost:8080/demo1_war/hello.do
5、使用get提交数据 http://localhost:8080/demo1_war/hello.do?username=zhangsan
servlet特征
一般采用单实例多线程的方式对外提供服务,一个客户请求对应一个线程
如果在Servlet类中定义属性,则需要考虑线程安全问题
Servlet用MIME过滤数据,由javax.servlet和javax.servlet.http两个包组成Java Servlet API框架
编写Servlet必须直接或间接实现作为Servlet的核心javax.servlet.Servlet接口,通常是实现
javax.servlet.http.HttpServlet的子类,可以覆盖继承doGet()或者doPost()方法,两者分别对应于Http(s)中的Get请求和Post请求
servlet优点
1、 是mvc的基础,其他的框架比如struts1,struts2,webwork都是从servlet基础上发展过来的。所以掌握servlet是掌握mvc的关键。
2、 Servlet把最底层的api暴漏给程序员,使程序员更能清楚的了解mvc的各个特点。
3、 程序员可以对servlet进行封装。Struts2就是从servlet中封装以后得到的结果。
4、 市场上任何一个mvc的框架都是servlet发展过来的,所以要想学好struts2这个框架,了解servlet的运行机制很关键。
servlet缺点
1、 每写一个servlet在web.xml中都要做相应的配置。如果有多很servlet,会
导致web.xml内容过于繁多。
2、 这样的结构不利于分组开发。
3、 在servlet中,doGet方法和doPost方法有HttpServletRequest和HttpServletResponse参数。这两个参数与容器相关,如果想在servlet中作单元测试,则必须初始化这两个参数。
4、 如果一个servlet中有很多个方法,则必须采用传递参数的形式,分解到每一个方法中。