Servlet初涉
Servlet简介
servlet是JavaEE的规范(接口)之一, 也是JavaWeb的三大组件之一;三大组件分别是Servlet程序、Filter过滤器、Listener监听器。
Servlet是运行在服务器上的一个Java小程序,它可以接收客户端发送过来的请求,并相应数据给客户端。
实现Servlet程序
-
编写一个类去实现servlet接口
创建一个类然后
implements Servlet并实现其方法(实际开发中不使用)创建一个类然后
extends HttpServlet去继承已经实现好的Servlet子类(实际使用) -
实现service方法处理请求并响应数据
-
在
web.xml中去配置servlet程序的访问地址要在
web.xml中配置两个标签servlet和servlet-mapping1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<!-- servlet标签给Tomcat配置Servlet程序 -->
<servlet>
<!-- servlet-name标签:给Servlet程序其一个别名(一般设定为类名) -->
<servlet-name>HelloServlet</servlet-name>
<!-- servlet-class是servlet程序的全类名 -->
<servlet-class>com.example.tomcat_web.HelloServlet</servlet-class>
</servlet>
<!-- servlet-mapping标签给servlet程序配置访问地址 -->
<servlet-mapping>
<!-- servlet-name标签的作用是表明这个标签是为哪一个servlet程序配置的 -->
<servlet-name>HelloServlet</servlet-name>
<!-- url-pattern标签配置访问地址表明在工程路径下的访问地址 -->
<url-pattern>/hello</url-pattern>
</servlet-mapping>
Servlet的生命周期
- 执行Servlet构造方法
- 执行
init()初始化 - 执行
service()方法 - 执行
destory()销毁方法
1~2步创建服务时调用,3步每次访问都会调用,4步结束服务时调用
获取访问类型
使用service()方法中类型为ServletRequest的参数
1 |
|
通过继承HTTPServlet实现Servlet程序
- 编写一个类去继承HttpServlet类
- 根据需要重写
doGet()或doPost()方法和其他 - 同样需要配置
web.xml
直接使用IDEA创建Servlet程序
在需要创建servlet程序的包上New -> Servlet程序即可实现自动配置
一般取消创建Java EE6+ 注解类选项,完成后只需要在web.xml中配置servlet-mapping即可
Servlet类的继承体系
ServletConfig类
从类名上看显然该类与Servlet程序的配置有关
ServletConfig类的三大作用:
-
获取Servlet程序的别名即
web.xml中servlet-name的值1
2
3
4
5
6
7
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取Servlet别名
String servletName = config.getServletName();
} -
获取初始化参数
init-param初始化参数是在
web.xml中配置的,需要在对应的servlet标签下配置,可以配置多组1
2
3
4
5
6
7
8
9
10
11
12
13
14
15<!-- servlet标签给Tomcat配置Servlet程序 -->
<servlet>
<!-- servlet-name标签:给Servlet程序其一个别名(一般设定为类名) -->
<servlet-name>HelloServlet</servlet-name>
<!-- servlet-class是servlet程序的全类名 -->
<servlet-class>com.example.tomcat_web.HelloServlet</servlet-class>
<!--init-param是初始化参数-->
<init-param>
<!--参数名-->
<param-name>username</param-name>
<!--参数值-->
<param-value>root</param-value>
</init-param>
</servlet>然后在对应的类中就可获取这个初始化参数
1
2
3
4
5
6
7
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取初始参数
String initParameter = config.getInitParameter("username");
} -
获取
ServletContext对象1
2
3
4
5
6
7
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取ServletContext对象
ServletContext servletContext = config.getServletContext();
}
注意:当我们需要重写继承自HTTPServlet的类的
init()方法时,一定要在方法内加入这段代码super.init(config);,表示向父类传递类型为ServletConfig的servlet配置对象,原因是HttpServlet的父类GenericServlet需要使用到了这个参数并且保存了它的值
ServletContext类
- ServletContex是一个接口,表示Servlet上下文对象
- 一个Web工程只有一个ServletContext对象实例
- ServletContext对象是一个域对象
- ServletContext是在web工程部署启动的时候创建,在web工程停止的时候销毁的
注:域对象是可以像Map一样存取数据的对象,这里的域是指存取数据的操作范围(整个Web工程)
| 存数据 | 取数据 | 删除数据 | |
|---|---|---|---|
| Map | put() | get() | remove() |
| 域对象 | setAttribute() | getAttribute() | removeAttribute() |
ServletContext类的作用:
-
获取
web.xml中配置的上下文参数 context-param先在
web.xml中配置上下文参数,同样可以根据需要配置多组但是这里配置的参数所有在该web工程下的类都能通过ServletContext访问即属于整个web工程1
2
3
4
5<!-- 这里的context-param标签是上下文参数标签,属于整个web项目 -->
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>然后就可以通过
ServletContext类获取到这些参数1
2
3
4
5
6
7
8
9
10
11
12
13
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取初始参数
String initParameter1 = config.getInitParameter("username");
//获取ServletContext对象
ServletContext servletContext = config.getServletContext();
//获取上下文参数
String initParameter2 = servletContext.getInitParameter("username");
}这里把通过
ServletConfig对象实例获取得到的初始化参数与通过Servletcontext对象实例获取得到的初始化参数同时放在了一起,这里需要注意的是通过ServletConfig获取的初始化参数是在web.xml中专门为当前类配置的初始化参数,而通过ServletContext获取的是属于整个web工程的初始化参数 -
获取当前的工程路径(格式为:
/工程路径)1
2
3
4
5
6
7
8
9
10
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取ServletContext对象
ServletContext servletContext = config.getServletContext();
//获取当前工程路径
String contextPath = servletContext.getContextPath();
} -
获取工程部署后在服务器磁盘上的绝对路径
1
2
3
4
5
6
7
8
9
10
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取ServletContext对象
ServletContext servletContext = config.getServletContext();
//获取当前工程的绝对路径
String realPath = servletContext.getRealPath("/");
}这里的在函数中传入的参数
/是被解析为当前工程工程路径,传入getRealPath()方法后获取得到了该web项目部署在服务器上是绝对路径 -
像Map一样存储数据
1
2
3
4
5
6
7
8
9
10
11@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
//获取ServletContext对象
ServletContext servletContext = config.getServletContext();
//像Map一样存储数据
servletContext.setAttribute("name", "Object");
servletContext.getAttribute("name");
}
Servlet处理Http请求
-
Get请求
请求行:
(1) 请求方式 GET
(2) 请求的资源路径
(3) 请求的协议及其版本号
请求头:
(1) 由key : value 键值对组成,不同键值对代表不同的含义
-
Post请求
请求行:
(1) 请求方式 POST
(2) 请求的资源路径
(3) 请求的协议及其版本号
请求头:
(1)同样是由key : value键值对组成,不同键值对由不同的含义
(2) 空行
请求体:
发给服务器的内容
-
http响应
响应行:
(1) 响应的协议和版本号
(2) 响应状态码
(3) 响应状态描述符
响应头:
(1) 还是由key : value键值对组成,不同键值对由不同的含义
(2) 空行
响应体:
回传给用户的数据
MIME类型说明
MIME(Multipurpose Internet Mail Extensions)多用途互联网邮件扩展类型,用于支持非ASCLL编码的内容传输,其格式为“大类型/小类型”
用于WAP服务器的MIME类型有:
| 类型 | 描述 | 典型示例 |
|---|---|---|
text |
表明文件是普通文本,理论上是人类可读 | text/plain, text/html, text/css, text/javascript |
image |
表明是某种图像。不包括视频,但是动态图(比如动态gif)也使用image类型 | image/gif, image/png, image/jpeg, image/bmp, image/webp, image/x-icon, image/vnd.microsoft.icon |
audio |
表明是某种音频文件 | audio/midi, audio/mpeg, audio/webm, audio/ogg, audio/wav |
video |
表明是某种视频文件 | video/webm, video/ogg |
application |
表明是某种二进制数据 | application/octet-stream, application/pkcs12, application/vnd.mspowerpoint, application/xhtml+xml, application/xml, application/pdf |
HttpServletRequest类
作用:将对Tomcat服务器的Http请求封装到HttpServletRequest对象中,然后传递给service方法(doGet和doPost),我们通过这个对象的访问就可以实现获取请求中的信息的功能。
-
获取请求的统一资源标识符(URI)和统一资源定位符(URL)
getRequestURI()和getRequestURL()1
2
3
4
5
6
7
8
9
10public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>"+ "URI\t:" + request.getRequestURI() + "</h1>");
out.println("<h1>"+ "URL\t:" + request.getRequestURL() + "</h1>");
out.println("</body></html>");
} -
获取请求发送的IP地址
getRemoteHost()1
2
3
4
5
6
7
8
9public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h1>"+ "IP_Host\t:" + request.getRemoteHost() + "</h1>");
out.println("</body></html>");
} -
获取请求头
getHeader(String s)1
2
3
4
5
6
7
8
9
10public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
//获取请求头中的用户代理信息
out.println("<h1>"+ "User-Agent\t:" + request.getHeader("User-Agent") + "</h1>");
out.println("</body></html>");
} -
获取请求类型(前面有提到)
getMethod()1
2
3
4
5
6
7
8
9public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
out.println("<h3>"+ "Method\t:" + request.getMethod() + "</h3>");
out.println("</body></html>");
} -
获取请求参数
getParameter(String s)和getParameterValues(String s)先写一个简单的HTML表单文件
1
2
3
4
5
6
7
8
9
10
11<body>
<!--action:填写你的表单需要提交到的地址 也就是你服务器页面的访问地址-->
<form action="http://localhost:8080/Tomcat_web_war/hello" method="get">
用户名:<input type="text" name="username"><br/>
密码:<input type="password" name="password"><br/>
兴趣爱好:<input type="checkbox" name="hobby" value="cpp">C++
<input type="checkbox" name="hobby" value="java">Java
<input type="checkbox" name="hobby" value="js">JavaScript<br/>
<input type="submit">
</form>
</body>然后在接受到请求参数的文件中就可以获取到请求参数啦
1
2
3
4
5
6
7
8
9
10
11
12
13public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/html");
// Hello
PrintWriter out = response.getWriter();
out.println("<html><body>");
//获取请求参数
out.println("<h3>"+ "username\t:" + request.getParameter("username") + "</h3>");
out.println("<h3>"+ "password\t:" + request.getParameter("password") + "</h3>");
out.println("<h3>"+ "hobby\t:" + request.getParameter("hobby") + "</h3>");
out.println("<h3>"+ "hobbys\t:" + Arrays.asList(request.getParameterValues("hobby"))+ "</h3>");
out.println("</body></html>");
} -
设置请求参数的编码(解析)格式为
UTF-8避免中文乱码1
request.setCharacterEncoding("UTF-8");
注意这个函数必须在使用这个对象前就调用,否则是不会生效的
请求的转发
请求转发简单说就是一个servlet程序调用另一个servlet程序共同完成一项请求
-
在本程序中处理请求数据
1
out.println("<h2>"+ "Hello1" + "</h2>");
-
可以在原有的请求中添加一些请求参数,例如标识这个请求是经过本程序处理过的(从降低耦合的角度上来看这个例子似乎不太合适)
1
request.setAttribute("httpResponse", out);
-
创建请求的调度对象(另一个程序的入口),然后传参并在另一个程序中对请求进行进一步的处理
1
2RequestDispatcher requestDispatcher = request.getRequestDispatcher("/hello2");
requestDispatcher.forward(request, response);同样的这里的
getRequestDispatcher中传的参数仍然是工程路径 -
可以通过请求转发到
WEB_INF目录下的程序进行处理
HttpServletResponse类
作用:返回给客户端的信息可以通过HttpServletResponse实例来进行设置
两种输出流:
| 类型 | 方法 | 作用 |
|---|---|---|
| 字节流 | getOutputStream() |
常用于下载(传递二进制数据) |
| 字符流 | getWriter() |
常用于回传字符串信息 |
两个流只能同时使用一个,否则会抛出异常
例如我们在前面就用到了的out对象就是一个字符流对象
1 | request.setCharacterEncoding("UTF-8"); |
这里先设置了响应的字符编码(需要浏览器也支持)和响应头的相应的内容类型(MIME)
也可以这样直接修改相应头修改相应内容的编码形式
1 | response.setContentType("text/html; charset=UTF-8"); |
同样需要注意的是要在使用这个response对象之前调用
请求重定向
方法1:
-
设置相应状态码302表示重定向
1
response.setStatus(302);
-
设置响应头说明重定向的目的地址
1
response.setHeader("Location", "http://localhost:8080");
方法2:(推荐)
1 | response.sendRedirect("http://localhost:8080"); |








