JavaWeb请求对象与响应对象

请求与响应

web服务在调用service之前,都会创建两个对象,分别为HttpServletResponse和HttpServletRequest,分别用于封装HTTP响应和请求消息。

图片地址=>https://blog.csdn.net/weixin_45151795/article/details/106562541

在这里插入图片描述

在web服务器运行阶段,每个servlet都只会创建一个实例对象,然而每次Http请求都会调用service(HttpServletResponse resp,HttpServletRequest req)方法,重新创建一个请求与响应对象。

HttpServletReponse对象

响应消息分为:状态行、响应消息头、消息体三部分。

因此在HttpServletResponse 接口中定义了向客户端发送响应状态码、响应消息头、消息体。

发送状态码的相关方法

1.setStatus(int status)方法

​ 设置状态吗,服务器默认产生一个状态码200的状态行。

2.sendError(int sc)方法

​ 该方法用于发送表示错误信息的状态码。404表示找不到客户端。在response对象中,提供了两个重载sendError(int sc)方法

public void sendError(int code) throws java.io.IOException
public void sendError(int code,String message) throws java.io.IOException
//该文本信息message将出现在客户端的正文内容中。
public class repTest01 extends HttpServlet {
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		resp.sendError(404,"这是一个404错误状态码");//直接是服务器内部分错误页面
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

	}
}

在这里插入图片描述

发送响应消息头的相关方法

方法声明功能描述
void addHeader(String name,String value)设置响应头字段,会增加同名头字段
void setHeader(String name,String value)设置响应头字段,会覆盖同名头字段
void addIntHeader(String name,intvalue)设置int类型响应头字段,会增加同名头字段
void setHeader(String name,intvalue)设置int类型响应头字段,会覆盖同名头字段
void setContentlength(int len)设置响应消息的实体内容大小,单位字节
void setContentType(String type)用于设置servlet输出内容的MIME类型,例如发送的是JPEG格式的图像数据,就需要设置为“image/jpeg",还可以设置字符编码,“text/html;charset=UTF-8”.优先级中
void setLocal(Local loc)设置响应消息的本地化信息,优先级低
void setCharacterEncoding(String charset)用于设置输出内容使用的字符编码。优先级最高。

发送响应消息体相关的方法

方法描述功能描述
1.getOutputStream()方法字节输出流对象为ServletOutputStream类型。ServletOutputStream是OutputStream的子类,它可以直接输出字节数组中的二进制数据。
2.getWriter()方法获取的字符输出流对象为PrintWriter类型。直接输出字符文本内容。因此想要输出内容全部为字符文本的网页文档使用该方法。
//ServletOutputStream
public class repTest02 extends HttpServlet {
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String data = "itcast";
		ServletOutputStream outputStream = resp.getOutputStream();
//		outputStream.write(data);//要进行类型转换
		outputStream.write(Integer.parseInt(data));//系统默认转换的类型
		outputStream.write(213);
		outputStream.write(data.getBytes());
	}

	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

	}
}
public class repTest03 extends HttpServlet {
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		String data = "itcast";
		PrintWriter writer = resp.getWriter();
		writer.write(data);
//		PrintWriter writer1 = resp.getWriter();
//		writer1.write(data);
	}
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
	}
}
注意两个发送响应消息体的方法不可以同时使用。

HttpServletResponse应用中文乱码

HttpServletResponse默认使用ISO8859-1码表,IE浏览器使用GB2312码表解码
解决乱码的两种方式
1.第一种方式
//设置HttpServletResponse使用utf-8编码
response.setCharacterEncoding("utf8");
//通知浏览器解码方式,设置头字段解码方式
response.setHeader("Content-Type","text/html;charset=UTF-8");

2.第二种方式
//包含第一种方式的两种功能
response.setContentType("Content-Type","text/html;charset=UTF-8");

实现网页定时刷新功能

通过设置response对象的setHeader()方法进行实现

//2秒后跳转
resp.setHeader("Refresh","2,URL=http://www.itcast.cn");

//2秒后定时刷新当前页面
resp.setHeader("Refresh","2");
resp.getWriter().println(new java.util.Date());//对输出方法进行了整合在一行。。
		

