目录
- 一、Servlet 是什么?
- 二、Servlet 任务
- 三、第一个Servlet程序
- 1、在MyEclipse里创建一个web工程(ServletTest)
- 2、创建com.XXX.servlet包,包下创建HelloServlet.java class文件
- 3、编写web.xml
- 4、然后开启tomcat服务,
- 5、访问 http://localhost:8080/ServletTest/hello,页面空白看控制台可见“servlet被访问了!”语句,
- 四、servlet的生命周期
- 五、Servlet的请求分发处理
- 六、通过继承HttpServlet实现Servlet程序
- 1、创建一个类HelloServlet02.java继承HttpServlet
- 2、web.xml中添加
- 3、index.jsp的路径修改为
- 4、运行http://localhost:8080/ServletTest/index.jsp,点击提交后看控制台打印出表单的请求方式。
- 七、Servlet整体类继承关系
- ServletConfig类
- Servletcontext类
- 八、Http协议
- 1、什么是HTTP协议?
- 2、请求的HTTP协议格式
- GET请求
- 1、请求行
- (1)请求的方式 GET
- (2)请求的资源路径[+?+请求参数]
- (3)请求的协议的版本号 HTTP/1.1
- 2、请求头 key : value 组成不同的键值对,表示不同的含义。
- POST请求
- 1、请求行
- 2、请求头
- 3、响应的HTTP协议格式
- 1、响应行
- 2、响应头
- 3、响应体 ----->>就是回传给客户端的数据
- 4、常用的响应码说明
- 5、MIME类型说明
- 九、HttpServletRequest类
- 1、HttpServletRequest类有什么作用。
- 2、HttpServletRequest类的常用方法
- 3、请求的转发
- 4、Web中的相对路径和绝对路径
- 5、web中"/"斜杠的不同意义
- 十、HttpServletResponse类
- 1、HttpServletResponse类的作用
- 2、两个输出流的说明。
- 3、解决响应中文乱码的问题
- (1)方案一
- (2)、方案二
- 十一、请求重定向
三大组件分别是:Servlet程序、Listener监听器、Filter过滤器
一、Servlet 是什么?
Servlet是JavaEE规范之一。规范就是接口
Java Servlet 是运行在 Web 服务器或应用服务器上的 java程序,它可以接收客户端发送过来的请求,并响应数据给客户端
(它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。)
1、Tomcat 服务器
目前非常流行的Tomcat服务器是Apache-Jarkarta开源项目中的一个子项目,是一个小型、轻 量级的支持JSP和Servlet 技术的Web服务器,也是初学者学习开发JSP应用的首选。
2、Resin 服务器
Resin是Caucho公司的产品,是一个非常流行的支持Servlet和JSP的服务器,速度非常快。Resin本身包含了一个支持HTML的Web服务器,这使它不仅可以显示动态内容,而且显示静态内容的能力也毫不逊色,因此许多网站都是使用Resin服务器构建
3、JBoss服务器
JBoss是一个种遵从JavaEE规范的、开放源代码的、纯Java的EJB服务器,对于J2EE有很好的支持。JBoss采用JML API实现软件模块的集成与管理,其核心服务又是提供EJB服务器,不包含Servlet和JSP的Web容器,不过它可以和Tomcat完美结合
4、WebSphere 服务器
WebSphere是IBM公司的产品,可进一步细分为 WebSphere Performance Pack、Cache Manager 和WebSphere Application Server等系列,其中WebSphere Application Server 是基于Java 的应用环境,可以运行于 Sun Solaris、Windows NT 等多种操作系统平台,用于建立、部署和管理Internet和Intranet Web应用程序。
5、WebLogic 服务器
WebLogic 是BEA公司的产品(现在已经被Oracle收购),可进一步细分为 WebLogic Server、WebLogic Enterprise 和 WebLogic Portal 等系列,其中 WebLogic Server 的功能特别强大。WebLogic 支持企业级的、多层次的和完全分布式的Web应用,并且服务器的配置简单、界面友好。对于那些正在寻求能够提供Java平台所拥有的一切应用服务器的用户来说,WebLogic是一个十分理想的选择。
使用 Servlet,您可以收集来自网页表单的用户输入,呈现来自数据库或者其他源的记录,还可以动态创建网页。
Java Servlet 通常情况下与使用 CGI(Common Gateway Interface,公共网关接口)实现的程序可以达到异曲同工的效果。但是相比于 CGI,Servlet 有以下几点优势:
- 性能明显更好。
- Servlet 在 Web 服务器的地址空间内执行。这样它就没有必要再创建一个单独的进程来处理每个客户端请求。
- Servlet 是独立于平台的,因为它们是用 Java 编写的。
- 服务器上的 Java 安全管理器执行了一系列限制,以保护服务器计算机上的资源。因此,Servlet 是可信的。
- Java 类库的全部功能对 Servlet 来说都是可用的。它可以通过 sockets 和 RMI 机制与applets、数据库或其他软件进行交互。
二、Servlet 任务
Servlet 执行以下主要任务:
- 读取客户端(浏览器)发送的显式的数据。
这包括网页上的 HTML 表单,或者也可以是来自 applet 或自定义的 HTTP客户端程序的表单。
- 读取客户端(浏览器)发送的隐式的 HTTP 请求数据。
这包括 cookies、媒体类型和浏览器能理解的压缩格式等等。
- 处理数据并生成结果。
这个过程可能需要访问数据库,执行 RMI 或 CORBA 调用,调用 Web 服务,或者直接计算得出对应的响应。
- 发送显式的数据(即文档)到客户端(浏览器)。
该文档的格式可以是多种多样的,包括文本文件(HTML 或 XML)、二进制文件(GIF 图像)、Excel 等。
- 发送隐式的 HTTP 响应到客户端(浏览器)。
这包括告诉浏览器或其他客户端被返回的文档类型(例如 HTML),设置 cookies和缓存参数,以及其他类似的任务。
javaee api(英文文档)
https://docs.oracle.com/javaee/7/api/toc.htm
三、第一个Servlet程序
1、在MyEclipse里创建一个web工程(ServletTest)
点击两次next,然后打钩生成web.xml文件。
2、创建com.XXX.servlet包,包下创建HelloServlet.java class文件
然后类实现Servlet接口,并且实现其方法
代码如下
package com.atdyq.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServlet implements Servlet {
/*
* 三种情况导致destroy(销毁的意思)的调用:
1.reload 该servlet(webApps)
2.关闭tomcat
3.关机
* 销毁servt实例 实际就是释放内存
*/
@Override
public void destroy() {
}
//返回对象,其中包含此服器的初始化和启动参数。
@Override
public ServletConfig getServletConfig() {
return null;
}
//返回有关服务器的信息,如作者、版本和版权。
@Override
public String getServletInfo() {
return null;
}
//该函数用于初始化该servlet(类似于类的构造函数)
//该函数只会被调用一次(当用户第一次访问该servlet是被调用)
@Override
public void init(ServletConfig arg0) throws ServletException {
}
/*service方法是专门用来处理请求和响应的
* 这个函数用于处理业务逻辑
程序员应当那个当业务逻辑逻辑代码写在这里
当用户访问servlet时都会被调用
req用于获得客户端的信息
res用户想客户端返回信息 (可以认为是游览器)
*/
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("servlet被访问了!");//控制台输出语句
}
}
3、编写web.xml
<?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>com.atdyq.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
4、然后开启tomcat服务,
选择你的tomcat
随后在server运行
5、访问 http://localhost:8080/ServletTest/hello,页面空白看控制台可见“servlet被访问了!”语句,
四、servlet的生命周期
servlet的生命周期就是从servlet出现到销毁的全过程。
加载类—>实例化(为对象分配空间)—>初始化(为对象的属性赋值)—>请求处理(服务阶段)—>销毁
修改代码:
package com.atdyq.servlet;
import java.io.IOException;
import javax.servlet.Servlet;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
public class HelloServlet implements Servlet {
//返回对象,其中包含此服器的初始化和启动参数。
@Override
public ServletConfig getServletConfig() {
return null;
}
//返回有关服务器的信息,如作者、版本和版权。
@Override
public String getServletInfo() {
return null;
}
public HelloServlet(){
System.out.println("1、构造器方法");
}
//该函数用于初始化该servlet(类似于类的构造函数)
//该函数只会被调用一次(当用户第一次访问该servlet是被调用)
@Override
public void init(ServletConfig arg0) throws ServletException {
System.out.println("2.初始化");
}
/*service方法是专门用来处理请求和响应的
* 这个函数用于处理业务逻辑
程序员应当那个当业务逻辑逻辑代码写在这里
当用户访问servlet时都会被调用
req用于获得客户端的信息
res用户想客户端返回信息 (可以认为是游览器)
*/
@Override
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
System.out.println("3.servlet被访问了!");//控制台输出语句
}
/*
* 三种情况导致destroy(销毁的意思)的调用:
1.reload 该servlet(webApps)
2.关闭tomcat
3.关机
* 销毁servt实例 实际就是释放内存
*/
@Override
public void destroy() {
System.out.println("4、被销毁了");
}
}
1、执行 servet构造器方法
2、执行 init初始化方法
第一、二步,是在第一次访问,的时候创建serviet程序会调用。
3、执行 service方法
第三步,每次访问都会调用。
4、执行destroy销毁方法(只有你停止服务时才会调用到)
发现一直未调用到destroy方法,停止tomcat服务就会执行
五、Servlet的请求分发处理
service() 方法是执行实际任务的主要方法。Servlet 容器(即 Web 服务器)调用 service() 方法来处理来自客户端(浏览器)的请求,并把格式化的响应写回给客户端。
每次服务器接收到一个 Servlet 请求时,服务器会产生一个新的线程并调用服务。service() 方法检查 HTTP 请求类型(GET、POST、PUT、DELETE 等),并在适当的时候调用 doGet、doPost、doPut,doDelete 等方法。
HTTP定义了与服务器交互的不同方法,最常用的有4种,Get、Post、Put、Delete,如果我换一下顺序就好记了,Put(增),Delete(删),Post(改),Get(查),即增删改查,下面简单叙述一下:
1)Get,它用于获取信息,注意,他只是获取、查询数据,也就是说它不会修改服务器上的数据,从这点来讲,它是数据安全的,而稍后会提到的Post它是可以修改数据的,所以这也是两者差别之一了。
2)Post,它是可以向服务器发送修改请求,从而修改服务器的,比方说,我们要在论坛上回贴、在博客上评论,这就要用到Post了,当然它也是可以仅仅获取数据的。
3)Delete 删除数据。可以通过Get/Post来实现。
4)Put,增加、放置数据,可以通过Get/Post来实现。
doGet() 和 doPost() 方法是每次服务请求中最常用的方法。
doGet() 方法
GET 请求来自于一个 URL 的正常请求,或者来自于一个未指定 METHOD 的 HTML 表单,它由 doGet() 方法处理。
public void doGet(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
doPost() 方法
POST 请求来自于一个特别指定了 METHOD 为 POST 的 HTML 表单,它由 doPost() 方法处理。
public void doPost(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException {
// Servlet 代码
}
下面我们来看一下对doget() 和dopost()方法的调用
在index.jsp里创建一个表单,action为转向地址
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
</head>
<body>
<form action="http://localhost:8080/ServletTest/hello" method="post">
<input type="submit">
</form>
<br>
</body>
</html>
修改HelloServlet.java 文件的service方法
@Override
public void service(ServletRequest reqServletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3.servlet被访问了!");//控制台输出语句
//类型转换
HttpServletRequest httpServletRequest =(HttpServletRequest) reqServletRequest;
//获取请求方式
String method = httpServletRequest.getMethod();
if("GET".equals(method)){
doGet();
}else if("POST".equals(method)){
doPost();
}
}
public void doGet(){
System.out.println("get请求");
}
public void doPost(){
System.out.println("post请求");
}
随后开启tomcat,运行网址:http://localhost:8080/ServletTest/index.jsp
查看控制台可见,表单的请求方法(你可以修改index.jsp里的method的方法改为get,即可看见请求方式转为get)
六、通过继承HttpServlet实现Servlet程序
1、创建一个类HelloServlet02.java继承HttpServlet
package com.atdyq.servlet;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class HelloServlet02 extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
System.out.println("get请求触发");
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
System.out.println("post请求触发");
}
}
2、web.xml中添加
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.atdyq.servlet.HelloServlet02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
3、index.jsp的路径修改为
<body>
<form action="http://localhost:8080/ServletTest/hello2" method="post">
<input type="submit">
</form>
4、运行http://localhost:8080/ServletTest/index.jsp,点击提交后看控制台打印出表单的请求方式。
七、Servlet整体类继承关系
Servlet接口,只是负责定义Servlet程序的访问规范。
GenericServlet类实现了Servlet接口。做了很多空实现。
并持有一个ServletConfig类的引用。并对ServletConfig的使用做一些方法。
ServletConfig类
而ServletConfig类,从类名上来看,就知道是servlet程序的配置信息类。
他主要有三大作用:
1,可以获取Servlet程序的别名servlet-name的值
2,获取初始化参数init-param
在web.xml中增加参数
HelloServlet02中加入初始化方法
运行得到参数值
3,获取Servletcontext类对象
1、ServletContext是一个接口,它表示Servlet上下文对象
2、一个web工程,只有一个ServletContext对象实例。
3、Servletcontext对象是一个域对象。
4、ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁。|
什么是域对象?
域对象,是可以像 Map一样存取数据的对象,叫域对象。
这里的域指的是存取数据的操作范围。
Servletcontext类
Servletcontext类的四大作用:
1、获取web.xml中配置的上下文参数context-param
2、获取当前的工程路径,格式:/工程路径
3、获取工程部署后在服务器硬盘上的绝对路径
4、像 Map一样存取数据
web.xml中配置的上下文参数context-param
HelloServlet02增加代码:
运行控制台输出结果
创建contextServlet1,contextServlet2类
package com.atdyq.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class contextServlet1 extends HttpServlet{
//4、像 Map一样存取数据
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = getServletContext();
context.setAttribute("key1", "value1");
context.setAttribute("key2", "99");
System.out.println("Context1 中获取域数据key1的值是:"+context.getAttribute("key1"));
System.out.println("Context1 中获取域数据key2的值是:"+context.getAttribute("key2"));
}
}
package com.atdyq.servlet;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class contextServlet2 extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//获取ServletContext对象
ServletContext context = getServletContext();
System.out.println("Context2中获取域数据key1的值是:"+context.getAttribute("key1"));
System.out.println("Context2中获取域数据key2的值是:"+context.getAttribute("key2"));
}
}
web.xml里增加别名
<servlet>
<servlet-name>contextServlet1</servlet-name>
<servlet-class>com.atdyq.servlet.contextServlet1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>contextServlet1</servlet-name>
<url-pattern>/context1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>contextServlet2</servlet-name>
<servlet-class>com.atdyq.servlet.contextServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>contextServlet2</servlet-name>
<url-pattern>/context2</url-pattern>
</servlet-mapping>
先运行context1再运行context2,不然直接运行context2 获取数据为空
http://localhost:8080/ServletTest/context1
得到结果:
然后执行
http://localhost:8080/ServletTest/context2
也得到结果
这是以为一个web工程只有一个上下文,只要赋值后,其他也可以调用。
八、Http协议
1、什么是HTTP协议?
协议是指双方,或多方,相互约定好,大家都需要遵守的规则,叫协议。
所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP协议。
HTTP协议中的数据又叫报文。
2、请求的HTTP协议格式
客户端给服务器发送数据叫请求。服务器给客户端回传数据叫响应。
请求又分为GET请求,和POST请求两种
GET请求
1、请求行
(1)请求的方式 GET
(2)请求的资源路径[+?+请求参数]
(3)请求的协议的版本号 HTTP/1.1
2、请求头 key : value 组成不同的键值对,表示不同的含义。
POST请求
1、请求行
(1)请求的方式 POST
(2)请求的资源路轻[+?+请求参数]
(3)请求的协议的版本号 HTTP/1.1
2、请求头
(1) key : value 不同的请求头,有不同的含义
空行
3、请求体 ==>>>就是发送给服务器的数据
3、响应的HTTP协议格式
1、响应行
(1)响应的协议和版本号 HTTP/1.1
(2)响应状态码 200
(3)响应状态描述 ok
2、响应头
(1)key : value 不同的响应头,有其不同含义
3、响应体 ----->>就是回传给客户端的数据
4、常用的响应码说明
200 表示请求成功
302 表示请求重定向
404表示请求服务器已经收到了,但是你要的数据不存在〈请求地址错误〉
500表示服务器已经收到请求,但是服务器内部错误〈代码错误>
5、MIME类型说明
MIME是 HTTP协议中数据类型。
MIME的英文全称是""Multipurpose Internet Mall Extensions”多功能internet 邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
九、HttpServletRequest类
1、HttpServletRequest类有什么作用。
每次只要有请求进入Tomcat服务器,Tomcat服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法(
docet和doPost〉中给我们使用。我们可以通过 HttpservetRequest对象,获取到所有请求的信息。
2、HttpServletRequest类的常用方法
getRequestURI() | 获取请求的资源路径 |
getRequestURL() | 获取请求的统一资源定位符《绝对路径》 |
getRemoteHost() | 获取客户端的ip地址 |
getHeader() | 获取请求头 |
getParameter() | 获取请求的参数 |
getParameterValues() | 获取请求的参数《多个值的时候使用》 |
getMethod() | 获取请求的方式GET 或POST |
setAttribute(key , value); | 设置域数据 |
getAttribute(key ); | 获取域数据 |
getRequestDispatcher() | 获取请求转发对象 |
代码示例:
新建一个web文件ServletHttp
RequestAPIServlet类:
package cn.com.http;
import java.io.IOException;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class RequestAPIServlet extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
System.out.println(" 获取请求的资源路径URI =>"+request.getRequestURI());
System.out.println("客户端ip地址 =》"+request.getRemoteHost());
System.out.println("获取请求头 User-Agent=》"+request.getHeader("User-Agent"));
System.out.println("获取请求的参数 name的值 =》"+request.getParameter("name"));
System.out.println("获取请求的方式GET 或POST=>"+request.getMethod());
}
}
ParameterServlet类:
package cn.com.http;
import java.io.IOException;
import java.util.Arrays;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ParameterServlet extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//获取请求参数
System.out.println("用户名:"+request.getParameter("username"));
System.out.println("密码:"+request.getParameter("password"));
String[] hobby = request.getParameterValues("hobby");
System.out.println("爱好:"+Arrays.asList(hobby));
}
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//设置请求体的字符集为UTF-8,从而解决post请求的中文乱码问题
//也要在获取请求参数之前调用才有效
request.setCharacterEncoding("UTF-8");
//获取请求参数
System.out.println("用户名:"+request.getParameter("username"));
System.out.println("密码:"+request.getParameter("password"));
String[] hobby = request.getParameterValues("hobby");
System.out.println("爱好:"+Arrays.asList(hobby));
}
}
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>ServletHttp</display-name>
<servlet>
<servlet-name>RequestAPIServlet</servlet-name>
<servlet-class>cn.com.http.RequestAPIServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestAPIServlet</servlet-name>
<url-pattern>/requestAPIServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ParameterServlet</servlet-name>
<servlet-class>cn.com.http.ParameterServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ParameterServlet</servlet-name>
<url-pattern>/parameterServlet</url-pattern>
</servlet-mapping>
</web-app>
访问:http://localhost:8080/ServletHttp/requestAPIServlet?name=dialove
控制台结果输出:
获取请求的资源路径URI =>/ServletHttp/requestAPIServlet
客户端ip地址 =》0:0:0:0:0:0:0:1
获取请求头 User-Agent=》Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.72 Safari/537.36 Edg/89.0.774.45
获取请求的参数 name的值 =》dialove
获取请求的方式GET 或POST=>GET
访问:http://localhost:8080/ServletHttp/index.jsp
控制台输出:
用户名:diaolove
密码:3456
爱好:[cpp, java, js]
注意
post请求中文会导致乱码:
解决方法:
在使用request来获取post()请求中的参数时,先设置编码。
request.getParameter(“XXX”);
结果就不乱码了。
3、请求的转发
什么是请求的转发?
请求转发,是一种服务器的行为,当客户端请求到达后,服务器进行转发,此时会将请求对象进行保存,地址栏中的 URL 地址不会改变,得到响应后,服务器端再将响应发送给客户端,从始至终只有一个请求发出。
请求转发的特点:
1、浏览地社程没变化
2、他们是一次请求
3、他们共享Request域中的数据
4、可以转发到WEB-INF目录下的html文件
5、是否可以访问工程以外的资源(不能)
新建Servlet1和Servlet2类
package cn.com.http;
import java.io.IOException;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet1 extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//获取请求的参数(办事的材料)查看
String username = request.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料)"+username);
//给材料盖一个章,并传递至到Servlet2(柜台2)去查看
request.setAttribute("key", "柜台1盖章");
//问路:ServLet2(柜台2)怎么走
/*请求转发必须要以斜杠打头,/斜杠表示地址为:http://ip:port/工程名/,映射到TDEA代码的web目录pr
*/
RequestDispatcher requestDispatcher=request.getRequestDispatcher("/servlet2");
//走向SevLet2(柜台2)
requestDispatcher.forward(request,response);
}
}
Servlet2类:
package cn.com.http;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Servlet2 extends HttpServlet {
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//获取请求的参数(办事的材料)查看
String username = request.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料)"+username);
//查看柜台1是否有盖章
Object key1 = request.getAttribute( "key");
System.out.println("柜台1是否有章:"+ key1);
//处理自己的业务
System.out.println("Servlet2处理自己的业务");
}
}
在web.xml里配置路径
然后访问:
http://localhost:8080/ServletHttp/servlet1?username=0098 控制台输出
在Servlet1(柜台1)中查看参数(材料)0098
在Servlet2(柜台2)中查看参数(材料)0098
柜台1是否有章:柜台1盖章
Servlet2处理自己的业务
4、Web中的相对路径和绝对路径
在javaweb中,路径分为相对路径和绝对路径两种:
相对路径是:
“.” 表示当前目录
“…” 表示上一级目录
资源名 表示当前目录/资源名
绝对路径:
http://ip:port/工程路径/资源路径
5、web中"/"斜杠的不同意义
在web中/斜杠是一种绝对路径。
斜杠如果被浏览器解析,得到的地址是:http://ip:port/
<a href="/">斜杠</a>
/ 斜杠如果被服务器解析,得到的地址是: http://ip:port/工程路径
1、<ur1-pattern>/servlet1</ur1-pattern>
2、 servletcontext.getRealpath("*/");
3、request.getRequestDispatcher(“/");
特殊情况:response.sendRediect("/");把斜杠发送给浏览器解析。得到 http://ip:port/
十、HttpServletResponse类
1、HttpServletResponse类的作用
HttpServletResponse类和 HttpServletRequest类一样。每次请求进来,Tomcat服务器都会创建一个Response对象传递给Servlet程序去使用。HttpServletRequest表示请求过来的信息,
我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置。
2、两个输出流的说明。
字节流
getoutputstream(); 常用于下载(传递二进制数据)
字符流
getwriter(); 常用于回传字符串(常用)
两个流同时只能使用一个。
使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
比如我同时使用两个响应流时:
会报错:
3、解决响应中文乱码的问题
我们发现当服务响应时输出英文正常显示,而中文的时候输出就是乱码。
package cn.com.http;
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 ResponseIOServlet extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
PrintWriter writer = response.getWriter();
writer.write("respons's content!!!");
}
}
英文的正常输出:
改中文输出时浏览器就乱码
然后有两种解决方案
(1)方案一
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//要求: 往客户端回传字符串数据。
response.setCharacterEncoding("UTF-8");
PrintWriter writer = response.getWriter();
writer.write("响应成功!!");
}
然后发现加入UTF-8输出结果还是乱码,这是因为跟浏览器的字符编码不同,但当你改成GBK时就正常解析了,但是每个浏览器的编码方式也不一样每个浏览器都去修改就很麻烦,所以获取请求头的类型来设置。
获取请求头的类型来设置,字符编码方式。
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
response.setHeader("Content-Type", "text/html;charset=UTF-8");
PrintWriter writer = response.getWriter();
writer.write("响应成功!!");
}
然后就OK了。
(2)、方案二
用这句
response.setContentType(“text/html;charset=UTF-8”);
它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
注意:此方法一定要在获取流对象之前调用才有效
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
//它会同时设置服务器和客户端都使用UTF-8字符集,还设置了响应头
//此方法一定要在获取流对象之前调用才有效
response.setContentType("text/html;charset=UTF-8");
System.out.println(response.getCharacterEncoding());
PrintWriter writer = response.getWriter();
writer.write("响应成功!!");
}
十一、请求重定向
请求重定向,是指客户端给服务器发请求,然后服务器告诉客户端说。我给你一些地址。你去新地址访问。叫请求重定向(因为之前的地址可能已经被废弃)。
创建两个Response类
Response1:
package cn.com.http;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class Response1 extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
System.out.println("欢迎你!");
//设置响应状态码302,表示已搬迁
response.setStatus(302);
//设置响应头,说明新的地址在哪里
response.setHeader("localhost","http://localhost:8080/ServletHttp/response2");
}
}
Response2
package cn.com.http;
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 Response2 extends HttpServlet{
public void doGet(HttpServletRequest request,HttpServletResponse response)throws ServletException, IOException {
response.getWriter().write("response2's result!");
}
}
访问:http://localhost:8080/ServletHttp/response1
会重定向到http://localhost:8080/ServletHttp/response2
输出Response2的内容