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>
密码:
<input type="password" name="password" size=20>
<br>
<input type="submit" name="submit" value="提交">
<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");%>
上一篇: Servlet获取初始化参数
下一篇: 不定长参数方法