servlet基础

一. 背景知识
1. 常用的Web服务器
    ~ IIS
    ~ Apache
    ~ Tomcat
2. 通常的动态网页技术
    ~ CGI (Common GateWay Interface)
    ~ API常用的有(NSAPI, ISAPI)
    ~ ASP (Active Server Page)
    ~ PHP (Personal Home Page) ----------->LAMP(Linux+apache+mysql+php)
    ~ JSP/Servlet (Java Server Page)

二. Tomcat的安装与配置
1. 解压到相应目录。如C:\tomcat
2. tomcat6的目录结构
    ~bin: 包含tomcat可执行的二进制文件。常用的有startup.bat, shutdown.bat
    ~conf: 包含tomcat的配置文件。如context.xml, server.xml, web.xml
    ~lib: 包含tomcat所需的Jar文件。
    ~logs: 日志文件
    ~temp: 临时文件
    ~webapps: web应用主目录
    ~work: 保存缓存文件
3. tomcat的配置
    ~配置JAVA_HOME系统环境变量,变量值指向安装的JDK路径。如C:\jdk1.6.0_17
    ~更改端口:打开conf\server.xml, 可把默认8080端口改成80(也可保持默认8080端口不变),在此不变。
 <Connector port="80" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" />
    ~自动加载: 打开conf\context.xml, 在Context属性里添加属性reloadable="true"
 <Context reloadable="true">

三. HTTP协议基础
1. HTTP(Hypertext Transfer Protocol, 超文本传输协议)
2. HTTP是以明文方式发送数据的
3. 用于从WWW服务器传输超文本到本地浏览器的传输协议
4. 现在广泛使用的版本HTTP/1.1

四. Servlet简介
1. Servlet是服务器小应用程序
2. 用来完成B/S架构下,客户端请求的响应处理
3. 平台独立,性能优良,能以线程方式运行
4. Servlet API为Servlet提供了统一的编程接口
5. Servlet一般在容器中运行
6. 常见的Servlet容器
    ~Tomcat
    ~Jetty/Resin

五. Web Application的概念
1. Web Application Name
1.1 WEB-INF
 ~web.xml: 该web app的配置文件
 ~lib目录: 该web app用到的库文件
 ~classes目录: 存放编译好的servlet
1.2 META-INF
 ~存放该web app的上下文信息,符合J2EE标准
2. Web Application可以直接放在webapp下面
3. 也可以通过配置文件指定到其它目录<host>里面
 <Context path="/虚拟路径名" docBase="目录位置" debug="0" reloadable="true"/>

六. Servlet应用程序实例
1. 建立所需的目录结构
    ~在tomcat安装目录的子目录webapps下新建文件夹hello
    ~在hello文件夹下新建WEB-INF文件夹和index.html文件
    ~在WEB-INF文件夹下新建classes和lib文件夹,以及web.xml文件
2. 编写HelloWorldServlet.java,并把编译好的class文件放到classes目录下
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 HelloWorldServlet extends HttpServlet {

 @Override
 protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
  response.setContentType("text/html;charset=gbk");
  PrintWriter out = response.getWriter();
  out.println("<html><head></head><body><center><font color='red'>
    HelloWorldServlet</font></center></body></html>");
  out.flush();
  out.close();
 }

 private static final long serialVersionUID = 1L;
 protected void doGet(HttpServletRequest request,HttpServletResponse response) throws ServletException, IOException {
  doGet(request,response);
 }
}
3. 配置web.xml
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app 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_2_5.xsd" version="2.5">
                                                                     
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>HelloWorldServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>hello</servlet-name>
        <url-pattern>/hello.do</url-pattern>
    </servlet-mapping>
  
</web-app>
4. 编写index.html
<html>
 <head>
  <title>this is a test page</title>
 </head>
 <body>
  <form method="post" name="form1" action="/hello/hello.do" >
   用户名:
   <input type="text" name="username" size=20>
   <br>
   密码:
   &nbsp;
   <input type="password" name="password" size=20>
   <br>
   &nbsp;&nbsp;&nbsp;&nbsp;
   <input type="submit" name="submit" value="提交">
   &nbsp;&nbsp;&nbsp;
   <input type="reset" name="reset" value="重置">
  </form>
 </body>
</html>
5. 在浏览器输入http://localhost:8080/hello/index.html点击提交按钮或者直接输入http://localhost:8080/hello/hello.do
 页面输出HelloWorldServlet
