Servlet体系结构
package cn.zhukun.web.servlet;
import javax.servlet.*;
import javax.servlet.annotation.WebServlet;
import java.io.IOException;
@WebServlet("/demo")
public class ServletDemo implements Servlet {
@Override
public void init(ServletConfig servletConfig) throws ServletException {
}
@Override
public ServletConfig getServletConfig() {
return null;
}
@Override
public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
System.out.printf("servlet体系结构");
}
@Override
public String getServletInfo() {
return null;
}
@Override
public void destroy() {
}
}
前面我们编写Servlet是通过实现Servlet接口来编写的,但是,使用这种方法,则必须要实现Servlet接口中定义的所有的方法,但是其中我们主要使用的还是service方法,剩余的四种方法中没有任何东西也要去实现,并且还需要自己手动的维护ServletConfig这个对象的引用。因此,这样去实现Servlet是比较麻烦的。
1、GenericServlet抽象类
GenericServlet抽象类的出现很好的解决了这个问题。本着尽可能使代码简洁的原则,GenericServlet实现了Servlet和ServletConfig接口,下面是GenericServlet抽象类的具体代码:
public abstract class GenericServlet implements Servlet, ServletConfig, Serializable {
private static final String LSTRING_FILE = "javax.servlet.LocalStrings";
private static ResourceBundle lStrings = ResourceBundle.getBundle("javax.servlet.LocalStrings");
private transient ServletConfig config;
public GenericServlet() {
}
public void destroy() {
}
public String getInitParameter(String name) {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getInitParameter(name);
}
}
public Enumeration<String> getInitParameterNames() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getInitParameterNames();
}
}
public ServletConfig getServletConfig() {
return this.config;
}
public ServletContext getServletContext() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getServletContext();
}
}
public String getServletInfo() {
return "";
}
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
public void log(String msg) {
this.getServletContext().log(this.getServletName() + ": " + msg);
}
public void log(String message, Throwable t) {
this.getServletContext().log(this.getServletName() + ": " + message, t);
}
public abstract void service(ServletRequest var1, ServletResponse var2) throws ServletException, IOException;
public String getServletName() {
ServletConfig sc = this.getServletConfig();
if (sc == null) {
throw new IllegalStateException(lStrings.getString("err.servlet_config_not_initialized"));
} else {
return sc.getServletName();
}
}
}
GenericServlet抽象类相比于直接实现Servlet接口,有以下几个好处:
1.为Servlet接口中的所有方法提供了默认的实现,则程序员需要什么就直接改什么,不再需要把所有的方法都自己实现了。
2.提供方法,包围ServletConfig对象中的方法。
3.将init( )方法中的ServletConfig参数赋给了一个内部的ServletConfig引用从而来保存ServletConfig对象,不需要程序员自己去维护ServletConfig了。
2、HttpServlet抽象类
虽然GenricServlet是对Servlet一个很好的加强,但是也不经常用,因为他不像HttpServlet那么高级。HttpServlet才是主角,在现实的应用程序中被广泛使用。
之所以所HttpServlet要比GenericServlet强大,其实也是有道理的。HttpServlet是由GenericServlet抽象类扩展而来的,HttpServlet抽象类的声明如下所示:
public abstract class HttpServlet extends GenericServlet implements Serializable
HttpServlet抽象类是继承于GenericServlet抽象类而来的。
HttpServlet的service方法的:
public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException {
HttpServletRequest request;
HttpServletResponse response;
try {
request = (HttpServletRequest)req;
response = (HttpServletResponse)res;
} catch (ClassCastException var6) {
throw new ServletException("non-HTTP request or response");
}
this.service(request, response);
}
HttpServlet中的service方法把接收到的ServletRequsest类型的对象转换成了HttpServletRequest类型的对象,把ServletResponse类型的对象转换成了HttpServletResponse类型的对象。之所以能够这样强制的转换,是因为在调用Servlet的Service方法时,Servlet容器总会传入一个HttpServletRequest对象和HttpServletResponse对象,预备使用HTTP。因此,转换类型当然不会出错了。转换之后,service方法把两个转换后的对象传入了另一个service方法,那么我们再来看看这个方法是如何实现的:
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getMethod();
long lastModified;
if (method.equals("GET")) {
lastModified = this.getLastModified(req);
if (lastModified == -1L) {
this.doGet(req, resp);
} else {
long ifModifiedSince = req.getDateHeader("If-Modified-Since");
if (ifModifiedSince < lastModified) {
this.maybeSetLastModified(resp, lastModified);
this.doGet(req, resp);
} else {
resp.setStatus(304);
}
}
} else if (method.equals("HEAD")) {
lastModified = this.getLastModified(req);
this.maybeSetLastModified(resp, lastModified);
this.doHead(req, resp);
} else if (method.equals("POST")) {
this.doPost(req, resp);
} else if (method.equals("PUT")) {
this.doPut(req, resp);
} else if (method.equals("DELETE")) {
this.doDelete(req, resp);
} else if (method.equals("OPTIONS")) {
this.doOptions(req, resp);
} else if (method.equals("TRACE")) {
this.doTrace(req, resp);
} else {
String errMsg = lStrings.getString("http.method_not_implemented");
Object[] errArgs = new Object[]{method};
errMsg = MessageFormat.format(errMsg, errArgs);
resp.sendError(501, errMsg);
}
}
这个service方法的参数是HttpServletRequest对象
和HttpServletResponse对象
,刚好接收了上一个service方法传过来的两个对象。
接下来我们再看看service方法是如何工作的,我们会发现在service方法中还是没有任何的服务逻辑,但是却在解析HttpServletRequest中的方法参数,并调用以下方法之一:doGet,doPost,doHead,doPut,doTrace,doOptions和doDelete。
这7种方法中,每一种方法都表示一个Http方法。doGet和doPost是最常用的。所以,如果我们需要实现具体的服务逻辑,不再需要覆盖service方法了,只需要覆盖doGet或者doPost就好了。
总之,HttpServlet有两个特性是GenericServlet所不具备的:
- 不用覆盖service方法,而是覆盖doGet或者doPost方法。(在少数情况,还会覆盖其他的5个方法。)
- 使用的是HttpServletRequest和HttpServletResponse对象。
(开发中写Servlet最常用的就是继承HttpServlet抽象类,复写doGet或doPost方法)
ServletRequset接口和它的子接口HttpServletRequest接口
1、Request和Response原理:
- request和response对象是由服务器创建的,我们来使用它们
- request对象是来获取请求消息,response对象用来设置响应消息
request对象继承体系结构:
2、ServletRequset接口
Servlet容器对于接受到的每一个Http请求,都会创建一个ServletRequest对象,并把这个对象传递给Servlet的Sevice( )方法。其中,ServletRequest对象内封装了关于这个请求的许多详细信息。
public interface ServletRequest {
int getContentLength();//返回请求主体的字节数
String getContentType();//返回主体的MIME类型
String getParameter(String var1);//返回请求参数的值 ,ServletRequest中最常用的方法,可用于获取查询字符串的值
}
3、HttpServletRequest接口
HttpServletRequest
对象代表客户端的请求,当客户端通过HTTP协议
访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,通过这个对象提供的方法我们可以分别获得HTTP请求的请求行,请求头和请求体。
3.1获得客户机请求行信息:
String getMethod()
:获取请求方式
String getContextPath()
:获取虚拟目录
String getServletPath()
:获取Servlet路径
getRequestURL()
:返回客户端发出请求时的完整URL。
String getProtocol()
:获取协议及版本
getRequestURI()
: 返回请求行中的资源名部分。
getQueryString ()
:返回请求行中的参数部分。
getPathInfo()
:方法返回请求URL中的额外路径信息。额外路径信息是请求URL中的位于Servlet的路径之后和查询参数之前的内容,它以“/”开头。
getRemoteAddr()
:方法返回发出请求的客户机的IP地址。
getRemoteHost()
:方法返回发出请求的客户机的完整主机名。
getRemotePort()
:方法返回客户机所使用的网络端口号。
getLocalAddr()
:方法返回WEB服务器的IP地址。
getLocalName()
:方法返回WEB服务器的主机名。
案例:
package cn.zhukun.web.servlet;
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("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
/**
* 1.获得客户机信息
*/
String requestUrl = request.getRequestURL().toString();//得到请求的URL地址
String requestUri = request.getRequestURI();//得到请求的资源
String queryString = request.getQueryString();//得到请求的URL地址中附带的参数
String remoteAddr = request.getRemoteAddr();//得到来访者的IP地址
String remoteHost = request.getRemoteHost();
int remotePort = request.getRemotePort();
String remoteUser = request.getRemoteUser();
String method = request.getMethod();//得到请求URL地址时使用的方法
String pathInfo = request.getPathInfo();
String localAddr = request.getLocalAddr();//获取WEB服务器的IP地址
String localName = request.getLocalName();//获取WEB服务器的主机名
response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
//通过设置响应头控制浏览器以UTF-8的编码显示数据,如果不加这句话,那么浏览器显示的将是乱码
response.setHeader("content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.write("获取到的客户机信息如下:");
out.write("<hr/>");
out.write("请求的URL地址:"+requestUrl);
out.write("<br/>");
out.write("请求的资源:"+requestUri);
out.write("<br/>");
out.write("请求的URL地址中附带的参数:"+queryString);
out.write("<br/>");
out.write("来访者的IP地址:"+remoteAddr);
out.write("<br/>");
out.write("来访者的主机名:"+remoteHost);
out.write("<br/>");
out.write("使用的端口号:"+remotePort);
out.write("<br/>");
out.write("remoteUser:"+remoteUser);
out.write("<br/>");
out.write("请求使用的方法:"+method);
out.write("<br/>");
out.write("pathInfo:"+pathInfo);
out.write("<br/>");
out.write("localAddr:"+localAddr);
out.write("<br/>");
out.write("localName:"+localName);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
3.2获得客户机请求头信息:
getHeader(string name)
:String
getHeaders(String name)
:Enumeration
getHeaderNames()
:
package cn.zhukun.web.servlet;
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;
import java.util.Enumeration;
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");//设置将字符以"UTF-8"编码输出到客户端浏览器
//通过设置响应头控制浏览器以UTF-8的编码显示数据
response.setHeader("content-type", "text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
Enumeration<String> reqHeadInfos = request.getHeaderNames();//获取所有的请求头
out.write("获取到的客户端所有的请求头信息如下:");
out.write("<hr/>");
while (reqHeadInfos.hasMoreElements()) {
String headName = (String) reqHeadInfos.nextElement();
String headValue = request.getHeader(headName);//根据请求头的名字获取对应的请求头的值
out.write(headName+":"+headValue);
out.write("<br/>");
}
out.write("<br/>");
out.write("获取到的客户端Accept-Encoding请求头的值:");
out.write("<hr/>");
String value = request.getHeader("Accept-Encoding");//获取Accept-Encoding请求头对应的值
out.write(value);
Enumeration<String> e = request.getHeaders("Accept-Encoding");
while (e.hasMoreElements()) {
String string = (String) e.nextElement();
System.out.println(string);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
3.3 获取请求体数据:
请求体:只有POST请求方式才有请求体,在请求体中封装了POST请求的请求参数。request对象将请求体的数据封装成流
- 获取流对象
BufferedReader getReader()
:获取字符输入流,只能操作字符数据
ServletInputStream getInputStream()
:获取字节输入流,可以操作所有类型数据 - 再从流对象中拿数据
案例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="demo4" method="post">
用户名(文本框):<input type="text" name="username" value="请输入用户名"><br>
密 码(密码框):<input type="password" name="userpass" value="请输入密码"><br>
<input type="submit" value="提交(提交按钮)">
</form>
</body>
</html>
package cn.zhukun.web.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.IOException;
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取请求消息体--请求参数
//1、获取字符流
BufferedReader br = request.getReader();
String line = null;
while ((line=br.readLine())!=null)
{
System.out.println(line);
}
}
}
3.4获得客户机请求参数(客户端提交的数据):
getParameter(String)
:根据参数名称获取参数值 ——常用
getParameterValues(String name)
:根据参数名称获取参数值的数组 ——常用
getParameterNames()
:获取所有请求的参数名称——不常用
getParameterMap()
:获取所有参数的map集合——编写框架时常用
案例:
get方式
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="demo3" method="get">
用户名(文本框):<input type="text" name="username" value="请输入用户名"><br>
密 码(密码框):<input type="password" name="userpass" value="请输入密码"><br>
<input type="submit" value="提交(提交按钮)">
</form>
</body>
</html>
package cn.zhukun.web.servlet;
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;
import java.util.Enumeration;
@WebServlet("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");//获取填写的用户名
String userpass = request.getParameter("userpass");//获取填写的密码
response.setContentType("text/html;charset=UTF-8");//设置客户端浏览器以UTF-8编码解析数据
PrintWriter out = response.getWriter();
out.write("用户名:"+username);
out.write("<br>");
out.write("密码:"+userpass);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
post方式:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="demo3" method="post">
用户名(文本框):<input type="text" name="username" value="请输入用户名"><br>
密 码(密码框):<input type="password" name="userpass" value="请输入密码"><br>
<input type="submit" value="提交(提交按钮)">
</form>
</body>
</html>
package cn.zhukun.web.servlet;
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("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");//获取填写的用户名
String userpass = request.getParameter("userpass");//获取填写的密码
response.setContentType("text/html;charset=UTF-8");//设置客户端浏览器以UTF-8编码解析数据
PrintWriter out = response.getWriter();
out.write("用户名:"+username);
out.write("<br>");
out.write("密码:"+userpass);
}
}
解决post提交方式的乱码:
request.setCharacterEncoding("UTF-8");
解决get提交的方式的乱码:(tomcat 8 已经将get方式乱码问题解决了)
parameter = newString(parameter.getbytes("iso8859-1"),"utf-8");
3.5请求跳转
请求转发:一种在服务器内部的资源跳转方式
步骤:
- 通过request对象获取请求转发器对象:RequestDispatcher getRequestDispatcher(String path)
- 使用RequestDispatcher对象来进行转发:forward(ServletRequest request, ServletResponse response)
案例:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="demo4" method="post">
用户名(文本框):<input type="text" name="username" value="请输入用户名"><br>
密 码(密码框):<input type="password" name="userpass" value="请输入密码"><br>
爱好:<input type="checkbox" name="hobby" value="game">游戏
<input type="checkbox" name="hobby" value="study">学习
<input type="checkbox" name="hobby" value="running">跑步
<input type="submit" value="提交(提交按钮)">
</form>
</body>
</html>
package cn.zhukun.web.servlet;
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.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo4被访问了");
response.setHeader("Content-Type","text/html;charset=UTF-8");
response.setContentType("text/html;charset=UTF-8");//设置客户端浏览器以UTF-8编码解析数据
PrintWriter out = response.getWriter();
//转发资源到demo3
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/demo3");
requestDispatcher.forward(request,response);
}
}
package cn.zhukun.web.servlet;
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("/demo3")
public class ServletDemo3 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo3被访问了");
request.setCharacterEncoding("UTF-8");
String username = request.getParameter("username");//获取填写的用户名
String userpass = request.getParameter("userpass");//获取填写的密码
//设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8");
//通知浏览器使用utf-8编码
response.setHeader("Content-Type","text/html;charset=UTF-8");
response.setContentType("text/html;charset=UTF-8");//设置客户端浏览器以UTF-8编码解析数据
PrintWriter out = response.getWriter();
out.write("用户名:"+username);
out.write("<br>");
out.write("密码:"+userpass);
out.write("<br>");
out.write("爱好:");
String[] hobbies = request.getParameterValues("hobby");
for (String hobby: hobbies)
{
out.write(hobby);
out.write("  ");
}
}
}
表单提交到demo4,demo4被访问了,demo4将资源跳转到demo3,将request对象和response对象转发给demo3,demo3被访问,但浏览器地址栏路径还是demo4。
特点:
- 浏览器地址栏路径不发生变化
- 只能转发到当前服务器内部资源中。
- 转发是一次请求
3.6共享数据
域对象:一个有作用范围的对象,可以在范围内共享数据
request域:代表一次请求的范围,一般用于请求转发的多个资源中共享数据
方法:
void setAttribute(String name,Object obj)
:存储数据Object getAttitude(String name)
:通过键获取值void removeAttribute(String name)
:通过键移除键值对
package cn.zhukun.web.servlet;
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.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
@WebServlet("/demo4")
public class ServletDemo4 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo4被访问了");
//存储数据到request域中
request.setAttribute("msg","hello");
//转发资源到demo3
RequestDispatcher requestDispatcher = request.getRequestDispatcher("/demo2");
requestDispatcher.forward(request,response);
}
}
package cn.zhukun.web.servlet;
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("/demo2")
public class ServletDemo2 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("demo2被访问了");
//获取数据
Object msg = request.getAttribute("msg");
System.out.println(msg);
}
}
demo4中在request域中保存的数据“hello”在资源跳转到demo3后被共享到了demo3
ServletResponse接口和它的子接口HttpServletResponse接口
1、ServletResponse接口
javax.servlet.ServletResponse接口表示一个Servlet响应,在调用Servlet的Service( )方法前,Servlet容器会先创建一个ServletResponse对象,并把它作为第二个参数传给Service( )方法。ServletResponse隐藏了向浏览器发送响应的复杂过程。
public interface ServletResponse {
String getCharacterEncoding();
String getContentType();
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentType(String var1);
void setBufferSize(int var1);
int getBufferSize();
void flushBuffer() throws IOException;
void resetBuffer();
boolean isCommitted();
void reset();
void setLocale(Locale var1);
Locale getLocale();
}
其中的getWriter方法,它返回了一个可以向客户端发送文本的的Java.io.PrintWriter
对象。默认情况下,PrintWriter对象使用ISO-8859-1编码(该编码在输入中文时会发生乱码)。
在向客户端发送响应时,大多数都是使用该对象向客户端发送HTML。还有一个方法也可以用来向浏览器发送数据,它就是getOutputStream,从名字就可以看出这是一个二进制流对象,因此这个方法是用来发送二进制数据的。
在发送任何HTML之前,应该先调用setContentType()
方法,设置响应的内容类型,并将“text/html”
作为一个参数传入,这是在告诉浏览器响应的内容类型为HTML,需要以HTML的方法解释响应内容而不是普通的文本,或者也可以加上“charset=UTF-8”改变响应的编码方式以防止发生中文乱码现象。
2、HttpServletResponse接口
HttpServletResponse
接口,它继承自ServletResponse接口,专门用来封装HTTP响应消息。 由于HTTP请求消息分为状态行,响应消息头,响应消息体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码,响应消息头,响应消息体的方法
HttpServletResponse内封装的响应
通过Response设置响应
void addCookie(Cookie var1)
;//给这个响应添加一个cookie
void addHeader(String var1, String var2)
;//给这个请求添加一个响应头
void sendRedirect(String var1) throws IOException
;//发送一条响应码,讲浏览器跳转到指定的位置
void setStatus(int var1)
;//设置响应行的状态码
PrintWriter getWriter()
获得字符流,通过字符流的write(String s)方法可以将字符串设置到response 缓冲区中,随后Tomcat会将response缓冲区中的内容组装成Http响应返回给浏览器端。
ServletOutputStream getOutputStream()
获得字节流,通过该字节流的write(byte[] bytes)可以向response缓冲区中写入字节,再由Tomcat服务器将字节内容组成Http响应返回给浏览器。
Response的乱码问题:
原因:response缓冲区的默认编码是iso8859-1,此码表中没有中文,所以需要更改response的编码方式
两种方法:
第一种:
//设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf-8");
//通知浏览器使用utf-8编码
response.setHeader("Content-Type","text/html;charset=UTF-8");
第二种:
//包含第一种方式的两种功能
response.setContentType("text/html;charset=UTF-8");