java-web 第四讲 servlet 学习心得
来源:互联网 发布:photoshop最新软件版本 编辑:程序博客网 时间:2024/06/01 09:50
1:servlet 接口:
1.1 servlet 主要方法: init() --ServletConfig
servlet 实例化后,容器会先调用init 方法,用于初始化该对象,即在处理客户需求前完成一些初始化工作。每一个 servlet实例,init 只能被调用一次,相当于java的static 块。
servlet 使用 ServletConfig 对象 从web 应用程序的配置信息中获取以 键值对形式提供的初始化参数。
servlet 使用 ServletConfig 对象获取 ServletContext 对象,使用 ServletContext 可以使 servlet 和servlet 容器进行通信。
service() --ServeltRequest ServletResponse
容器调用service() 方法来处理客户的请求,注意: 在service 方法前必须确保 init 方法正确完成。
容器会构造一个请求对象 ServletRequest 和 响应对象 ServletResponse 作为参数传递给service ().
destroy(): 当容器检测到servlet 对象从服务中移除的时候会调用该方法。释放资源 给GC
getServletConfig() 返回servletconfig 对象
getServletInfo() 返回一个字符串,包含servlet 信息
1.2 servlet 创建的三种方法一是实现Servlet接口,二是继承抽象类GenericServlet,三是继承HttpServlet类。
1: 实现servlet 接口 必须实现servlet 五个方法
- public class TestServlet implements Servlet{
- public void init(ServletConfig config) throws ServletException{
- System.out.println("init");
- }
- public ServletConfig getServletConfig(){
- reture null;
- }
- public void service(ServletRequest req,ServletResponse res)
- throws ServletException,IOException{
- //这里可以实现请求后要做的内容
- PrintWriter out = response.getWriter();
- out.println("Hello World!");
- }
- public String getServletInfo(){
- return null;
- }
- public void destroy(){
- System.out.println("destory");
- }
- }
2: 继承抽象类 GenericServletGenericServlet类中只有一个抽象方法,即service(ServletRequest req, ServletResponse res)
- public TestGenericServlet extends GenericServlet{
- public abstract void service(ServletRequest req,ServletResponse res)
- throws ServletException,IOException{
- PrintWriter out = response.getWriter();
- out.println("Hello World!");
- }
- }
3: 继承HttpServlet类编写Servlet应该是最容易的,而且是最常见的,我们一般要编写Servlet直接继承这个类就行了,重写doGet()或者doPost()方法即可
- public TestHttpServlet extends HttpServlet{
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException {
- response.setContentType("text/html;charset=gb2312");
- PrintWriter out = response.getWriter();
- out.println("<html>");
- out.println("<head>");
- out.println("<title>HelloWorld</title>");
- out.println("</head>");
- out.println("<body bgcolor=\"white\">");
- out.println("<hr>");
- out.println("HelloWorld");
- out.println("</body></html>");
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws IOException, ServletException {
- doGet(request, response);
- }
- }
在servlet 中,主要接口与类方法如下:
1.3: HttpServlet 详解
1:七种请求方法 doGet doPost doHead doPut doDelete doTrace doOptions 参数都是 HttpRequest HttpResponse
2:servlet 执行顺序: 当容器收到一个servlet 请求后, 先调用 公共的 service() 方法 在调用service 时候,首先将参数转换为 HttpRequest 和 HttpResponse
然后调用保护的(protected) service() 方法 将转换后的 HttpRequest 和 HttpResponse 作为参数传递下去
在 protected service 中 ,首先调用 HttpRequest 的 getMethod() 获取 HTTP 请求方法的名字,然后根据类型调用相应的 doXXX() 方法
1.4: HttpServletRequest,HttpServletResponse 详解
HttpServletRequest:String getContextPath() 返回请求URL 中表示上下文的部分 如: /simple/test 返回 /simple
Cookie[] getCookies() 返回本次请求所有的Cookie 对象
String getHeader() 返回请求报头的值
String getMethod() 返回本次请求使用的HTTP 方法的名字 如 post get Trace 等
String getPathInfo() 返回额外 url 信息 如 /simple/test 返回 test
String getPathTranslated() 返回真实路径信息 如
String getQueryString() 返回请求的action 名称 如 返回 logon
HttpSession getSession() 返回和此次请求相关联的session
HttpServletResponse:void addCookie(Cookie cookie) 新增一个cookie 到响应中去,可以设置多个。
addheader(String name,String value) 用给出的name and value 增加一个响应报头到响应中去
sendRedirect(String location) 发送一个临时的重定向到客户端 让客户端访问的url重新定位
1.5: ServletConfig
servlet容器使用ServletConfig 对象在容器初始化的时候向其传递配置信息
四种主要方法: String getInitParemeter(String name) 返回名字为 name 的初始化参数的值,初始化参数在配置文件 web.xml 中配置
Enumeration getInitParameterNames() 返回servlet 所有初始化参数名字的枚举集合
ServletContext getServletContext() 返回servlet 上下文对象的引用
String getServletName() 返回 当前servlet 的名称
2:servlet 配置
1:web.xml: web 应用程序的配置和部署都是通过web.xml 来完成的,其包含以下信息:
ServletContext 的初始化参数
Session 的配置
Servlet/Jsp 的定义
Servlet/jsp 的
MIME 类型映射
欢迎文件列表
错误页面
安全
地区和编码映射
JSP 配置
<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <!-- Servlet名字,可以随便取,有多个Servlet时不允许重名 --> <servlet-name>SimpleServlet</servlet-name> <!-- 指定实现这个Servlet的类 完整的包名+类名 --> <servlet-class>com.tide.servlet.SimpleServlet</servlet-class> </servlet> <servlet-mapping> <!-- –必须和<servlet>里的<servlet-name>内容一样 --> <servlet-name>SimpleServlet</servlet-name> <!-- 指定访问这个Servlet的URL。这里给出的是对于整个Web应用的相对URL路径 这里是浏览器访问时的地址 http://localhost:8080/Myservlet/hello 即可访问--> <url-pattern>/hello</url-pattern> </servlet-mapping></web-app>
对于servlet 上的页面 有两种访问方式: 一种是在web.xml 中的 url-pattern 中直接访问地址 另一种是访问jsp 对象
3:servlet 例子
3.1 简单表单模拟
web.xml 部署为<?xml version="1.0" encoding="UTF-8"?><web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"> <display-name></display-name> <welcome-file-list> <welcome-file>index.jsp</welcome-file> </welcome-file-list> <servlet> <servlet-name>loginjsp</servlet-name> <servlet-class>com.tide.servlet.Login</servlet-class> </servlet> <servlet-mapping> <servlet-name>loginjsp</servlet-name> <url-pattern>/login</url-pattern> </servlet-mapping></web-app>login.jsp 测试登陆<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"contentType="text/html; charset=UTF-8"%><% request.setCharacterEncoding("UTF-8"); %><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><html> <head> <title>用户注册</title> </head> <body> <center> <h2>用户注册</h2> <hr> <form action="login" method="post"> 用户姓名:<input type="text" name="username" style="width:138px" /> <br> 用户密码:<input type="password" name="password" style="width:138px" /> <br> <br> <input type="submit" value="确定"/> <input type="reset" value="取消"/> </form> </center> </body></html>
package com.tide.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 Login extends HttpServlet {public void doGet(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException {String name = req.getParameter("username");System.out.println("获取的名称为-- " + name);PrintWriter pw;pw = res.getWriter();/*pw.print("<html><head><title>");pw.print("Welcome");pw.print("<title><head>");pw.print("<body>");pw.print("hello " + name);pw.print("</body></html>");*/pw.print("hello "+name);pw.close();}public void doPost(HttpServletRequest req, HttpServletResponse res)throws ServletException, IOException{ String username = req.getParameter("username"); String password = req.getParameter("password"); res.setContentType("text/html"); PrintWriter out = res.getWriter(); out.println("<html><head><title>Login Result</title></head>"); out.println("<body> username: " + username + "<br>"); out.println("password: " + password + "</body></html>"); out.flush();}}
--------------------------------------------------------------------------------------------------
采用post 模式 可以避免密码的泄露
get与post方法之间的差别:
1.浏览器地址栏呈现的结果不同(表象);2.真正的原因在于向服务器端发送请求时的形式是不同的。 3.get的请求格式: GET /test/LoginServlet?username=hello&password=world HTTP/1.1 4.post的请求格式: POST /test/LoginServlet HTTP/1.1 Connection: Keep-Alive username=hello&password=world 5.通过浏览器进行文件上传时,一定要使用post方式而绝不能使用get方式。 6.通过浏览器地址栏输入网址的方式来访问服务器端资源,全部使用的是get方法请求的。------------------------------------------------------------------------------------------------------
3.2 消息包头输出到客户端
servlet 实现: 报文头部 客户端的运行环境等信息 全部通过 HttpServletRequest 来获取
public class OutputInfo extends HttpServlet {public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{res.setContentType("text/html;charset=gb2312");PrintWriter pw = res.getWriter();Enumeration headName = (Enumeration) req.getHeaderNames();pw.println("<html><head>");pw.println("<title> Info Page </title>");pw.println("</head>");pw.println("<body><center>");pw.println("<table border=1 align=center>");pw.println("<caption>Servlet 接收到的Http 消息 包头的信息</caption>");pw.println("<tr bgcolor=#999999>");pw.println("<th>消息包头的名字</th>");pw.println("<th>消息包头的值</th>");pw.println("</tr>");while(headName.hasMoreElements()){String name = (String) headName.nextElement();String value = req.getHeader(name);pw.println("<tr>");pw.println("<td>"+name+"</td>");pw.println("<td>"+value+"</td>");pw.println("</tr>");}pw.println("</table><p>");pw.println("<table border=1 align=center>");pw.println("<caption> 其他访问信息 </caption>");pw.println("</tr>");pw.println("<tr>");pw.println("<td>客户端的IP地址</td>");pw.println("<td>"+req.getRemoteAddr()+"</td>");pw.println("</tr>");pw.println("<tr>");pw.println("<td>客户端的端口号</td>");pw.println("<td>"+req.getRemotePort()+"</td>");pw.println("</tr>");pw.println("<tr>");pw.println("<td>服务器端的IP地址</td>");pw.println("<td>"+req.getLocalAddr()+"</td>");pw.println("</tr>");pw.println("<tr>");pw.println("<td>服务器端的端口号</td>");pw.println("<td>"+req.getLocalPort()+"</td>");pw.println("</tr>");pw.println("</table>");pw.println("</center></body></html>");pw.close();}}
将 servlet 添加到 web.xml 中 然后在客户端测试结果为 :
Servlet 接收到的Http 消息 包头的信息 消息包头的名字 消息包头的值 hostlocalhost:8080connectionkeep-alivecache-controlmax-age=0accepttext/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8user-agentMozilla/5.0 (Windows NT 6.1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 Safari/537.36accept-encodinggzip,deflate,sdchaccept-languagezh-CN,zh;q=0.8其他访问信息 客户端的IP地址127.0.0.1客户端的端口号60255服务器端的IP地址127.0.0.1服务器端的端口号8080
4:Servlet 生命周期
Servlet 运行期间,其生命周期由容器来统一管理,生命周期通过 Servlet 的 init() destroy() service() 三种方法来表示
主要包含了四个阶段:
1:加载和实例化
在容器启动 或者响应第一个客户请求时,创建servlet 实例。
2:初始化
servlet 实例化后,容器必须调用 servlet 的 init() 方法来初始化这个servlet 对象,目的为了servlet 在处理客户请求前完成一系列的初始化工作,
对于每一个servlet init() 只调用一次, 此时可以使用 ServletConfig 来从web.xml 中获取初始化的参数信息。
3:请求处理
servlet 容器调用servlet 的 service() 方法对请求进行处理,在此之前 init() 方法必须调用成功。Servlet 通过 ServletRequest 来获取客户端的信息和请求,对请求处理后 调用 ServletResponse 来设置响应信息。出现错误的话:该实例永久不可用-404 暂时不可用-503
4:服务终止
容器检测到实例从服务中移除后,调用 destroy()
5:Servlet 上下文
运行在java 虚拟机中的每一个web程序都有一个与之相关的 Servlet 上下文, java servlet API 提供了一个 ServletContext 接口来表示上下文。
一个 ServletContext 对象表示了一个web 程序的上下文, servlet 容器在初始化实例期间,向其传递 ServletConfig 对象, 通过其 getServletContext() 获取上下文。
上下文例子: 统计页面访问量 *************注意这里的上下文必须放在安全锁里
public class CountDemo extends HttpServlet {public void doGet(HttpServletRequest req,HttpServletResponse res) throws ServletException,IOException{ServletContext context = getServletContext();//Enumeration<String> count = context.getAttributeNames();Integer count = null;synchronized(context){count = (Integer)context.getAttribute("counter");if(null == count){count = new Integer(1);}else{count = new Integer(count.intValue()+1);}context.setAttribute("counter", count);}res.setContentType("text/html;charset=gb2312");PrintWriter pw = res.getWriter();pw.println("<html><head>");pw.println("<title>页面访问统计</title>");pw.println("</head><body>");pw.println("该页面已经被访问了 :"+"<b>"+count+"</b>"+" 次");pw.println("</body></html>");pw.close();}}
6:Servlet 请求转发
好处: <1> 提供了统一的访问方式 <2> 控制器(controller)可以将不同的请求发送给不同的servlet 来进行处理 本身不处理请求,缩短了响应时间
6.1 RequestDispacher: servlet 控制器
RequestDispacher 对象由 Servlet 来创建,用于封装一个由路径所标示的服务器资源。 主要有以下两种方法:
forward(ServletRequest req,ServletResponse res) : 该方法用于将 请求从一个servlet 传递给服务器上的 另外的 servlet jsp 页面,或者 HTML 文件
注意: 这个方法必须在响应被提交给客户端之前使用,之后的话会爆出 IllegastateException 错误 在 forward() 调用后原先在响应缓存中的未被提交的内容将自动清除。
include(ServletRequest req,ServletResponse res) 该方法用于响应中包含其他的资源信息(servlet jsp html)等内容。
这两个方法的区别是:include 将请求转发给其他对象后,被调用的servlet 做出的响应将并入原来的响应对象中,原来的servlet 对象还可以继续输出响应数据。
forward 将请求转发给其他对象后,将由被调用的servlet 对象做出响应,原来的servlet 执行将终止。
6.2 RequestDispache 对象的获取三种方法:
<1> ServletRequest.getRequestDispacher(String path) --资源路径名
<2> ServletContext.getNamedDispacher(String name) -- jsp 或 servlet 名称
<3> SerletContext.getRequestDispacher(String path)-- 这里路径必须以 / 开头 相对于当前上下文根的路径 如 /MyServlet
6.3 请求转发的实例
package com.tide.servlet;import java.io.IOException;import javax.servlet.RequestDispatcher;import javax.servlet.ServletContext;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.apache.commons.lang3.StringUtils;public class Login extends HttpServlet {public void doPost(HttpServletRequest req,HttpServletResponse res)throws ServletException,IOException{res.setContentType("text/html;charset=GB2312");ServletContext context = getServletContext();String name = req.getParameter("user");String pass = req.getParameter("passwd");System.out.println("获取到的用户名为 :"+name+" --密码为 :"+pass);if(StringUtils.isBlank(name) || StringUtils.isBlank(pass)){System.out.println("用户名或密码为空");RequestDispatcher dis = context.getRequestDispatcher("/register.jsp");dis.forward(req, res);}else{RequestDispatcher dis = context.getRequestDispatcher("/loginsuccess.jsp");dis.forward(req, res);}}}
底层分析:
请求转发(RequestDispatcher)的过程:客户首先发送一个请求到服务器端,服务器端发现匹配的servlet,并指定它去执行,当这个servlet执行完之后,它要调用getRequestDispacther()方法,把请求转发给指定的test.jsp,整个流程都是在服务器端完成的,而且是在同一个请求里面完成的,因此servlet和jsp共享的是同一个request,在servlet里面放的所有东西,在jsp中都能取出来,因此,jsp能把结果getAttribute()出来,getAttribute()出来后执行完把结果返回给客户端。整个过程是一个请求,一个响应。重定向(sendRedirect)的工作原理:客户发送一个请求到服务器,服务器匹配servlet,这都和请求转发一样,servlet处理完之后调用了sendRedirect()这个方法,这个方法是response的方法,所以,当这个servlet处理完之后,看到response.senRedirect()方法,立即向客户端返回这个响应,响应行告诉客户端你必须要再发送一个请求,去访问test.jsp,紧接着客户端受到这个请求后,立刻发出一个新的请求,去请求test.jsp,这里两个请求互不干扰,相互独立,在前面request里面setAttribute()的任何东西,在后面的request里面都获得不了。可见,在sendRedirect()里面是两个请求,两个响应。
0 0
- java-web 第四讲 servlet 学习心得
- java web(jsp + servlet + javabean)学习心得总结
- java 第四讲
- Java讲座第四讲
- java第四讲
- Java基础第四讲
- Java Web基础:第七讲 Servlet运行原理
- Java Web 第四天 使用Servlet处理请求
- java web从零单排第四期《servlet》(2)
- servlet 第四讲 笔记 分页技术
- Java Web基础:第四讲 Java Web应用的文档结构
- Java Web学习心得
- java Web 基础知识学习心得
- java web学习心得与总结(四)——servlet技术
- java web 开发学习心得体会
- Servlet自学第1讲:web入门
- 第四课 Java Servlet技术
- servlet 学习心得
- backbone学习进阶—
- pyhon之Tkinter实例化学习
- 读书笔记--JavaScript设计模式:Constructor模式(创建对象的方法)
- ubuntu14.04加入win7引导
- 关于小兵日历无法删除的解决办法
- java-web 第四讲 servlet 学习心得
- mergeSort
- 关于使用XMLHTTP的艰苦经历
- Interleaving String
- android:background="@color/white" [create file color.xml at res/values/]
- 前端性能优化最佳实践
- 自定义带占位符Placeholder的textView
- android布局属性详解
- JDK,JRE & JVM