6. 注意
    ~浏览器地址栏输入的访问路径区分大小写,hello.do不能写成Hello.do
    ~访问的路径由 <url-pattern>指定
    ~ <url-pattern>中的/hello.do表示的是hello这个web应用下的hello.do
    ~表单中action="/hello.do"表示访问域名下的hello.do,所以应写出action="/hello/hello.do"或者action="hello.do"(相对index.html的路径)

七. Servlet的生命周期
1. 生命全过程
    ~加载 ClassLoader
    ~实例化 new
    ~初始化 init(ServletConfig)
    ~处理请求 service doGet doPost
    ~退出服务 destory()
2. 只有一个对象
3. API中的过程:
    ~init()  //只执行一次,第一次初始化的时候
    ~public void init(ServletConfig config) throws ServletException
    ~service()
    ~public void service(ServletRequest request,ServletResponse response) throws ServletException, java.io.IOException
    ~destory() //webapp 退出的时候
    ~public void destory()

八. 为什么有两个init()方法
1. void init(ServletConfig config): Called by the servlet container to indicate to a servlet that the servlet is being placed into service.
2. void init(): A convenience method which can be overriden so that there's no need to call super.init(config).
3. ServletConfig 用法示例
3.1 把以下内容copy到web.xml文件中的<servlet></servlet>标签内.
    <servlet>
        <servlet-name>hello</servlet-name>
        <servlet-class>HelloServlet</servlet-class>
        <init-param>
            <param-name>name</param-name>
   <param-value>翁子轩</param-value>
        </init-param>
        <init-param>
   <param-name>age</param-name>
        <param-value>23</param-value>
        </init-param>
    </servlet>
3.2 在HelloServlet.java文件的doGet方法体内添加如下代码:
 response.setContentType("text/html;charset=gbk");
 PrintWriter out = response.getWriter();
 String s = this.getServletConfig().getInitParameter("name");
 String s1 = new String(s.getBytes("ISO-8859-1"),"GBK");
 out.println("<html><head>HelloServlet</head><body>"+s1+"</body></html>");
 out.flush();
 out.close();
3.3 在浏览器中输入http://localhost:8080/hello/hello.do, 页面输出结果为“HelloServlet翁子轩”
3.4 要对配置文件中的参数进行遍历,把上面的代码改写如下:
 response.setContentType("text/html;charset=gbk");
 PrintWriter out = response.getWriter();
 Enumeration e = this.getServletConfig().getInitParameterNames();
 for(;e.hasMoreElements();) {
  String name = e.nextElement().toString();
  String value = this.getServletConfig().getInitParameter(name);
  value = new String(value.getBytes("ISO-8859-1"),"GBK");
  out.println(value);
 }
 out.flush();
 out.close();
 //页面输出结果为"23 翁子轩"

九. 从页面中获取参数
1. 解决参数提交的乱码问题
1.1 解决post方式提交内容的乱码,且一定要写在存取第一个参数之前
 request.setCharacterEncoding("GBK");
1.2 解决get方式提交内容的乱码。修改server.xml,把URIEncoding设定为"GBK",然后重启tomcat.
<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="GBK" />
1.3 从页面中获取参数
 request.getParameter("username");

十. Cookie
1. 服务器可以向客户端写内容
2. 只能是文本内容
3. 客户端可以阻止服务器写入
4. 只能拿自己webapp写入的东西
5. Cookie分为两种
    ~属于窗口/子窗口(放在内存中的)
    ~属于文本(有生命周期的)
6. 一个servlet/jsp设置的cookies能够被同一个路径下面或者路径下面的servlet/jsp读到(路径=URL)(路径!=真实文件路径)
7. 向客户端写入Cookie
 for(int i=0; i<3; i++) {
  Cookie cookie = new Cookie("Session-Cookie-"+i, "Cookie-Value-S"+i);
  response.addCookie(cookie);  //未设置生命周期的Cookie只存在于内存中

  cookie = new Cookie("Persistent-Conkie-"+i, "Cookie-Value-P"+i);
  cookie.setMaxAge(3600);  //设置Cookie的生命周期
  response.addCookie(cookie);
 }
8. 读取客户端的Cookie
 Cookie[] cookies = request.getCookies();
 if(cookies !=null) {
  Cookie cookie;
  for(int i=0; i<cookies.length; i++) {
   cookie = cookies[i];
   out.println(cookie.getName());
   out.println(cookie.getValue());
  }
 }

