坏了坏了,寒假快结束了,年前开始溜了,过年大溜特溜了,急了急了,这回真滴急了😭😭😭
1、Servlet初入
1.1、什么是servlet
1、Serlet是JavaEE规范之一。 规范就是接口 2、Servlet就是JavaWeb三大组件之一。 三大组件分别是: Servlet 程序、Filter 过滤器、Listener 监听器 3、Servlet 是运行在服务器上的一个java小程序,它可以接收客户端发送过来的请求,并响应数据给客户端
1.2、第一个Servlet程序
1、编写一个类去实现Servlet接口,这里我们编写了一个HelloServlet类 2、实现service方法,处理请求,并响应数据 我们快速重写他的service方法,这里只是简单输出一下,只要访问HelloServlet程序,service方法就会被执行
3、到web.xml中去配置servlet程序的访问地址
<?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.flzj.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
</web-app>
在工程名后面+hello,运行一下,就看到了我们之前在HelloServlet.java 重写的service方法执行了,效果不错┗|`O′|┛ 嗷~~
1.3、url地址访问Servlet程序图解
客户端访问http:localhost:8080/javaweb02/hello,发送请求,localhost找到服务器ip,总所周知,电脑上有很多的软件,tomcat就是一个软件,在8080端口监听,通过8080端口和tomcat建立连接,tomcat里面跑了很多滴工程,什么javaweb02工程,ROOT工程…,\javaweb02 会找到javaweb02工程,而\hello资源路径 找到web.xml 里面的<url-pattern>/hello</url-pattern> 找有没有对应的地址 很明显找到了,找到了后,继续往上找这个地址是给谁用的,会找到是给HelloServlet用的,接着往上找是给哪个Servlet程序用的,发现是HelloServlet程序用的,接招找,它的全名是什么,找com.flzj.servlet.HelloServlet,接招找到我们写的这个类,执行了service方法
1.4、Servlet的生命周期
1、执行 Servlet 构造器方法
2、执行 init 初始化方法
@Override
public HelloServlet() {
System.out.println("1、执行Servlet构造器方法");
}
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2、执行 init 初始化方法");
}
再第一次访问,的时候创建Servlet程序会调用
3、执行service方法
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.println("3、执行service方法");
}
每次访问都会调用
4、执行destroy销毁方法
@Override
public void destroy() {
System.out.println("4、执行destroy销毁方法");
}
web工程停止时会调用
下面是效果图,我多次刷新页面,使得service方法多次执行
1.5、请求的发送和处理
1.5.1、servle请求的发送和处理
表单会发送 post 和 get 的请求。我们在webapp下写个a.html,点击提交,会跳转到action指向的页面,启动servlet程序。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>post and get</title>
</head>
<body>
<form action="http://localhost:8080/javaweb02/hello" method="get">
<input type="submit">
</form>
</body>
</html>
在service方法可以接收并使用,传过来的请求。
🔍问题:我要怎么区别是post请求还是get请求捏
非常简单,我们只要使用ServletRequest 下的 HttpServletRequest类的getMethon方法,下面的doPost和doGet方法是我们自己写的,使代码整洁
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
String method = httpServletRequest.getMethod();
if(method.equals("GET")){
doGet();
}else if(method.equals("POST")){
doPost();
}
}
public void doGet(){
System.out.println("get请求");
}
public void doPost(){
System.out.println("post请求");
}
1.5.2、HttpServlet请求的发送和处理
开发中一般找Servlet的子类去继承,比如HttpServlet类 1、编写一个类去继承HttpServlet 类 2、根据业务需要重写doGet或doPost方法(这个直接重写方法就是比手写方便多了
package com.flzj.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 HelloServlet2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost执行");
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doGet执行");
}
}
3、到web.xml中的配置Servlet 程序的访问地址
<servlet>
<servlet-name>HelloServlet2</servlet-name>
<servlet-class>com.flzj.servlet.HelloServlet2</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet2</servlet-name>
<url-pattern>/hello2</url-pattern>
</servlet-mapping>
效果自然不在多说
1.5.3、使用IDEA生成servlet程序
这个操作,我称之为kami , (🙅?罕见,damei 生成效果自带doPost和doget方法
package com.flzj.servlet;
import javax.servlet.*;
import javax.servlet.http.*;
import java.io.IOException;
public class HelloServlet3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
在xml这里,直接配置好了servlet,剩下只要自己写servlet-mapping即可
<servlet>
<servlet-name>HelloServlet3</servlet-name>
<servlet-class>com.flzj.servlet.HelloServlet3</servlet-class>
</servlet>
1.6、Servlet类的继承体系
我这图图改改的,本来一点都不麻的图,好像现在👴自己看了都有一点点小麻,但是聪明的同学,一定会看懂,对吧,对吧😍😍😍
1.6.1、GenericServlet 类
@Override
public ServletConfig getServletConfig() {
return config;
}
@Override
public String getInitParameter(String name) {
return getServletConfig().getInitParameter(name);
}
抽象 service( )方法
@Override
public abstract void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException;
1.6.2、HttpService类
两个service方法,一个负责类型转换,一个负责通过
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getMethod();
if (method.equals(METHOD_GET)) {
long lastModified = getLastModified(req);
if (lastModified == -1) {
doGet(req, resp);
} else {
long ifModifiedSince;
try {
ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
} catch (IllegalArgumentException iae) {
ifModifiedSince = -1;
}
if (ifModifiedSince < (lastModified / 1000 * 1000)) {
maybeSetLastModified(resp, lastModified);
doGet(req, resp);
} else {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
}
}
} else if (method.equals(METHOD_HEAD)) {
long lastModified = getLastModified(req);
maybeSetLastModified(resp, lastModified);
doHead(req, resp);
} else if (method.equals(METHOD_POST)) {
doPost(req, resp);
} else if (method.equals(METHOD_PUT)) {
doPut(req, resp);
} else if (method.equals(METHOD_DELETE)) {
doDelete(req, resp);
} else if (method.equals(METHOD_OPTIONS)) {
doOptions(req,resp);
} else if (method.equals(METHOD_TRACE)) {
doTrace(req,resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[1];
errArgs[0] = method;
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
}
@Override
public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest) req;
response = (HttpServletResponse) res;
} catch (ClassCastException e) {
throw new ServletException(lStrings.getString("http.non_http"));
}
service(request, response);
}
1.6.3、查看servlet源码
出现上方蓝色这条线捏,是告诉我们,要选择个tomcat的源码路径,我们选择 -src 的(可以从官网下 我们只需要java的就行了,其他测试什么的,就不管了,👌ok一下效果😤😤😤
Library source does not match the bytecode for class xxxx
这个是我目前科技解释不了的问题,待我日后学有所成必须,来试试看 好像是Maven的问题
2、ServletConfig 类
ServletConfig类从类名上来看,就知道是Servlet程序的配置信息类😁
2.1、ServletConfig类作用
我们去继承了servlet类的init()方法 找参数servletConfig测试
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("2、执行 init 初始化方法");
}
1、可以获取Servlet程序的别名(servlet-name)的值
servletConfig.getServletName()
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("servlet-name 是 : " + servletConfig.getServletName());
}
2、获取初始化参数init-param
我们广块溜到web.xml,在servlet标签里加上,这个是键值对,也可以多写几组,下面我写了2组
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.flzj.servlet.HelloServlet</servlet-class>
<init-param>
<param-name>username</param-name>
<param-value>root</param-value>
</init-param>
<init-param>
<param-name>url</param-name>
<param-value>jdbc:mysql.localhost:3060</param-value>
</init-param>
</servlet>
然后回到我们的HelloServlet类里面的init()方法来试试看
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("username对应的值是" + servletConfig.getInitParameter("username"));
System.out.println("url对应的值是" + servletConfig.getInitParameter("url"));
}
3、获取ServletContext对象
@Override
public void init(ServletConfig servletConfig) throws ServletException {
System.out.println("获取ServletContext对象" + servletConfig.getServletContext());
}
效果图
细节
1、ServletConfig对象可以获取
下面我们在继承了HttpSevlet类的HelloServlet2类,使用了getServletConfig()方法获取到了ServletConfig对象.
public class HelloServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletConfig servletConfig = getServletConfig();
}
}
小细节
这里就会有家人好奇了,为什么是在doGet这里重写啊,为什么我不能在doPost重写啊,根据👴的几次测试,发现这个默认访问是使用GET( QWQ 不会就我现在才发现把
👴已经粗略的学完了,👆上面不理解的内容,后面会解释
2.2、不同类的ServletConfig对象是不同的
这里的HelloSevlet 的ServletConfig对象和其他的类绝对是🙅?不同的,在之前,我们在web.xml下,给HelloServle配置了init-param,(username和url 忘记往上👆看),HelloServlet2👴没有给它配init-param,如果我们在HelloServlet2里给他这样写会怎么样。
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("doPost执行");
ServletConfig servletConfig = getServletConfig();
System.out.println("username对应的值是" + servletConfig.getInitParameter("username"));
System.out.println("url对应的值是" + servletConfig.getInitParameter("url"));
}
会输出null😄 ,因此我们可以得出结论,这两个ServletConfig对象不是同一个
2.3、重写init()方法去掉super.init(config)
众所周知,我们的IDEA在我们重写init()方法的时候会,自动加上这个super.init(config)那么我们去掉会怎么样捏?
@Override
public void init(ServletConfig config) throws ServletException {
System.out.println("重写了init方法,👴不畏惧");
}
然后启动,访问会报空指针异常😰😰😰 这是怎么会是捏?我们广块看一看,哦哦原来是父类GenericServlet的这个init()方法给我们重写了,父类的保存操作就会丢失
@Override
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
真的铸币了,GenericServletl类还有一个init()方法专门是给我们重写用的 no need to call super.init(confing) …
3、ServletContext类
3.1、什么是ServletContext
1、ServletContext 是一个接口, 它表示Servlet上下文对象 2、一个web工程,只有一个ServletContext对象实例 3、ServletContext 对象是一个域对象
这时候肯定有家人会问了,啊啊啊啊啊啊啊啊啊啊啊啊,什么是域对象??
域对象,是可以像Map一样存取数据的对象,叫域对象。这里的域指的是存取数据的操作范围,整个web工程。
| 存数据 | 取数据 | 删数据 |
---|
Map | put() | get() | remove() | 域对象 | setAttribute() | getAttribute() | removeAttribute() |
4、ServletContext是在web工程部署启动的时候创建。在web工程停止的时候销毁。
3.2、ServletContext类的四个作用
3.2.1、获取web.xml中配置的上下文参数context-param
首先我们要去web.xml 里面写,这个也是键值对,可以有多组。context-param是上下文参数(它属于整个web工程)
<?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">
<context-param>
<param-name>username</param-name>
<param-value>context</param-value>
</context-param>
<context-param>
<param-name>password</param-name>
<param-value>root</param-value>
</context-param>
...
ContextServlet类里面doGet()方法我们重写下
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext servletContext = getServletConfig().getServletContext();
System.out.println("username是: " + servletContext.getInitParameter("username"));
System.out.println("password是:" + servletContext.getInitParameter("password"));
}
3.2.2、获取当前的工程路径格式:/工程路径
getContextPath() 方法
System.out.println("当前工程路径" + servletContext.getContextPath());
3.2.3、获取工程部署后在服务器硬盘上的绝对路径
/ 被服务器解释地址为 : http://ip:port/工程名/
System.out.println("工程部署路径" + servletContext.getRealPath("/"));
效果图
3.2.4、像Map一样存取数据
解释下,3.2.1的问题(为什么获取ServletContext对象可以直接写getServletContext()),因为GenericServlet父类的getServletContext()方法长这样
@Override
public ServletContext getServletContext() {
return getServletConfig().getServletContext();
}
😄下面是像Map一样溜,为了证实一个web工程,只有一个ServletContext对象实例,我们写两个类
public class ContextServlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println("从ContextServlet1中提取(此时为空)"+context.getAttribute("k"));
context.setAttribute("k","v");
System.out.println("从ContextServlet1中提取"+context.getAttribute("k"));
}
public class ContextServlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
ServletContext context = getServletContext();
System.out.println("从ContextServlet2中提取"+context.getAttribute("k"));
}
}
ContextServlet2 也是提的取到ContextServlet1存的内容的
4、HTTP
4.1、什么是HTTP协议
(超文本传输协议)是一个简单的请求----响应协议,它通常运行在TCP之上。
文本:html,字符串,… 超文本:图片,音乐,视频,定位,地图.…… 端口:80 Https:安全的
所谓HTTP协议,就是指,客户端和服务器之间通信时,发送的数据,需要遵守的规则,叫HTTP协议。
HTTP协议中的数据又叫报文。
4.2、请求的HTTP协议格式
4.2.1、GET请求
组成部分
1、请求行 (1)请求的方式GET (2)请求的资源路径[+?+请求参数] (3)请求的协议的版本号HTTP/1.1
2、请求头 key: value组成 不同的键值对,表示不同的含义。
图解
4.2.2、POST请求
组成
1、请求行 (1)请求的方式POST (2)请求的资源路径[+?+请求参数] (3)请求的协议的版本号HTTP/1.1
2、请求头key: value不同的请求头,有不同的含义
空行
3、请求体:发送给服务器的数据
图解
4.2.3、常用的请求头
Accept: 表示客户端可以接收的数据类型 Accpet-Languege: 表示客户端可以接收的语言类型 User-Agent: 表示客户端浏览器的信息 Host: 表示请求时的服务器ip和端口号
4.2.4、区分GET和POST请求
GET请求有哪些:
1、form 标签method=get 2、a标签 3、link 标签引入css 4、Script 标签引入js文件 5、img标签引入图片 6、iframe 引入html页面 7、在浏览器地址栏中输入地址后敲回车
POST请求有哪些: 1、form 标签method=post
4.3、响应的HTTP协议格式
1.响应行 (1)响应的协议和版本号 (2)响应状态码 (3)响应状态描述符
2、响应头 (1) key: value 不同的响应头,有其不同含义 空行
3、响应体 回传给客户端的数据
常见的响应码
200 表示请求成功
302 表示请求重定向
404 表示请求服务器已经收到了,但是你要的数据不存在(请求地址错误)
500 表示服务器已经收到请求,但是服务器内部错误(代码错误)
之前的重写init()方法,导致代码出写空指针异常
4.4、MIME类型说明
MIME是HTTP协议中数据类型。 MIME的英文全称是"Multipurpose Internet Mail Extensions"多功能Internet邮件扩充服务。MIME类型的格式是“大类型/小类型”,并与某一种文件的扩展名相对应。
文件 | MIME类型 |
---|
超文本标记语言文本 | .html ,.htm text/html | 普通文本 | .txt text/plain | RTF文本 | .rtf application/rtf | GIF 图形 | .gif image/gif | AVI 文件 | .avi video/x-msvideo | TAR 文件 | .tar application/x-tar |
4.5、如何用浏览器查看HTTP协议
5、HttpServletRequerst 类
每次只要有请求进入Tomcat服务器, Tomcat 服务器就会把请求过来的HTTP协议信息解析好封装到Request对象中。然后传递到service方法( doGet和doPost)中给我们使用。我们可以通过HttpServletRequest 对象,获取到所有请求的信息。
5.1、HttpServletRequerst 类的常用方法
API | 作用 |
---|
getRequestURI( ) | 获取请求的资源路径 | getRequestURL( ) | 获取请求的统一资源定位符(绝对路径) | getRemoteHost( ) | 获取客户端的ip地址 | getHeader( ) | 获取请求头 | getParameter( ) | 获取请求的参数 | getParameters( ) | 获取请求的参数(多个值的时候使用) | getMethod( ) | 获取请求的方式 GET 或 POST | setAttribute(key , value) | 设置域数据 | getAttribute(key) | 获取域数据 | getRequestDispatcher( ) | 获取请求转发对象 |
我们刚快测试一些来试试看
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
System.out.println("URI ==> " + request.getRequestURI());
System.out.println("URL ==> " + request.getRequestURL());
System.out.println("客户端ip地址==>" + request.getRemoteHost());
System.out.println("请求头User-Agent==>" + request.getHeader("User-Agent"));
}
获取参数
先写一个html的表单方便测试 和 ParameterServlet类来接收数据
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>调查问卷</title>
</head>
<body>
<form action="localhost:8080/javaweb03/parameterServlet" method="get">
用户名<input type="text" name="username"><br/>
密码 <input type="password" name="pwd"> <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>
</html>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("用户名:" + req.getParameter("username"));
System.out.println("密码:" + req.getParameter("pwd"));
String[] hobby = req.getParameterValues("hobby");
System.out.println("爱好" + Arrays.asList(hobby));
}
post 请求中文乱码问题
我们只要设置请求体的字符集为UTF-8,setCharacterEncoding() 方法,要在获取请求参数之前调用才有效
req.setCharacterEncoding("UTF-8");
5.2、请求转发
5.2.1、 图解
5.2.2、代码实现
public class Servlet1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("在Servlet1(柜台1)中查看参数(材料)" + username);
request.setAttribute("key1","柜台1的章");
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/servlet2");
requestDispatcher.forward(request,response);
}
}
public class Servlet2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
System.out.println("在Servlet2(柜台2)中查看参数(材料)" + username);
System.out.println("柜台1盖的章是" + request.getAttribute("key1"));
System.out.println("servlet2处理自己的业务");
}
}
5.2.3、特点
1、浏览器地址栏没有发生变化
2、他们是一次请求
3、共享request域中的数据
4、可以访问到WEB-INF目录下
之前tomcat那里,我们就学习过,这个WEB-INF目录不能直接访问,比如这里面的aa.html
但是请求转发可以访问到,我们只要😁在servlet1这个类里面改改就行
//3、问问aa.htm怎么走
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/WEB-INF/aa.html");
//4、走到aa.html
requestDispatcher.forward(request,response);
5、不能访问工程以外的资源
比如我们访问www.baidu.com 会
5.3、Servlet-base标签
base标签可以设置当前页面中所有相对路径工作时,参照哪个路径来进行跳转。
比如这里,我们写了一个html
<html lang="zh_CN">
<head>
<meta charset="UTF-8">
<title>Title</title>
<base href="http://localhost:8080/javaweb2/a/b/c.html">
</head>
<body>
这是a下的b下的c.html页面 <br/>
<a href = "../../index.html" >跳回首页</a>
</body>
</html>
如果我们用,请求转发访问到这个页面,因为请求转发的特性(浏览器地址栏没有发生变化),所以会导致这个a标签返回的地址不正确,比如,我们需要返回到http://localhost:8080/javaweb2/index.html 但可能会从 http://localhost:8080/javaweb02/servletFoward 返回到http://localhost:8080/index.html 显然这不是我们想要的。这时候加上base标签,就会解决我们的问题🌶,这个路径会变成base标签设置页面相对路径工作时参照的地址
5.4、Web种的相对路径和绝对路径
相对路径是: .??????????表示当前目录 …???????表示上一级目录 资源名 表示当前目录/资源名
绝对路径: http://ip:port/工程路径/资源路径
5.5、web种 \ 斜杆的不同含含义
/斜杠如果被浏览器解析,得到的地址是: htp://ip:port/
<a href="/"> 斜杠 </a>
/ 斜杠如果被服务器解析,得到的地址是: htp://ip:port/工程路径
1、<url-pattern>/serv1et1</url-pattern>
2、servletContext. getRealPath("/");
3、request. getRequestDispatcher("/");
特殊情况:
response.sendRediect("/");
6、HttpServletResponse
6.1、HttpServletResponse类的作用
HttpServletResponse类和HttpServletRequest类一样。每次请求进来,Tomcat 服务器都会创建一个Response对象传递给Servlet程序去使用
HttpServletRequest 表示请求过来的信息,HttpServletResponse 表示所有响应的信息,我们如果需要设置返回给客户端的信息,都可以通过HttpServletResponse对象来进行设置
6.2、两个输出流的说明
字节流??????????getOutputStream(); 常用于下载(传递二进制数据) 字符流??????????getWriter(); 常用于回传字符串(常用) 两个流同时只能使用一个。 使用了字节流,就不能再使用字符流,反之亦然,否则就会报错。
public class RequestResponse_ extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.getWriter();
resp.getOutputStream();
}
}
6.3、如何往客户端回传数据
public class RequestResponse_ extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("链接成功🌶");
}
}
然后会发现中文不行🌶 ┭┮﹏┭┮ 会出现???
resp.setCharacterEncoding("UTF-8");
resp.setHeader("Content-Type","text/html; charset=UTF-8");
其实还有一种方法
resp.setContentType("text/html;charset=UTF-8");
确实是同时修改了服务器的字符集
浏览器我们在检查一下,嗷嗷嗷确实是这样
6.4、请求重定向
6.4.1、请求重定向了解
图解
代码实现
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("经过response1");
response.setStatus(302);
response.setHeader("Location","http://localhost:8080/javaweb03/response2");
}
}
public class Response2 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
response.getWriter().write("欢迎来到response2");
}
}
效果图
特点
1、浏览器地址栏会发生变化
2、两次请求
3、不共享Request域中数据
因为每次请求进来, Tomcat 服务器都会创建一个Response对象传递给Servlet程序去使用。
4、不能访问WEB-INF下的资源
第二次请求是浏览器发起的,不能访问服务器的WEB-INF(请求转发是服务器发起的)
5、可以访问工程外的资源
道理就是浏览器发起的,所以dddd
6.4.2、请求重定向简单版
sendRedirect() 方法
public class Response1 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("经过response1");
response.sendRedirect("http://localhost:8080/javaweb03/response2");
}
}
|