Servlet

Servlet概述

Java Servlet(服务小程序),生成动态的web内容
Servlet运行于支持Java的web应用服务器中

1.导入jar包.在/Library/Tomcat/lib/servlet-api.jar
2.创建一个类,实现servlet接口
3.配置web.xml

web.xml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?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-name>HelloServlet</servlet-name>
<servlet-class>me.cscar.network.servlet.HelloServlet</servlet-class>
<!-- 初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>
</servlet>
<!-- 映射 -->
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>

一个实现servlet接口的类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package me.cscar.network.servlet;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import java.io.IOException;

public class HelloServlet implements javax.servlet.Servlet{

@Override
public void init(ServletConfig servletConfig) throws ServletException {

}

@Override
public ServletConfig getServletConfig() {
return null;
}

@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("success");
}

@Override
public String getServletInfo() {
return null;
}

@Override
public void destroy() {

}
}

servlet的生命周期

1.创建对象
2.初始化
3.执行操作
4.销毁

整个生命周期的过程都是用Tomcat来管理调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
//初始化方法
public void init(ServletConfig servletConfig) throws ServletException {
}

//获取当前servlet的配置信息
public ServletConfig getServletConfig() {
return null;
}

//执行操作的方法
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
}

//返回作者,版权信息,版本信息
public String getServletInfo() {
return null;
}

//销毁方法
public void destroy() {
}

注意:
在servlet整个生命周期中,都是单例的.
servlet的构造器必须是公共无参数构造器

servlet的请求流程

1.在当前项目的根路径下的WEB-INF目录中,读取web.xml文件
2.获取web.xml中所有的元素,判断是否存在标签里的资源名称,不存在返回404错误
3.根据/资源名称获取对应的servlet的全限定名.
4.根据获取到的全限定名,使用反射来调用构造器,创建对象

1
Object obj = Class.forName("全限定名").newInstance();

5.使用创建的servlet对象,调用init(config)方法.或者,从Tomcat中的servlet实例缓冲池中取出”全限定名”对应的对象,Servlet obj = …
6.创建ServletRequest对象,ServletResponse对象,再使用servlet对象调用service方法.

1
obj.service(req,resp)

7.在service方法中对客户端做响应操作

Servlet接口

配置web.xml初始化参数

1
2
3
4
5
<!-- 初始化参数 -->
<init-param>
<param-name>encoding</param-name>
<param-value>utf-8</param-value>
</init-param>

通过servlet对象获取参数

1
String encoding = obj.getInitParameter("encoding") //utf-8

获取所有的初始化参数名称

1
2
3
4
5
6
Enumeration<String> names = obj.getInitParameterNames(); //使用迭代器遍历
while (names.hasMoreElements()) {
String name = names.nextElement();
String value = config.getInitParameter(name);
System.out.println(name + ":" + value);
}

方法

1
2
3
4
String getServletName() //获取当前Servlet 的<servlet-name>中的内容
ServletContext getServletContext() //获取上下文对象,一个应用就只有一个上下文对象
String getInitParameter(String name) //获取指定名称的初始化参数值
Enumeration<String> getInitParameterNames() //获取所有的初始化参数的名称

Servlet的继承体系

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package me.cscar.network.servlet;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

public class HttpServletDemo extends HttpServlet {
@Override
public void init() throws ServletException {
System.out.println("自己的初始化代码");
}

@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("执行操作");
}
}

HttpServletRequest常用方法

常用方法 返回
req.getMethod() 请求方式(post,get)
req.getRequestURI 返回请求行中的资源名字部分
req.getRequestURL() 返回客户端请求的完整url
req.getContextPath() 获取当前项目的上下文路径path的值
req.getRemoteAddr() 发出请求的客户机ip地址
req.getHeader(“User-Agent”) 指定名称的头字段的值

获取表单请求参数