十一. Session
1. 服务器的一块内存(存key-value)
2. 和客户端窗口对应(子窗口)(独一无二)
3. 客户端和服务器有对应的SessionID
4. 客户端向服务器端发送SessionID的时候有两种方式:
    ~cookei(内存cookie)
    ~rewriten URL
 response.encodeURL(request.getRequestURL().toString())
5. 浏览器禁掉cookie, 就不能使用session(使用cookie实现的session)
6. 如果想安全的使用session(不论客户端是否禁止cookie). 只能使用URL重写(大大增加编程负担), 所以很多网站要求客户端打开cookie.
7. ServletContext: ServletContext application = this.getServletContext();

十二. Servlet连接Mysql数据库
1. 启动mysql,并在其中建立相应的数据库和表
2. 把jdbc的驱动复制到lib目录下(mysql-connector-java-3.1.13-bin.jar)
3.
 Connection conn = null;
 Statement stmt = null;
 ResultSet rs = null;
  
 response.setContentType("text/html");
 response.setCharacterEncoding("gb2312");
 PrintWriter out = response.getWriter();
  
 out.println("<table border=1>");
 out.println("<tr><td>Content:</td></tr>");
 try {
  Class.forName("com.mysql.jdbc.Driver");
  conn = DriverManager.getConnection("jdbc:mysql://localhost/bbs?user=root&password=12345678");
  stmt = conn.createStatement();
  rs = stmt.executeQuery("select * from article");
  while(rs.next()){
   out.println("<tr>");
   out.println("<td>" + rs.getString("cont") + "</td>");
   out.println("</tr>");
  }
  out.println("</table>");
 } catch (ClassNotFoundException e) {
  e.printStackTrace();
 } catch (SQLException e) {
  e.printStackTrace();
 } finally {
  try {
   if(rs != null) {
    rs.close();
    rs = null;
   }
   if(stmt != null) {
    stmt.close();
    stmt= null;
   }
   if(conn != null) {
    conn.close();
    conn = null;
   }
  } catch (SQLException e) {
   e.printStackTrace();
  }
 }
4. 注意:仔细检查连接串;确认有没有这个表;如果出错,先去后台看报错信息;确认mysql以及启动;把jdbc的驱动复制到lib目录下

十三. Servlet中使用javabean
1. 广义的javabean = 普通java类
    狭义的javabean = 符合Sun JavaBean标准的类
2. 在Servlet中使用Bean和在通常程序中使用Bean类似
    ~属性名称第一个字母必须小写,一般private
    ~一般具有getters and setters
    ~要具有一个参数为空的构造方法
    ~但Bean不应具有GUI表现
    ~一般是用来实现某一业务逻辑或取得特定结果

十四. JSP简介
1. JSP----Java Server Pages
2. 拥有servlet的特性与优点(本身就是一个servlet)
3. 直接在HTML中内嵌JSP代码
4. JSP程序由JSP Engine先将它转换Servlet代码,接着将它编译成类文件载入执行
5. 只有当客户端第一次请求JSP时,才需要将其转换、编译
6. 优点:
 ~性能优良----优于CGI, PHP, ASP
 ~平台无关性----操作系统无关,Web服务器无关
 ~可扩展性----tag的扩展机制,简化页面开发

十五. JSP编程----基本语法
1. JSP传统语法
1.1 Declaration
 ~基本语法:<%! %>
 ~说明:在此声明的变量、方法都会被保留成唯一的一份,直到JSP程序停止执行
 ~例如:
  <%!
   int i;
   public void setName() {... ...}
  %>
1.2 Scriptlet
 ~基本语法:<%程序代码区%>
 ~可以放入任何的Java程序代码
 ~例如:
  <%
   for(int i=0; i<10; i++) {... ...}
  %>
