我们再前面已经学过ServletContext(代表整个web应用的一个东西),我们了解到Servlet里面最重要的方法为service方法,service方法里面会有两个参数,为HttpServletRequest(请求),HttpServletResponse(响应)
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的HttpServletResponse对象;
如果要获取客户端请求过来的参数:找HttpServletRequest
如果要给客户端响应一些信息:找HttpServletResponse
我们先看HttpServletResponse,我们进入源码进行了解:
我们按住ctrl,点击鼠标左键,进入源码界面:
我们点击Structure,我们可以看到该类的方法。同时我们可以看到该类继承ServletResponse,我们可以进入源码,查看方法:
这两个类的方法全部加起来才是它的方法。
1.简单分类:
负责向浏览器发送数据的方法
(往外写出的方法)
ServletOutputStream getOutputStream() throws IOException; //写流用这个
PrintWriter getWriter() throws IOException; //写中文用这个,如果用这个写一些东西的时候,会造成字符串损坏或者丢失
负责向浏览器发送响应头的方法
这是ServletResponse里面的方法:
void setCharacterEncoding(String var1); //设置响应的编码
void setContentLength(int var1); //设置响应的字符串长度
void setContentLengthLong(long var1); //设置长度
void setContentType(String var1); //设置类型
这是HttpServletResponse里面的方法:
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
这是两个类综合过来的。
里面还有一些源码如下所示:
状态码的体现:我们知道HttpServletResponse里面有一些200(连通)、300(不通)、400(不通)诸如此类的状态码。可以手动设置,也可以获得。一般是按浏览器自己走。
void setStatus(int var1);
同时我们也可以来看一些响应设置状态码的常量:
以下为一些比较常见的状态码常量。(300代表重定向,4开头就是一些错误,5代表就是服务器错误
int SC_CONTINUE = 100; //100是服务器接收到客户端发来的请求的初始部分,并且请客户端继续发送
int SC_OK = 200; //状态ok
int SC_NOT_FOUND = 404; //没有找到
int SC_INTERNAL_SERVER_ERROR = 500; //服务器端错误
int SC_BAD_GATEWAY = 502; //网关出现了问题
响应状态码:(重要部分)
200:请求响应成功 200
3XX:请求重定向 307
重定向:客户端访问一个地址,服务器返回一个新的地址,让客户端重新去访问这个新的地址。
4XX:找不到资源 404
资源不存在
5xx:服务器代码错误 500 502(网关错误)所访问的服务器崩了,即会出现这个问题。
这里面的方法即对应咱们Http里面提到的响应体和响应状态码。
2.下载文件
1.向浏览器输出消息(之前的文章一直再进行运用)
2.下载文件
(1)要获取下载文件的路径
(2)下载的文件名是什么
(3)设置想办法让浏览器能够支持我们下载所需要的东西
(4)获取下载文件的输入流
这是IO里面的内容,后续我们会再java开发专栏详细更新该内容。
(5)创建缓冲区
(6)获取OutputStream对象
(7)将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
我们通过代码去实现这个下载文件的方法:
(1)要获取下载文件的路径
首先我们去设置一个图片,保存在桌面上,如下所示:
之后我们将该图片保存在resouces里面,
我们即可进入resources里面进行查看,即可发现存在一张图片。
我们可以利用如下代码进行将该图片插入:
String realPath = this.getServletContext().getRealPath("/下载图片.png");
/代表直接在当前web里面进行查找该图片。防止查找不到该图片。
之后获取文件路径即为:
System.out.println("下载文件的路径:"+realPath);
(2)下载的文件名是什么
而我们如何获取下载图片.png,我们可以通过substring进行获取。
substring(返回一个新的字符串,它是此字符串的一个子字符串。该子字符串始于指定索引处的字符,一直到此字符串索引末尾。)
我们的代码设置如下所示:
我们截取最后一个/的下一个字符串,获取/我们需要进行转义(
\\ |
代表一个反斜线字符''\' |
ASCII码值(十进制):92 |
)
我们设置的代码如下所示:
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
其中\\为转义字符。我们再进行+1,即可获取/的下一个字符串即为下载图片.png。
(3)设置想办法让浏览器能够支持(Content-Disposition)我们下载所需要的东西
如果我们需要浏览器支持我们能够下载所需要的东西,我们需要去搜索下载文件的一个头:如下所示:
我们的头文件为:Content-Disposition(我们要设置的一个响应头)
附件为:attachment:filename="+filename
我们设置的代码如下所示:
resp.setHeader("Content-Disposition","attachment:filename="+filename);
(4)获取下载文件的输入流
我们设置的代码如下所示:
FileInputStream in = new FileInputStream(realPath);
(5)创建缓冲区
我们设置代码如下所示:
int len=0;
byte[] buffer = new byte[1024];
(6)获取OutputStream对象
我们设置代码如下所示:
ServletOutputStream out = resp.getOutputStream();
(7)将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
我们进行设置代码如下所示:
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
out.close();
in.close();
}
我们创建缓冲区,可以更加快速的获取输出的内容。
就是这个逻辑,我们完成之后我们进行设置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_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>filedown</servlet-name>
<servlet-class>com.rgf.servlet.FileServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>filedown</servlet-name>
<url-pattern>/down</url-pattern>
</servlet-mapping>
</web-app>
我们在网址进行访问http://localhost:9571/servlet_02_war/down,运行之后我们发现如下所示:
如果出现如上所示,可能问题是我们还没有设置tomcat,我们进行设置:
找到这里之后,如下所示:
我们发现tomcat所运行的项目仍然是servlet-02,我们进行修改:
我们进行设置之后,重新运行。我们发现,我们出现如下界面:
我们发现问题是因为系统找不到指定的文件。
我们进行路径的查看:
我们发现下载文件的路径是这个,我们进行与该图片的实际路径进行对比:
D:\java\untitled2\response\src\main\resources\下载图片.png
我们发现两者路径不同,我们继续解决该问题:
我们可以将该路径写死,我们将该代码进行修改:
String realPath = "D:\\java\\untitled2\\response\\src\\main\\resources\\下载图片.png";
我们重新运行之后如下所示:
我们使用QQ浏览器登陆网址后直接出现该界面,点击下载后即可下载。
但是我们使用双核浏览器进行登录后,我们发现如下所示:
我们发现我们将该图片打开了,但是我们是要将该图片是要进行下载,我们进行修改如下所示:
我们发现我们在设置想办法让浏览器能够支持(Content-Disposition)我们下载所需要的东西过程中代码出现问题:
resp.setHeader("Content-Disposition","attachment;filename="+filename);
我们将该代码原来的:改为了;之后重新运行如下所示:
我们修改之后,双核浏览器和QQ浏览器都可以直接进行下载了。但是在这里我们可以看到,图片名称为__.png,而不是理论上的下载图片.png。
我们将文件名字修改为英文名字我们继续下载重新进行查看内容:修改为rgf.png
我们点击Do Refactor,即可进行修改:
我们重新运行之后如下所示:
我们可知文件名相同,为rgf.png。
对于中文文件名出现的问题,我们可以将代码设置如下所示:
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
对于中文文件名,我们可以通过中文编码将他实现,我们下载的时候是filename,到了这边后进行转换。URLencoder可以将我们的文件转换一个编码,有两个参数,第一个参数代表我们文件本来的一个名字,而由于java传出去的话可能不一样,设置他为UTF-8这样子的一个类型。这一段代码相当于将文件转了一个码,让浏览器用中文文件名URLencoder进行编码,否则有可能乱码。
我们重新运行之后如下所示:
我们的代码整体如下所示:
package com.rgf.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//2.下载文件的步骤
//(1)要获取下载文件的路径
//这是获取绝对地址:getContext,获得上下文地址。
//getRealPath:获得绝对地址
//getResourcePaths:获得资源的地址
String realPath = "D:\\java\\untitled2\\response\\src\\main\\resources\\下载图片.png";
System.out.println("下载文件的路径:"+realPath);
//(2)下载的文件名是什么
String filename = realPath.substring(realPath.lastIndexOf("\\") + 1);
//(3)设置想办法让浏览器能够支持我们下载所需要的东西
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(filename,"UTF-8"));
//(4)获取下载文件的输入流
//这是IO里面的内容,后续我们会再java开发专栏详细更新该内容。
FileInputStream in = new FileInputStream(realPath);
//(5)创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
//(6)获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
//(7)将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
while((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
out.close();
in.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
3.验证码功能
我们在响应的时候除了下载文件还可以设置其他东西,比如我们可以设置在HTTP响应里面所提到的响应体里面的内容,如下所示:HTTP详解_蕾峰的博客-CSDN博客
Accept: 告诉浏览器,它所支持的数据类型
Accept-Encoding:告诉浏览器,支持哪种编码格式 GBK UTF-8 GB2312 ISO8859-1
Accept-Language:告诉浏览器,它的语言环境
Connection:告诉浏览器,请求完成断开还是保持连接
Host: 主机
Refresh:告诉客户端,多久刷新一次。
Location:让网页重新定位,
Cache-Control:缓存控制
我们来设置一个验证码功能:
我们先思考验证码怎么来的:
(1)前端实现(用javascript去判断)
(2)后端实现,需要用到java的图片类(images类),生成一个图片。没有这个图片就没有验证码了,我们需要把这个图片响应到前端。
我们运行之后如下所示:
我们发现每三秒进行刷新。
我们点击鼠标右键,进行查看的时候我们发现其为图片。我们进入界面查看:
我们发现该头的设置为:
我们所设置的都在这里面,他的Content-type为image/jpeg,所以体现为图片。
以下为我们所编写的代码:
package com.rgf.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//如何让浏览器3秒自动刷新一次;我们在学习javascript的时候用window.location.reload(),window.history.go(0)
// 和document.execCommand(’‘Refresh’’),这三个方法是最快速的可以去做。
//而如何让后台去做,我们需要响应回去。响应可以设置前端的所有东西
resp.setHeader("refresh","3");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80,20,BufferedImage.TYPE_INT_RGB);//图片的宽高颜色
//我们通过此创建的图片什么也没有,所以我们需要得到图片
//得到图片
//java如何去画画:现在有一张白纸,通过这张图片拿到了一支笔,我们可以拿这支笔在上面画任何东西。getGraphics相当于一支笔
//Graphics graphics1 = bufferedImage.getGraphics(); 我们需要2D的笔,进行强制转换(java是可以写大型游戏的)
Graphics2D g= (Graphics2D) image.getGraphics(); //alt+enter,进行类型的强制转换。
//设置图片的背景颜色(我们可以利用images或者什么东西去画,一般我们是用画笔去画
g.setColor(Color.CYAN);
g.fillRect(0,0,80,20);//该颜色将位于该方位的进行填充
//给图片写数据,由于验证码是动态的,我们继续生成随机数。
g.setColor(Color.black);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString(makeNum(),0,20); //我们用画笔将随机数画上去,从所设置的区域里面开始画
//告诉浏览器,这个请求用图片的方式进行打开
resp.setContentType("image/jpeg");
//网站存在缓存,我们可以不让浏览器缓存(最优化)
resp.setDateHeader("expires",-1);
//让浏览器不去缓存的数据类型,这些进行了解就好了,目前已经快被淘汰,不怎么使用这些了
resp.setHeader("Cache-Control","no-cache"); //缓存策略为不缓存
resp.setHeader("Pragma","no-cache");
//把图片写给浏览器
ImageIO.write(image,"jpg", resp.getOutputStream());
}
//生成随机数,写一个方法
private String makeNum(){
Random random = new Random();
String num = random.nextInt(999999999) + "";//几个数字代表验证码为几位数,我们需要的是给他返回String,我们通过创建变量来达到目的
//我们获取随机数之后,我们需要将该随机数往外面写,通过以下方法:
StringBuffer sb = new StringBuffer();
/*StringBuffer:字符串变量(Synchronized,即线程安全)。如果要频繁对字符串内容进行修改,出于效率考虑最好使用 StringBuffer,
如果想转成 String 类型,可以调用 StringBuffer 的 toString() 方法。
Java.lang.StringBuffer 线程安全的可变字符序列。在任意时间点上它都包含某种特定的字符序列,
但通过某些方法调用可以改变该序列的长度和内容。可将字符串缓冲区安全地用于多个线程。
StringBuffer 上的主要操作是 append 和 insert 方法,可重载这些方法,以接受任意类型的数据。
每个方法都能有效地将给定的数据转换成字符串,然后将该字符串的字符追加或插入到字符串缓冲区中。
append 方法始终将这些字符添加到缓冲区的末端;
insert 方法则在指定的点添加字符。
String 类型和 StringBuffer 的主要性能区别:
String 是不可变的对象, 因此在每次对 String 类型进行改变的时候,都会生成一个新的 String 对象,
然后将指针指向新的 String 对象,所以经常改变内容的字符串最好不要用 String ,因为每次生成对象都会对系统性能产生影响,
特别当内存中无引用对象多了以后, JVM 的 GC 就会开始工作,性能就会降低。
使用 StringBuffer 类时,每次都会对 StringBuffer 对象本身进行操作,而不是生成新的对象并改变对象引用。
所以多数情况下推荐使用 StringBuffer ,特别是字符串对象经常改变的情况下。
在某些特别情况下, String 对象的字符串拼接其实是被 Java Compiler 编译成了 StringBuffer 对象的拼接,
所以这些时候 String 对象的速度并不会比 StringBuffer 对象慢,
4.使用策略
(1)基本原则:
如果要操作少量的数据,用String ;
单线程操作大量数据,用StringBuilder ;
多线程操作大量数据,用StringBuffer。
(2)不要使用String类的"+"来进行频繁的拼接,因为那样的性能极差的,
应该使用StringBuffer或StringBuilder类,这在Java的优化上是一条比较重要的原则。例如:
String result = "";
for (String s : hugeArray) {
result = result + s;
}
// 使用StringBuilder
StringBuilder sb = new StringBuilder();
for (String s : hugeArray) {
sb.append(s);
}
String result = sb.toString();
当出现上面的情况时,显然我们要采用第二种方法,因为第一种方法,每次循环都会创建一个String result用于保存结果,
除此之外二者基本相同(对于jdk1.5及之后版本)。
(3)为了获得更好的性能,在构造 StringBuffer 或 StringBuilder 时应尽可能指定它们的容量。
当然,如果你操作的字符串长度(length)不超过 16 个字符就不用了,当不指定容量(capacity)时默认构造一个容量为16的对象。
不指定容量会显著降低性能。
(4)StringBuilder 一般使用在方法内部来完成类似 + 功能,因为是线程不安全的,所以用完以后可以丢弃。
StringBuffer 主要用在全局变量中。
StringBuilder 一般使用在方法内部来完成类似 + 功能,因为是线程不安全的,所以用完以后可以丢弃。StringBuffer 主要用在全局变量中。
(5)相同情况下使用 StringBuilder 相比使用 StringBuffer 仅能获得 10%~15% 左右的性能提升,但却要冒多线程不安全的风险。
而在现实的模块化编程中,负责某一模块的程序员不一定能清晰地判断该模块是否会放入多线程的环境中运行,
因此:除非确定系统的瓶颈是在 StringBuffer 上,并且确定你的模块不会运行在多线程模式下,才可以采用 StringBuilder;
否则还是用 StringBuffer。
*/
for(int i=0;i<9-num.length();i++){ //我们进行循环的时候,我们通过遍历将该验证码位数长度依次降低,但与此同时,后面用0进行填充
//即仍然保持9位数的长度,即可不断刷新
sb.append("0");
}
num = sb.toString() + num;//使用StringBuffer的toString()方法,可以将StringBuffer转换成String.
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
4.实现重定向:
B一个web资源收到客户端A请求后,B他会通知A客户端去访问另外一个web资源C,这个过程叫重定向
常见场景:
用户登录(用户首先访问一个登录界面这样子一个东西,访问登录界面之后,如果登录成功,就会跳转到另外一个页面,这个过程就是请求重定向的过程。
使用这个方法来实现重定向:
resp.sendRedirect();
我们将鼠标移动到sendRedirect,按住ctrl键,即可进入源码,我们发现方法如下所示:
void sendRedirect(String var1) throws IOException;
我们进行设置新的类来进行测试:
package com.rgf.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 RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.sendRedirect("/img"); //这是验证码里面的图片,在web.xml里面进行跳转过的
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
然后我们将web.xml进行设置:
<servlet>
<servlet-name>RedirectServlet</servlet-name>
<servlet-class>com.rgf.servlet.RedirectServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RedirectServlet</servlet-name>
<url-pattern>/red</url-pattern>
</servlet-mapping>
之后我们进行运行:
我们发现出错了,没有进行跳转。我们发现我们没有设置项目名称。我们将代码重新修改如下所示:(这里面的项目名称为配置tomcat里面的名称)
resp.sendRedirect("/response_war_exploded/img");
我们进行设置之后,重新运行后如下所示:
我们运行的路径为:http://localhost:9571/response_war_exploded/red。
我们运行之后我们发现跳转到我们所设置好的路径:http://localhost:9571/response_war_exploded/img
如下所示:
我们进入开发者工具里面进行查看:
我们发现状态码为302,我们知道状态码以3开头的都为重定向的意思。重定向到Location,为/response_war_exploded/img。
我们根据该设置,通过代码的方式进行拆分一下:
这是我们对于重定向位置的设置:
resp.setHeader("Location","/response_war_exploded/img");
我们进行重定向状态码的设置时,我们可以直接进行数字设置:
resp.setStatus(302);
我们在重定向设置状态码的时候,我们需要重新编码,也可以利用:
我们随便选择一个,之后按住ctrl,点击HttpServletResponse,进入界面之后找到302的编码:
之后我们将该编码复制出来,如下所示:
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY );
这两种对于编码的设置是相同的。但是采用302来说更加的规范一些。
以下为我的代码的编写的设置:
package com.rgf.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 RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
resp.setHeader("Location","/response_war_exploded/img"); //重定向地址的设置
resp.setStatus(HttpServletResponse.SC_MOVED_TEMPORARILY ); //编码的设置
*/
resp.sendRedirect("/response_war_exploded/img"); //重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
面试题:请你聊聊重定向和转发的区别:
相同点:
(1)页面都会实现跳转
不同点:
请求转发的时候,url不会产生变化
重定向的时候,url地址栏会发生变化;
我们下来看index.jsp,我们进行设置一个最简单的form表单:
<html>
<body>
<h2>Hello World!</h2>
<form action="" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
这些所编写的表单一定要提交过去进行处理,而action就是寻找请求的
我们创建一个新的测试类,如下所示:
package com.rgf.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//可能存在get和post,前端是不固定的。
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入这个请求了");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
之后我们进行设置web.xml里面的文件:
<servlet>
<servlet-name>RequestTest</servlet-name>
<servlet-class>com.rgf.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>RequestTest</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
我们在访问的时候,一般是通过访问web.xml里面的url地址,然后直接访问到我们所编写的类。
我们希望我们在index.jsp里面一点击登录的时候,后台数据从web.xml里面提交过来,而/login为找到该请求的网址,/是需要在web目录下找这个login。所以我们需要在index.jsp里面设置的代码如下所示:
<html>
<body>
<h2>Hello World!</h2>
<%--这里提交的路径需要寻找到项目的路径--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
但是在前端里面,我们无法得知/是什么意思,这个/是相对web目录下找这个login。
我们在设置过程中需要用到JSP的包:我们需要进行导包:
我们点击网址如下所示:
https://mvnrepository.com/search?q=jsp
进入界面之后:
我们点击javax.servlet.jsp-api。
我们进入界面之后,点击2.3.3.
我们将该下面代码复制到pom.xml:
我们发现 External Libraries,和Maven里面的Dependencies都出现了所导入的包,即导入正确。
我们导入完毕之后进行测试:
我们发现出现如上所示,我们进行修改代码如下所示:同时我们也解决了出现乱码的问题:
<html>
<body>
<h2>Hello World!</h2>
<%--这里提交的路径,需要寻找到项目的路径,也就是我们的Context路径--%>
<%--项目的路径如何寻找:需要使用符号里面的JSP符号(${})--%>
<%--pageContext.request.contextPath()代表当前项目的路径,--%>
<form action="${pageContext.request.contextPath}/login" method="get">
<%--我们现在提交的话会找这个请求下的login,--%>
<%--pageContext.request.contextPath(),这个代表当前项目,--%>
<%--这一行代码增加之后即会解决乱码的问题--%>
<%@page contentType="text/html;charset=UTF-8"%>
用户名:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
我们运行之后如下所示:
我们将该用户名设置为hello,密码为rgf521ypl,我们进行提交之后,get方式提交的会在地址栏找到所提交的输入的东西:
http://localhost:9571/response_war_exploded/login?username=hello&password=rgf521ypl
在使用浏览器方面,我们强烈推荐使用谷歌浏览器。
我们点击提交之后,我们发现如下所示:
确认了login是走进来了。
进入了这个请求之后,我们来看一下处理请求。
我们将该处理请求的代码设置如下所示:
//处理请求
String username = req.getParameter("username");//从请求里面获取参数,getParameter
String password = req.getParameter("password");
之后我们设置重定向之后所可以跳转的界面:
我们设置重定向的代码如下所示:
resp.sendRedirect("/response_war_exploded/success.jsp");
之后我们重新运行之后如下所示:
我们成功达到重定向的界面 。
我们可知,达到这个界面的过程就是一个重定向的过程。
我们进入运行的界面如下所示;
我们发现成功的进入该请求
我们的代码设计如下所示:文章来源:https://www.toymoban.com/news/detail-682723.html
package com.rgf.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
//可能存在get和post,前端是不固定的。
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//处理请求
String username = req.getParameter("username");//从请求里面获取参数
String password = req.getParameter("password");
System.out.println(username+":"+password);
//重定向的时候一定要注意路径问题,否则就会出现404。
resp.sendRedirect("/response_war_exploded/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
文章来源地址https://www.toymoban.com/news/detail-682723.html
到了这里,关于HttpServletResponse详解的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!