实现请求重定向HttpServletResponse对象中的sendRedirect(java.lang.String location) throw IOException方法,会生成302响应码和location响应头

在这里插入图片描述

HttpServletRequest对象

在Servlet API接口中定义了一个HTTPServletRequest接口,它继承自Servletrequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求消息头、和请求消息体。因此在HTTPServletRequest接口中定义了获取请求行、请求头和请求消息行的相关方法。

获取请求行消息的相关方法

当要访问Servlet时,会在请求消息的请求行,包含请求方法、请求资源名、请求路径等信息。

获取请求行的相关方法
方法声明功能描述
String getMethod()用于获取HTTP请求消息的请求方式
String getRequestURL()用于获取请求行中资源名称部分。即位于URL的主机和端口之后、参数部分之前的部分
String getQueryString()用于获取请求行中的参数部分,也就是资源路径后面问好(?)的所有内容
String str = req.getQueryString();//获取请求参数后面的内容
String str1 = req.getProtocol();//用于获取版本
String str2 = req.getContextPath();//获取请求URL中属于web应用程序的路径
String str3 = req.getServletPath();//获取servlet名称,映射路径
String str4 = req.getRemoteAddr();//获取客户端IP地址
String str5 = req.getRemoteHost();//获取请求客户端网络连接的端口号
String str6 = req.getLocalAddr();//获取web服务器上接收的当前请求网络连接的IP地址
String str7 = req.getLocalName();//获取web接收的当前网络IP对应的主机名
int str8 = req.getLocalPort();//获取web服务器上接收当前网络连接的端口号
String str9 = req.getServerName();//获取当前请求所指向的主机名
int str10 = req.getServerPort(); //获取当前请求所连接的服务器端口号
String str11 = req.getScheme();//获取请求的协议名
StringBuffer str12 = req.getRequestURL();//获取完整的客户端发出请求时的URL,不包括参数后面的查询参数部分
null       post方式 =================   get方式 username=13123sdhjf
HTTP/1.1
/servletTest_war_exploded
/Qingqiu01
0:0:0:0:0:0:0:1
0:0:0:0:0:0:0:1
0:0:0:0:0:0:0:1
0:0:0:0:0:0:0:1
8080
localhost
8080
http
http://localhost:8080/servletTest_war_exploded/Qingqiu01

request—利用Referer请求头防止“盗链”

解释:
	在实际的开发之中,我们经常会使用Referer头字段,例如一些网站为了吸引人气并且提高站点的访问量,提供各种软件的下载页面,但是他们本身并没有这些资源,只是将下载的超链接指向其他站点上的资源。而真正提供了下载资源的站点为了防止这种“盗链”,就需要检查请求资源,只接收本站链接发送的下载请求,阻止其他的站点链接的下载请求。
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class DownManagerServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException{//不会抛出Exception
		resp.setContentType("text/html;charset=utf-8");
		PrintWriter out = resp.getWriter();
		//获取referer头的值
		String referer = req.getHeader("referer");
		String sitePart = "http://" + req.getServerName();
		//判断referer是否为空,这个头的首地址是否以sitePart开始的
		//startsWith() 方法用于检测字符串是否以指定的前缀开始。
		if(referer != null && referer.startsWith(sitePart)){
			//处理正在下载的请求
			out.println("dealing downing....");
		}else{
			//非法下载请求跳转到download.html的页面、
			RequestDispatcher rd = req.getRequestDispatcher("/download.html");
			rd.forward(req,resp);
		}

	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
		doGet(req,resp);
	}
}

//映射

    <servlet>
        <servlet-name>DownManagerServlet</servlet-name>
        <servlet-class>qingqiu.DownManagerServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>DownManagerServlet</servlet-name>
        <url-pattern>/DownManagerServlet</url-pattern>
    </servlet-mapping>

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

<!--/servletTest_war_exploded/DownManagerServlet  与下面的DownManagerServlet起到的效果是一样的 -->
    <a href="DownManagerServlet">download</a>
</body>
</html>

HttpServletRequest应用

获取请求参数

在实际的开发过程中,经常需要获得用户提交的表单数据,例如用户名、密码、电子邮件等,为了方便获取表单中的请求大参数,在HTTPServletRequest接口的父类ServletRequest中,定义了一系列的获取参数的方法。