方法 返回
req.getParameter(“value”) 获取表单请求参数
getParameterValues(“hobby”) 指定名字参数的多个参数值。(复选框)
req.getParameterNames() 获取表单的所有参数名
req.getParameterMap() 把所有的表单数据保存在map中
getOutputStream() 获取字节输出流对象. ( 文件下载)
getWriter() 获取字符输出流对象
response.setContentType(“text/html;charset=utf-8”) 设置输出的MIME类型和编码方式
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//req.getMethod():返回请求方式
System.out.println(req.getMethod());
//req.getRequestURI:返回请求行中的资源名字部分
System.out.println(req.getRequestURI());
//返回客户端请求的完整url
System.out.println(req.getRequestURL());
//获取当前项目的上下文路径<context>path的值
System.out.println("ContextPath" + req.getContextPath());
//返回发出请求的客户机ip地址
System.out.println(req.getRemoteAddr());
//返回指定名称的头字段的值
System.out.println(req.getHeader("User-Agent"));

//设置编码
req.setCharacterEncoding("UTF-8");


System.out.println("name:" + req.getParameter("username"));
System.out.println("password:" + req.getParameter("psw"));
//获取表单中的多个数据
String[] values = req.getParameterValues("hobby");
System.out.println(Arrays.toString(values));
//获取表单的所有参数名
Enumeration<String> names = req.getParameterNames();
while (names.hasMoreElements()) {
String name = names.nextElement();
System.out.println(name);
}
//把所有的表单数据保存在map中
Map<String, String[]> map = req.getParameterMap();
Set<Map.Entry<String, String[]>> entrySet = map.entrySet();
for (Map.Entry<String, String[]> entry : entrySet) {
String name = entry.getKey();
String[] value = entry.getValue();
System.out.println(name + ":" + Arrays.toString(value));
}

JSP的原理

流程:

1.所有的jsp,jspx的访问都交给JspServlet来处理
2.把jsp文件转化为java文件
3.把所有java文件都转化为字节码文件
4.把转化的文件存放在tomcat/work/…文件下

体系:

HttpServlet <- HttpJspBase <- myDemo_jsp
jsp就是一个Servlet
在java文件中

1
2
3
out.write("");
...
out.print(...);

存在字符输出流对象,输出了html

jsp语法:

1
2
3
4
5
6
7
8
9
<%!
Java代码
%>

<%-- 注释,不会编译到servlet中 --%>

<%=
表达式(调用out.print,输出到页面上)
%>

JSP 三大指令

  1. page
  2. include
  3. taglib

page指令:
作用:定义JSP页面的各种属性

属性:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
language:指示JSP页面中使用脚本语言。默认值java,目前只支持java。
extends:指示JSP对应的Servlet类的父类。不要修改。
*import:导入JSP中的Java脚本使用到的类或包。(如同Java中的import语句)
JSP引擎自动导入以下包中的类: javax.servlet.* javax.servlet.http.* javax.servlet.jsp.*
注意:一个import属性可以导入多个包,用逗号分隔。
*sessioin:指示JSP页面是否创建HttpSession对象。默认值是true,创建
*buffer:指示JSP用的输出流的缓存大小.默认值是8Kb。

autoFlush:自动刷新输出流的缓存。
isThreadSafe:指示页面是否是线程安全的(过时的)。默认是true
true:不安全的。
false:安全的。指示JSP对应的Servlet实现SingleThreadModel接口。
*errorPage: 指示当前页面出错后转向(转发)的页面。
目标页面如果以"/"(当前应用)就是绝对路径。

配置全局错误提示页面:

web.xml
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/error.jsp</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>

*isErrorPage:指示当前页面是否产生Exception对象。
*contentType:指定当前页面的MIME类型。作用与Servlet中的response.setContentType()作用完全一致
*pageEncoding:通知引擎读取JSP时采用的编码(因为要翻译)
还有contentType属性的作用。
*isELIgnored:是否忽略EL表达式。${1+1}。默认值是false
page指令最简单的使用方式:<%@ page pageEncoding="UTF-8"%>

2.include(静态包含,开发中能用静的不用动的)
作用:包含其他的组件。
语法:<%@include file=""%>file指定要包含的目标组件。路径如果以"/"(当前应用)就是绝对路径。
原理:把目标组件的内容加到源组件中,输出结果。

动态包含:
采用动作元素:<jsp:include page=""/>路径如果以"/"(当前应用)就是绝对路径。


3.taglib
作用:引入外部的标签
语法
<%@ taglib uri="标签名称空间" prefix="前缀"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>