1.3 Expression
1.4 Comment
1.5 Directives
 ~Directive(编译指令)相当于在编译期间的命令
 ~格式:<%@Directive 属性="属性值"%>
 ~常见的Directive:
  page:
   $ 指明与JSP Container的沟通方式
   $ 基本格式:
    <%@page language="script language"
     extends="className"
     import="importList"
     buffer="none|kb size" ----none:不缓冲,默认8k
     session="true|false"  ----是否可以使用session,默认true
     autoFlush="true|false" ----缓冲器是否自动清除,默认true
     isThreadSafe="true|false" ----默认false(永远不要设成true)
     info="info Text"  ----任何字符
     errorPage="errorPageUrl"
     isErrorPage="true|false"
     contentType="contentTypeInfo"
     pageEncoding="gb2312"
    %>
  include
   $ 将指定的JSP程序或者HTML文件包含进来
   $ 格式:<%@include file="fileURL" %>
   $ JSP Engine会JSP程序的转换时期先把file属性设定的文件包含进来,然后开始执行转换及编译的工作。
      (原封不动的把文件的代码copy到该位置,然后进行转换和编译,只生成一个java和class)
   $ 限制:不能向fileURL中传递参数, 如不能abc.jsp?user=aaa
  taglib
1.6 Action动作指令
 ~Action(动作指令)在运行期间的命令
 ~常见的:
  jsp:useBean
   $ jsp:setProperty
   $ jsp:getProperty
  jsp:include
   $ <%@include和jsp:include的区别
   -------------------------------------------------------------------------------------------------------------------
   <%@include file="date.jsp"%> <jsp:include page="date.jsp" flush="true"
   -------------------------------------------------------------------------------------------------------------------
   include编译指令是在JSP程序的转换 而include指令在转换时期是不会被编译的,
   时期就将file属性所指定的程序内容 只有在客户端请求时期如果被执行到才会被
   嵌入,然后再编译执行  动态的编译载入
   -------------------------------------------------------------------------------------------------------------------
   只生成一个class文件   多个
   -------------------------------------------------------------------------------------------------------------------
   include不能带参数   <jsp:include>可以
   -------------------------------------------------------------------------------------------------------------------
   同一个request对象   不同的request对象,可以取得包含它的页面
       的参数,并添加了自己的参数
   -------------------------------------------------------------------------------------------------------------------
  jsp:forward
   $ jsp:param
   $ forward和sendredirect的区别
   -------------------------------------------------------------------------------------------------------------------
   Sendrediret   Forward
   -------------------------------------------------------------------------------------------------------------------
   是不同的request   虽然是不同的对象,但是可以取到上一个
       页面的内容
   -------------------------------------------------------------------------------------------------------------------
   send后的语句会继续执行,除非return farward后的语句不会继续发送给客户端
   -------------------------------------------------------------------------------------------------------------------
   速度慢    速度快
   -------------------------------------------------------------------------------------------------------------------
   需要到客户端的往返,可以转到任何页面 服务器内部转换
   -------------------------------------------------------------------------------------------------------------------
   地址栏有变化   地址栏没有变化
   -------------------------------------------------------------------------------------------------------------------
   可以传参数,直接写在url后面  可以传参数
   -------------------------------------------------------------------------------------------------------------------
   /代表的是http://127.0.0.1/  /代表的是http://127.0.0.1/hello,并且只能
       以/开头
   -------------------------------------------------------------------------------------------------------------------
  jsp:plugin
   $ 嵌入applet
1.7 内置对象
2. JSTL
3. JSF

十六. JSP中使用javabean
1. jsp:useBean各项参数含义
    ~id: 对象实例名称
    ~scope: Bean作用的范围,默认为page, 对整个jsp页面有效
    ~class: Bean类名称(全名)
    ~type: Bean实例类型,可以是本类,或其父类,或实现的接口,默认为本类
2. Scope各项参数的意义
    ~page: 仅涵盖使用JavaBean的页面
    ~request: 有效范围仅限于使用JavaBean的请求
    ~session: 有效范围在用户整个连接过程中(整个会话阶段均有效)
    ~application: 有效范围涵盖整个应用程序。也就是对整个网站均有效

十七. 乱码问题
1. 场合:页面本身有中文的时候
    解决办法:
 servlet: response.setContentType("text/html;charset=gbk");
 Jsp: <%@page contentType="text/html;charset=gb2312"%>
    注意:一定要写在PrintWriter out = response.getWriter(); 之前
2. 场合:解决get方式的乱码问题
    解决办法:修改server.xml------->URIEncoding="GBK"
3. 场合:解决post方式提交内容的乱码
    解决办法:request.setCharacterEncoding("GBK");
    注意:一定要写在存取第一个参数之前,不要调用response.setCharcterEncoding("GBK");
4. 场合:<jsp:param name="user" value="<%=s%>"/>, url地址包含中文参数
    解决办法:<%request.setCharacterEncoding("GBK");%>

你可能感兴趣的:(java,tomcat,Web,servlet,J2EE)