方法声明功能描述
String getParameter(String naem)用于获取某个指定名称的参数值,如果请求消息中没有指定包含的指定名称的参数,则getParameter()方法返回null。如果指定的名称的参数存在但是没有设置值,那么返回一个空串。如果包含多个该指定的名称的参数,则该方法将会返回第一个出现的参数值。
String[] getParameterValues(String name)如果请求消息中包含多个相同的名称参数(通常由一个包含有多个同名字段元素的Form表单生成),从而使其包含在String的数组当中。常见的是对于多选表单中,个人兴趣爱好有多个的时候,可以通过它进行取值。
Enumeration getParameterNames()getParameterNames()方法用于返回一个包含请求消息中所有参数名的Enumeration对象,在此基础之上,可以对请求消息中所有消息的所有参数进行遍历进行处理。
Map getParameterMap()getParameterMap()方法用于将请求消息中的所有参数名和值装进一个Map对象中返回。

注意是表单中name的取值。!!!!!!!!!!!

//https://www.cnblogs.com/lonecloud/p/5467731.html
对于空串来说这是一个对象他被""这个对象给实例化了只是他的长度为0字符的内容为空。
而String变量中还可以存储一个特殊的值,这个是null,这个表示没有和其他的对象与这个变量相关联。也差不多相当于一个没有被实例化的对象,只是定义了一个对象而已。
//测试代码
	@Test
	public void test1(){
		String str1 = null;
		String str2 = "";
		System.out.println(str1 == str2);
		System.out.println("str2="+str2+"str2.length="+str2.length());
		System.out.println("str1="+str1+"str1.length="+str1.length());
	}
//测试结果
false
str2=str2.length=0
java.lang.NullPointerException

//出现空指针异常,和上面的说明一样,str1未被实例化,所以只是声明了一个对象,从而产生空指针的异常。

对于请求参数的中文乱码问题

1.设置编码方式
	在HttpServletRequest接口中,提供了setCharacterEncoding()方法,该方法用于设置request对象的解码方式。
	request.setCharacterEncoding("utf-8");//只对post的提交方式有效,对于get方式的请求无效。
2.get方式的乱码,可以先使用错误码表ISO-8859-1将用户名重新编码,然后使用码表UTF-8进行解码
	name=new String(name.getBytes("ISO-8859-1"),"utf-8");
3.可以配置tomcat解决GET提交方式的中文参数乱码问题。
	<Connector port="8080" protocol="HTTP/1.1"
							connectionTimeout="20000"
							redirectPort="8443" useBodyEncodingForURI="true" />

通过Request对象传递参数

方法声明功能声明
setAttribute()用于将一个对象与一个名称关联后存储进ServletRequest对象中。注意:如果在ServletRequest对象中已经存在指定的名称的属性,该方法会先删除原来的属性,然后添加新的属性。如果传递给该方法的属性值对象为null,则删除指定的名称的属性,效果等同于removeAtrribute()
getAtrribute()获取ServletRequest对象中返回指定名称的属性对象。
removeAttribute()从ServletRequest对象中删除指定名称的属性。
getAttributeNames()返回ServletRequest对象中所有属性名的Enumeration对象。
注意只有属于同一个请求中的数据才可以通过ServleRequest对象传递数据。

RequestDispatcher对象的应用

当web资源收到客户端的请求之后,如果希望服务器通知另外一个资源去处理请求,这时,除了使用sendRedirect()方法实现请求重定向外,开可以通过RequestDispatcher接口的实例对象来实现。

获取RequestDispatcher对象的方法
方法声明功能描述
RequestDispatcher getRequestDispatcher(String path)返回封装了某个路径所指定的RequestDispatcher对象。其中path必须以"/"开头,用于表示当前web应用的根目录。需要注意的是,WEB-INF目录中的内容对RequestDispatcher对象也是可见的,因此,传递给RequestDispatcher()方法的资源也可以是WEB-INF目录中的文件。

当获取到RequestDispatcher对象后,最重要的工作就是通知web资源处理当前的Servlet请求,为此,在RequestDispatcher接口中,定义了两个相关的方法。

