从容器到Servlet
前面我们介绍了JSP的内置对象和Servlet的相关知识, 以及如何部署和开发一个Servlet。但是, 并没有详细介绍如何将Servlet与JSP结合起来使用。Web容器是JSP唯一可以识别的HTTP服务器, 所以必须了解Web容器如何生成请求和响应对象。本节将介绍容器HttpServlet之间的“来龙去脉”
web容器可以做什么
Web容器的作用就是创建一个Servlet实例, 并完成Servlet注册以及根据web.xml中的URL 进行响应。当请求来到容器时, Web容器会转发给对应的Servlet来处理请求。
当客户端请求HTTP服务器时, 会使用HTTP来传递请求、标头、参数等信息。HTTP协议是无状态的协议, 通过文本信息传递消息, 而Servlet是Java对象, 运行在Web容器中。当HTTP 服务器将请求转给Web容器时, Web容器会创建一个HttpServletRequest和HttpServletResponse对象, 将请求中的信息传递给HttpServletRequest对象, 而HttpServletResponse对象则作为对客户端响应的Java对象, 这一过程如图所示。
Web容器会根据配置信息(例如web.xml或者@WebServlet)查找相对应的Servlet并调用它的service() 方法。service() 方法会根据HTTP请求的方式, 决定是调月用doPost() 方法或者是doGet(方法。例如, HTTP请求的方式为post,则调用doPost() 方法。
在doPost() 方法中, 可以使用HttpServletRequest对象、HttpServletResponse对象。例如, 使用getParameter() 取得请求参数值, 使用getWriter() 取得输出流对象PrintWriter, 并进行响应处理。最后由Web容器转换为HTTP响应, 由HTTP服务器对浏览器做出响应。随后, Web容器将HttpServletRequest对象、HttpServletResponse对象销毁回收, 请求响应结束, 过程如图所示。
前面提到过HTTP协议是一种无状态的协议, 每一次的请求、响应后, 浏览器不会记得客户端的信息。Web容器根据每次请求都会创建新的request、response对象, 做出响应后就销毁该次的request、response对象。下次的请求、响应就与上一次的请求、响应对象无关了, 所以对于请求、响应的设置,是不能保存到下一次请求的。
类似于这种request、response对象的创建、服务、销毁, 就是Web容器提供的请求、响应的生命周期管理。
令人茫然地doXXX()方法
Servlet中的service() 方法包括多种:doGet() 、doPost() 、doHead() 等。当Method是POST时,请求会调用doPost() 方法; 当Method是GET时, 请求会调用doGet() 方法。在定义Servlet时,一般是继承HttpServlet类, 然后定义doPost() 或者doGet() 方法。在HttpServlet中doGet() 和doPost()方法的实现过程如下:
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_get_not_supported");
this.sendMethodNotAllowed(req, resp, msg);
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String msg = lStrings.getString("http.method_post_not_supported");
this.sendMethodNotAllowed(req, resp, msg);
}
假如, 在自定义Servlet时不实现doGet() 或者doPost() 方法, 那么程序就会调用以上方法。当客户端发出POST请求时, 就会收到错误消息, 如图所示。
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name="hello",urlPatterns = {"/hello"})
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doGet(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
因此, 在定义完Servlet后, 需要实现doGet() 或者doPost() 方法。
关于HttpServletRequest对象
HttpServletRequest对象是请求封装对象, 由Web容器生成, 使用该对象可以取得HTTP请求中的信息。在Servlet中, 也是使用该对象进行请求处理的。如果要共享request中的属性值, 可以将请求对象设置到该对象中, 那么Servlet在同一请求中就可以共享其对象。曾介绍过JSP的内置对象request实质上就是HttpServletRequest。本节将要讨论的是如何读取Body内容、取得上传文件、调派请求等。
getReader() getInputStream()读取body内容
在HttpServletRequest对象中, 可以运用getReader() 方法获取Body内容, 而使用getInputStream()方法获得上传文件的内容。下面利用一个示例来说明如何获取Body内容。
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name="GetReaderBody",urlPatterns = {"/getreader"})
public class GetReaderBody extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
BufferedReader br =req.getReader();
String input ="";
String body = "";
while ((input=br.readLine())!=null){
body+=input+"<br>";
}
resp.setContentType("text/html;charset=utf-8");
PrintWriter out =resp.getWriter();
out.println("<!doctype html>");
out.println("<html lang=\"zh-CN\">");
out.println("<head>");
out.println("<meta charset=\"UTF-8\">");
out.println("<title>Document</title>");
out.println("</head>");
out.println("<body>");
out.println(body);
out.println("</body>");
out.println("</html>");
out.flush();
out.close();
}
}
index.jsp
<%@page language="java" import="java.util.*" pageEncoding="utf-8" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<form action="/web05_war/getreader" method="post">
用户名:
<input type="text" name="username">
<br>
密码:
<input type="password" name="pwd">
<br>
<input type="submit" value="提交" name="user_submit">
</form>
</body>
</html>
从图中可以看出, 页面用的是UTF-8编码, 所以在Servlet中都统一被转化为UTF-8编码,并且参数值都是一一对应的。以上是用get Reader() 方法获取Body内容。如果在form中设置enctype 的值为multipart/form-data, 表示从客户端上传文件, 获取Body的内容时就会获得一堆很奇怪的字符。
上传文件
index.jsp
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取div内容</title>
</head>
<body>
<form action="/web01_war/body" method="post" enctype="multipart/form-data">
<span>选择文件</span>
<input type="file" name="filename">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
后台接口
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
@WebServlet(name="getreaderbody",urlPatterns = {"/body"})
public class GetReaderBody extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
byte[] body =readBody(req);
String txtBody = new String(body,"UTF-8");
String fileName = getFilename(txtBody);
wirteToFile(fileName,body);
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out = resp.getWriter();
out.println("<h1>上传成功</h1>");
out.flush();
out.close();
}
private byte[] readBody(HttpServletRequest req) throws IOException{
int len = req.getContentLength();
InputStream is = req.getInputStream();
byte[] bt = new byte[len];
int total = 0;
while (total<len){
int bytes = is.read(bt,total,len);
total+=bytes;
}
return bt;
}
private String getFilename(String bodyText){
int index = bodyText.indexOf("filename=\"")+10;
String filename = bodyText.substring(index);
filename = filename.substring(filename.lastIndexOf("\\")+1,filename.indexOf("\""));
return filename;
}
private void wirteToFile(String filename,byte[] body){
try {
FileOutputStream fileOutputStream = new FileOutputStream("d:/"+filename);
fileOutputStream.write(body);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
程序运行结束后会在“d:/”文件夹下新建一个上传的文件,打开文件后可发现多了很多
页面中的信息,这是因为没有进行位置的过滤。其实在Servlet3.0及4.0中,可以利用getPart()
getParts()去获取上传文件。
getPart和getParts获取文件
在Servlet3.0中新增getPartO)和getParts()方法来处理上传文件的功能。getPart()用于处理单文件内容,getParts()用于处理多文件内容。在使用getPart()和getParts()方法时,必须使用MultipartConfig注解,这样Servlet才能获得Part对象。MultipartConfig的属性如表所示。
属性 | 说明 |
---|---|
fileSizeThreshold | 数值类型,当上传文件的大小大于该值时,内容将先写入缓存文件,默认值为0 |
location | 字符串类型,设置存放生成的文件目录地址,也是上传过程中临时文件的保存路径,执行Part.write()方法之后,临时文件将被清除 |
maxFileSize | 数值类型,设置允许文件上传的最大值,默认值为-1L,表示不限制大小 |
maxRequestSize | 数值类型,限制multipart/form-data请求的最大数,默认值为-lL,表示不限制大小 |
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;
@MultipartConfig(location = "D:/home",maxFileSize = 1024*1024*10)
@WebServlet(name="getreaderbody",urlPatterns = {"/partbody"})
public class GetPartBody extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
Part part = req.getPart("filename");
String filename = getFileName(part);
part.write(filename);
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out =resp.getWriter();
out.println("<h1>上传成功</h1>");
out.flush();
out.close();
}
private String getFileName(Part part){
if(part==null){
return null;
}
String fileName = part.getHeader("content-disposition");
if(fileName==null||fileName=="") {
return null;
}
return getFilename(fileName);
}
private String getFilename(String bodyText){
int index = bodyText.indexOf("filename=\"")+10;
String filename = bodyText.substring(index);
filename = filename.substring(filename.lastIndexOf("\\")+1,filename.indexOf("\""));
return filename;
}
}
html页面
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取div内容</title>
</head>
<body>
<form action="/web01_war/partbody" method="post" enctype="multipart/form-data">
<span>选择文件</span>
<input type="file" name="filename">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
上传文件
上传多个文件
修改servlet
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.MultipartConfig;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.Part;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Collection;
@MultipartConfig(location = "D:/home",maxFileSize = 1024*1024*10)
@WebServlet(name="getreaderbody",urlPatterns = {"/partbody"})
public class GetPartBody extends HttpServlet {
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
Collection<Part> parts = req.getParts();
for (Part part:
parts) {
String filename = getFileName(part);
part.write(filename);
}
resp.setContentType("text/html;charset=UTF-8");
PrintWriter out =resp.getWriter();
out.println("<h1>上传成功</h1>");
out.flush();
out.close();
}
private String getFileName(Part part){
if(part==null){
return null;
}
String fileName = part.getHeader("content-disposition");
if(fileName==null||fileName=="") {
return null;
}
return getFilename(fileName);
}
private String getFilename(String bodyText){
int index = bodyText.indexOf("filename=\"")+10;
String filename = bodyText.substring(index);
filename = filename.substring(filename.lastIndexOf("\\")+1,filename.indexOf("\""));
return filename;
}
}
jsp修改
<%@ page language="java" import="java.util.*" pageEncoding="utf-8" %>
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>获取div内容</title>
</head>
<body>
<form action="/web01_war/partbody" method="post" enctype="multipart/form-data">
<span>选择文件1</span>
<input type="file" name="filename1">
<br>
<span>选择文件2</span>
<input type="file" name="filename2">
<br>
<input type="submit" value="提交">
</form>
</body>
</html>
上传多个文件成功
使用RequestDispatcher调派请求
在Web程序中,经常是由多个Servlet来完成请求.RequestDispatcher接口就是为了多个Servlet
之间的调整而实现的。该接口可以由HttpServletRequest的getRequestDispatcher(方法取得。调用时
指定跳转的URL地址即可完成跳转动作。RequestDispatcher接口有两种方法实现跳转Servlet:
include()和forward()。
include
include方法的含义是可以在当前的Servlet中显示另外一个Servlet中的内容
新建GetRequestDispatcherSecond.java
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name="GetRequestDispatcherSecond",urlPatterns = {
"/include_second"
},loadOnStartup = 0)
public class GetRequestDispatcherSecond extends HttpServlet {
private static final long serialVersionUID=1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<h1>second Servlet</h1>");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
GetRequestDispatcher.java
package com.wujialiang;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name="GetRequestDispatcher",urlPatterns = {
"/include"
},loadOnStartup = 0)
public class GetRequestDispatcher extends HttpServlet {
private static final long serialVersionUID=1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("<h1>first Servlet</h1>");
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/include_second");
requestDispatcher.include(req,resp);
out.println("<h1>including servlet</h1>");
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
forward()方法
forward()方法是RequestDispatcher中的另一种Servlet跳转方法,只是它的含义是跳转到其他
的Servlet,.而不会再返回跳转前的Servlet。forward()方法在Servlet中经常用到,因为很多业务逻
辑都是跳转到其他的Servlet中进行处理。下面利用一个实例说明其用法并且建立简单的模型架构。
HelloServlet.java
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name="hello",urlPatterns = {
"/hello"
},loadOnStartup = 0)
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
String msg = (String)req.getAttribute("msg");
out.println("<h1>Hello "+msg+"</h1>");
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
ForwardServlet.java
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name="forward",urlPatterns = {
"/forward"
},loadOnStartup = 0)
public class ForwardServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
req.setAttribute("msg",username);
req.getRequestDispatcher("/hello").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req,resp);
}
}
关于HttpResponse对象
HttpServletResponse是用于对浏览器做出响应的操作对象, 可以设置响应类型, 也可以直接输出HTML内容。
通常情况下, 使用setContentType() 设置JSP响应类型, 使用getWriter() 取得PrintWriter对象或者使用getOutputStream() 取得ServletOutputStream流对象, 使用setHeader() 、addHeader() 设置标头, 使用sendRedirect() 、sendError() 对页面进行重定向或者是发送错误消息。
使用getWriter()输出字符串
在前面的例子中,经常可以看到使用get Writer() 方法获取PrintWriter对象, 指定字符串对浏览器输出HTML代码。
通常情况下, 在对浏览器做出响应的同时会设置字符编码, 因为默认的编码是GBK或者是ISO-8859-1, 输出中文时会显示乱码, 所以需要设置支持中文的字符编码格式。这里有两种设置编码格式方式:使用setContentType() 或者setCharacter Encoding() 方法。
设置编码语句为:
resp.setContentType("text/html;charset=utf-8");
resp.setCharacterEncoding("utf-8");
设置编码的时候需要在获得PrintWriter对象或者ServletOutputStream流对象之前进行,否则无效。如果请求的参数中有中文,还需要设置在请求中支持中文字符编码,而且要注意与响应的编码保持一致。
在Servlet开发中, 必须告诉浏览器是以何种方式处理响应(内容类型) , 所以要设置响应标头。在设置context-type中, 指定MIME类型后, 浏览器就能知道标头类型。MIME类型有text/html、application/pdf、application/jar、application/x-zip、image/jpeg等。在应用程序中, 可以在web.xml中设置MIME类型。例如:
<mime-mapping>
<extension>jar</extension>
<mime-type>application/jar</mime-type>
</mime-mapping>
<extension>用于设置文件的后缀, <mime-type>用于设置对应的MIME类型名称。在前面的例子中,曾介绍过请求参数是中文的例子。这里通过实例说明请求参数是中文和响应中也有中文时应该如何发送请求。
index.jsp
<%@page pageEncoding="utf-8" import="java.util.*" %>
<!doctype html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<div>
<h1>调查问卷</h1>
<form action="/web07_war/resp" method="post">
姓名:
<input type="text" name="name">
<br>
邮箱:
<input type="text" name="email">
<br>
你喜欢的明星是:
<select name="star" multiple>
<option value="成龙">成龙</option>
<option value="邓超">邓超</option>
<option value="洪金宝">洪金宝</option>
</select>
<input type="submit" value="提交">
</form>
</div>
</body>
</html>
接口
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "getResponseServlet",urlPatterns = {
"/resp"
})
public class getResponseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
String name = req.getParameter("name");
String eamil = req.getParameter("email");
String[] startName = req.getParameterValues("star");
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("您好,"+name);
out.println("<br>您的邮箱为:"+eamil);
String likeStars = "";
for (String s : startName) {
likeStars+=" "+s;
}
out.println("<br>您喜欢的明星为:"+likeStars);
out.close();
}
}
使用getOutoutStream输出二进制字符串
getOutputStream() 是为了取得输出流而设置的, 在大多数情况下, PrintWriter对象就能解决问题。但是对于上传文件和下载文件则需要用到字节输出流。通过getOutputStream() 方法可以取得ServletOutputStream对象, 它是OutputStream的子类。
resources下新建doc文件夹,该文件夹下新增test.doc
编写downloadServlet.java
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
@WebServlet(name = "download",urlPatterns = {
"/down"
})
public class downloadServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("application/msword");
resp.addHeader("Content-dispotion","attachment;filename=test.doc");
InputStream in =getServletContext().getClassLoader().getResourceAsStream("doc/test.doc");
ServletOutputStream os = resp.getOutputStream();
byte[] bytes = new byte[1024];
int len=-1;
while ((len=in.read(bytes))!=-1){
os.write(bytes,0,len);
}
//关闭输入输出流
in.close();
os.close();
}
}
sendRedirect和sendError方法
sendRedirect
redirectServlet.js
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "redirectServlet",urlPatterns = {
"/redirect2"
})
public class redirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("我是redirect2页面");
out.close();
}
}
sendRedirectServlet.java
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet(name = "sendRedirectServlet",urlPatterns = {
"/redirect"
})
public class sendRedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html;charset=utf-8");
PrintWriter out = resp.getWriter();
out.println("跳转到另一个页面");
resp.sendRedirect(req.getContextPath()+"/redirect2");
out.println("跳转完成");
out.close();
}
}
访问http://localhost:8080/web07_war/redirect跳转到了http://localhost:8080/web07_war/redirect2
从中可以看出, 跳转到redirect2后, 只显示其内容, 而不显示跳转前的Servlet内容。
sendError
如果在处理请求的时候发生错误, 就可以用send Error) 方法传递服务器的状态和错误消息。例如,请求的页面地址不存在,则可以发送如下错误信息:
response.sendError(HttpServletResponse.SC_NOT_FOUND);
SC_NOT_FOUND表示资源文件不存在, 服务器会响应404错误代码, 错误代码统一定义在HttpServletResponse接口上, 还可以自定义错误信息, 程序如下:
response.sendError(HttpServletResponse.SC NOTFOUND, "页面错误");
sendErrorServlet.java
package com.wujialiang;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet(name = "error",urlPatterns = {
"/error"
})
public class sendErrorServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
resp.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED,"不允许get请求");
}
}
常见的http错误请求码
错误代码 | 说明 |
---|---|
401 | 访问被拒绝 |
401.2 | 服务器配置导致登录失败 |
403 | 禁止访问 |
403.6 | IP地址被拒绝 |
403.9 | 用户数过多 |
404 | 没有找到文件或目录 |
405 | 用来访问本页面的HTTP不被允许(方法不被允许) |
406 | 客户端浏览器不接受所请求页面的MIME类型 |
500 | 内部服务器错误 |
504 | 网关超时 |
505 | HTTP版本不受支持 |