什么是Servlet
Servlet是sun公司提供的一门用于开发动态web资源的技术。
A servlet is a small Java program that runs within a Web server.
Servlet作用
Servlets receive and respond to requests from Web clients,
usually across HTTP, the HyperText Transfer Protocol.
能够接收客户端请求,进行响应,并且遵循http协议
创建Servlet
编写一个Java类,实现servlet接口。
public class MyFirstServlet extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
}
}
把Servlet类部署到web.xml中。
<servlet>
<!--自己配的一个名称-->
<servlet-name>MyFirstServlet</servlet-name>
<!--一定是servlet类所对应全路径-->
<servlet-class>com.example.servlet.MyFirstServlet</servlet-class>
</servlet>
<servlet-mapping>
<!--自己配的一个名称,和上边servlet的名称一定要完全对应-->
<servlet-name>MyFirstServlet</servlet-name>
<!--映射的一个URL,一定是/开头(具体路径)-->
<url-pattern>/servlet/MyFirstServlet</url-pattern>
</servlet-mapping>
servlet调用过程
MyElipse-Servlet模板修改
到MyElipse安装目录下,搜索 *wizard*.jar
找到 com.genuitec.eclipse.wizards_11.5.0.me
替换templates/Servlet.java
Servlet生命周期
1.在默认情况下,Servlet生命周期执行过程如下:
在用户第一次请求时:
1.实例化:构造方法1次
2.初始化:(init):1次
3.get 或者 post方法 每次请求都会被执行
3.服务:(service),以后每次请求,都会直接执行service() :N次
4.销毁:当服务器停止或应用被移除,此时销毁destory()方法执行: 1次
2.改写生命周期
是通过<load-on-startup>来实现的
取值: 整数(1开始 越小优先级越高)
结果?
服务器启动时,对应的Servlet就会执行生命周期(实例化,初始化)
以后每次用户执行时,走service()方法
优点:当用户每一次请求时,速度会变快
缺 点:如果load-on-startup配置太多,Tomcat启动速度会变慢
Servlet具体配置
普通配置
配置多个映射地址
<servlet-mapping> <servlet-name>MyFirstServlet</servlet-name> <url-pattern>/servlet/MyFirstServlet</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name> MyFirstServlet </servlet-name> <url-pattern>/my</url-pattern> </servlet-mapping>
配置统配符
2.通配符的使用 1./* (/servlet/* /* ) 2.*.扩展名(*.do *.action ) 不要这写成/*.action <servlet-mapping> <servlet-name>MyFirstServlet</servlet-name> <url-pattern>/*</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>myfirst</servlet-name> <url-pattern>*.czbk6</url-pattern> </servlet-mapping> http://localhost:8080/myapp/hello.action 3.总结规律: 1.能精确匹配的用精确匹配 /servlet/SecondServlet 2./*优先级高于*.扩展名
线程安全问题
说明servlet不是线程安全的,而且它设计目标就是采用多线程来处理用户请求
线程安全问题解决方法:
1.synchronized:线程同步
2.用单线程:就是实现SingleThreadModel接口
总结:这两种方法都不行,违背了设计意图!!!
最终解决办法:
程序员自己注意,不要定义成员变量,尽量用局部变量
合理决定在Servlet中定义的变量的作用
ServletConfig
1.什么是ServletConfig
A servlet configuration object used by a servlet container used to
pass information to a servlet during initialization
2.作用?
1.得到初始化参数?
如何配置初始化参数?
<init-param>
<!-- 参数名 -->
<param-name></param-name>
<!-- 参数名所对应取值 -->
<param-value></param-value>
</init-param>
注意:该标签出现在<load-on-startup>之前
getInitParameter("参数名");
//获取所有的参数名称
Enumeration<String> initParameterNames = servletConfig
.getInitParameterNames();
while (initParameterNames.hasMoreElements()) {
//获取一个又一个的参数名称
String elementName = initParameterNames.nextElement();
//根据参数名称获取参数内容
System.out.println(servletConfig.getInitParameter(elementName));
}
3.得到一个ServletConfig实例的两种方法?
1,init(ServletConfig config)
2.getServletConfig(); //继承父类GenericServlet或它的子类才行
ServletContext
1.什么是ServletContext?
它是服务器产生的一个对象,它用于实现各个Servlet之间信息共享 ,用于获取全局初始化参数
* 它是运行在服务器中,每个web应用程序都会有一个自己唯一的ServletContext对象。
* 由服务器在加载应用时,就创建好了。
* 它跟web应用程序同生命周期
2.作用? 域中传值 -两遍
1.作为一个全局范围的域对象来用(四大域作用范围),可以实现应用范围的数据共享.实现各个Servlet之间信息共享
实现原理:
就是在全局范围内维护一个Map集合
setAttrbite(key,Value);
Object obj = getAttribute(key);
removeAttribute(key);
2.获取全局化参数
getInitParameter("");
getInitParameterNames();
HttpServletRequest
HttpServletRequest 代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装到这个对象中,开发人员可以通过这个对象,获取客户端请求的信息
常用方法
getRequestURL方法返回客户端发出请求时的完整URL。
getRequestURI方法返回请求行中的资源名部分。
getQueryString 方法返回请求行中的参数部分。
getRemoteAddr方法返回发出请求的客户机的IP地址
getRemoteHost方法返回发出请求的客户机的完整主机名
getRemotePort方法返回客户机所使用的网络端口号
getLocalAddr方法返回WEB服务器的IP地址。
getLocalName方法返回WEB服务器的主机名
** getMethod得到客户机请求方式
获得客户机请求头
** getHead(name)方法
getHeaders(String name)方法
getHeaderNames方法
获得客户机请求参数(客户端提交的数据)
** getParameter(name)方法
** getParameterValues(String name)方法
getParameterNames方法
** getParameterMap方法 //做框架用,非常实用
getInputStream
请求参数的中文乱码问题
浏览器是什么编码就以什么编码传送数据 GET方式 new String(username.getBytes(“ISO-8859-1”),“UTF-8”); POST方式 request.setCharacterEncoding(“UTF-8”);//POST有效 更改Tomcat的配置解决URL编码问题:<Connector URIEncoding=“UTF-8”/>
BeanUtils
导包 两个jar包 logging BeanUtils ---不能够解决乱码 // 获取参数 // 创建一个空对象 Student student = new Student(); // 获取参数的集合 try { // 直接通过BeanUtils的静态方法将请求参数的集合赋值进去,对对象进行赋值 BeanUtils.populate(student, req.getParameterMap()); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } // 修改乱码问题 String string = new String( student.getUsername().getBytes("ISO-8859-1"), "UTF-8"); student.setUsername(string); // 可以打印信息了 System.out.println(student.toString());
HttpServletResponse
对象是指服务器的响应。
这个对象中封装了向客户端发送数据、发送响应头,发送响应状态码的方法。
Response 响应数据及乱码解决
response.setContentType("text/html;charset=UTF-8");
字节流解决乱码问题
// 指定浏览器打开这个网页的编码方式
//MIME text/html */*
response.setContentType("text/html;charset=UTF-8");
// 字节流
// 输出时,指定自己的编码方式utf-8
response.getOutputStream().write("你好啊,收到了你的请求,很开心".getBytes("UTF-8"));
字符流解决乱码问题
//通知浏览器打开方式为utf-8
resp.setContentType("text/html;charset=UTF-8");
resp.getWriter().write("你好,我时刻在关注着白百合");