RequestDispatcher接口中的方法
方法声明功能描述
forward(ServletRequest request,ServletResponse response)该方法用于将请求从一个Servlet传递给另外一个web资源。在servlet中,可以对请求做一个初步处理,然后通过调用这个方法,将请求传递给其他资源响应。注意:该方法必须在响应提交给客户端之前被调用,否则将抛出lllegalStateException异常。
include(ServletRequest requeset,ServletResponse response)该方法用于将其他的资源作为当前响应内容包含进来。
请求转发forward()

在这里插入图片描述

注意:方法里面的请求对象与响应对象不能写反,必须请求在前,响应在后。
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class RequestForwardServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//不会抛出Exception
		resp.setContentType("text/html;charset=utf-8");
		//将数据存储到request对象中
		req.setAttribute("company","长沙有限责任公司");
		RequestDispatcher dispatcher = req.getRequestDispatcher("/ResultServlet");
		dispatcher.forward(req,resp);

	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
		doGet(req,resp);
	}
}
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class ResultServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//不会抛出Exception
		resp.setContentType("text/html;charset=utf-8");
		//获取PrintWriter对象用于输出信息
		PrintWriter printWriter = resp.getWriter();
		//获取request对象中保存的数据、
		String company = (String) req.getAttribute("company");
		if(company!=null){
			printWriter.println("公司名称="+company);
		}
	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
		doGet(req,resp);
	}
}
<!--    请求转发-->
    <servlet>
        <servlet-name>RequestForwardServlet</servlet-name>
        <servlet-class>qingqiu.RequestForwardServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>RequestForwardServlet</servlet-name>
        <url-pattern>/RequestForwardServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>ResultServlet</servlet-name>
        <servlet-class>qingqiu.ResultServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>ResultServlet</servlet-name>
        <url-pattern>/ResultServlet</url-pattern>
    </servlet-mapping>
请求包含include()

当客户端访问Servlet1时,Servlet1通过调用include()方法将其他web资源包含了进来,这样,当请求处理完毕后,回送给客户端的响应结果既包含了当前Servlet的响应结果,也包含了其他web资源的响应结果。

注意:包含里面的Servlet返回的是响应结果

在这里插入图片描述

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class IncludingServlet extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//不会抛出Exception
		PrintWriter printWriter = resp.getWriter();
		//对请求包含的请求进行参数传递
		String username = "lzy勇";
		String password = "123456";
		RequestDispatcher dispatcher = req.getRequestDispatcher("/IncludedServlet?"+"username="+username+"&&"+"password="+password);
		printWriter.println("before including----");
		dispatcher.include(req,resp);
		printWriter.println("after including----");
	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
		doGet(req,resp);
	}
}

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

public class IncludedServlet  extends HttpServlet {
	public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//不会抛出Exception
		resp.setContentType("text/html;charset=utf-8");
		resp.setCharacterEncoding("utf-8");
		PrintWriter respWriter = resp.getWriter();
		respWriter.println("URI:"+req.getRequestURI()+"sadfs</br>");
		respWriter.println("QueryString="+req.getQueryString());
		respWriter.println("username="+req.getParameter("username"));
		respWriter.println("password="+req.getParameter("password"));
	}
	public void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException,IOException{
		doGet(req,resp);
	}
}
    <!--    请求包含-->
    <servlet>
        <servlet-name>IncludingServlet</servlet-name>
        <servlet-class>qingqiu.IncludingServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>IncludingServlet</servlet-name>
        <url-pattern>/IncludingServlet</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>IncludedServlet</servlet-name>
        <servlet-class>qingqiu.IncludedServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>IncludedServlet</servlet-name>
        <url-pattern>/IncludedServlet</url-pattern>
    </servlet-mapping>

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-syXYRJDf-1618151629343)(D:\2020123later_anzhuang\笔记软件\笔记目录\Javaweb\images\QQ截图20210408122729.png)]

出现了编码错误。

	在IncludingServlet中加入一行===  resp.setContentType("text/html;charset=utf-8");
	在IncludedServlet中加入一行===  req.setCharacterEncoding("utf-8");
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值