第四节、请求与响应

从容器到HttpServlet

之前是如何开发JSP程序以及部署和开发一个Servlet,没有将二者结合起来使用,本章将详细地介绍如何将JSP与Servlet结合起来使用在这里插入图片描述
Servlet中的service()方法有多种方法:doGet()、doPost()、doHead()等。当Method是POST时,请求会调用doPost()方法;当Method是GET时,请求会调用doGet()方法。

HttpServletRequest对象

请求封装对象,由Web容器生成。使用该对象可以取得HTTP请求中的信息。在Servlet中,也是使用该对象进行请求的处理

使用getReader()、getInputStream()读取Body内容

新建一个Java工程、配置相对应的Tomcat、导入Tomcat模块包:
在这里插入图片描述
在src文件夹下建立com.eshore包,该包下建立一个GetReaderBody.java文件。在Web下面建立getReaderBody.jsp文件。现在通过action来连接Servlet的GetReaderBody.java文件。
在这里插入图片描述

package com.eshore;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.annotation.WebServlet;

//给当前文件的路径设置为根目录下的GetReaderBody
@WebServlet(
		urlPatterns = { "/GetReaderBody" },
		name = "getReaderBody"
)
public class GetReaderBody extends HttpServlet {
	//采用HttpServletRequest
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		BufferedReader br = request.getReader();//获取BufferedReader对象
		String input ="";
		String body = "";
		while((input = br.readLine())!=null){//遍历body内容
			body+=input+"<br/>";
		}
		response.setContentType("text/html;charset=UTF-8");//设置响应的类型和编码
		PrintWriter out = response.getWriter();//获取PrintWriter()对象
		out.println("<!DOCTYPE HTML>");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <BODY>");
		out.print(body);
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>获取body内容</title>
  </head>
  
  <body>
  <%--"<%=request.getContextPath()%>获得request对象的地址--%>
       <form action="<%=request.getContextPath()%>/GetReaderBody" method="POST">
       		用户名:<input name="username"/><br/>&nbsp;&nbsp;&nbsp;&nbsp;码:<input name="password" type="password"/><br/>
       		<input type="submit" name="user_submit" value="提交" />
       </form>
  </body>
</html>

在这里插入图片描述
在这里插入图片描述

一堆乱码就是上传文件的内容,显然这不是想要的结果,可以使用getInputStream()读取Body内容。

package com.eshore;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.annotation.WebServlet;

//给当前文件的路径设置为根目录下的GetReaderBody2
@WebServlet(
		urlPatterns = { "/GetReaderBody2" },
		name = "getReaderBody2"
)
public class GetReaderBody2 extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取请求Body
		byte[] body = readBody(request);
		//将内容统一编码
		String textBody = new String(body,"UTF-8");
		//获得文件的名字
		String filename = getFilename(textBody);
		//写到指定位置
		writeToFile(filename, body);
		//返回页面消息
		response.setContentType("text/html;charset=UTF-8");//设置响应的类型和编码
		PrintWriter out = response.getWriter();//取得PrintWriter()对象
		out.println("<!DOCTYPE HTML>");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <script>alert(\"上传成功\")</script><BODY>");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
	//获取请求的输入流
	private byte[] readBody(HttpServletRequest request) 
					throws IOException{
		//获取请求内容长度
		int len = request.getContentLength();
		//获取请求的输入流
		InputStream is = request.getInputStream();
		//新建一个字节数组
		byte b[] = new byte[len];
		int total = 0;
		while(total<len){//获取字节流
			int bytes = is.read(b, total, len);
			total += bytes;
		}
		return b;
	}
	//获取文件的名称
	private String getFilename(String bodyText){
		String filename = bodyText.substring(bodyText.indexOf("filename=\"")+10);
		filename = filename.substring(filename.lastIndexOf("\\")+1,filename.indexOf("\""));
		return filename;
	}
	//写入到指定文件
	private void writeToFile(String filename,byte[] body)
			throws FileNotFoundException,IOException{
		//写到指定的文件地址
		FileOutputStream fileOutputStream = 
			new FileOutputStream("d:/file/"+filename);
		fileOutputStream.write(body);
		fileOutputStream.flush();
		fileOutputStream.close();//注意关闭输出流
	}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>获取上传文件body内容</title>
  </head>
  
  <body>
       <form action="<%=request.getContextPath()%>/GetReaderBody2"
       		method="POST" enctype="multipart/form-data">
       		选择文件:<input type="file" name="filename"/>
       		<input type="submit" name="file_submit" value="提交" />
       </form>
  </body>
</html>

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

使用getPart()、getParts()取得上传文件

getPart()用于处理单文件,getParts()用于处理多文件。在使用getPart()和getParts()方法时,必须使用MultipartConfig注解,这样Servlet才能获得Part对象。

package com.eshore;

import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.annotation.WebServlet;

//给当前文件的路径设置为根目录下的GetReaderBody2
@WebServlet(
		urlPatterns = { "/GetReaderBody2" },
		name = "getReaderBody2"
)
public class GetReaderBody2 extends HttpServlet {

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//获取请求Body
		byte[] body = readBody(request);
		//将内容统一编码
		String textBody = new String(body,"UTF-8");
		//获得文件的名字
		String filename = getFilename(textBody);
		//写到指定位置
		writeToFile(filename, body);
		//返回页面消息
		response.setContentType("text/html;charset=UTF-8");//设置响应的类型和编码
		PrintWriter out = response.getWriter();//取得PrintWriter()对象
		out.println("<!DOCTYPE HTML>");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <script>alert(\"上传成功\")</script><BODY>");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
	//获取请求的输入流
	private byte[] readBody(HttpServletRequest request) 
					throws IOException{
		//获取请求内容长度
		int len = request.getContentLength();
		//获取请求的输入流
		InputStream is = request.getInputStream();
		//新建一个字节数组
		byte b[] = new byte[len];
		int total = 0;
		while(total<len){//获取字节流
			int bytes = is.read(b, total, len);
			total += bytes;
		}
		return b;
	}
	//获取文件的名称
	private String getFilename(String bodyText){
		String filename = bodyText.substring(bodyText.indexOf("filename=\"")+10);
		filename = filename.substring(filename.lastIndexOf("\\")+1,filename.indexOf("\""));
		return filename;
	}
	//写入到指定文件
	private void writeToFile(String filename,byte[] body)
			throws FileNotFoundException,IOException{
		//写到指定的文件地址
		FileOutputStream fileOutputStream = 
			new FileOutputStream("d:/file/"+filename);
		fileOutputStream.write(body);
		fileOutputStream.flush();
		fileOutputStream.close();//注意关闭输出流
	}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>getPart()获取上传文件body内容</title>
  </head>
  
  <body>
       <form action="<%=request.getContextPath()%>/upload.do" 
       		method="POST" enctype="multipart/form-data">
       		选择文件:<input type="file" name="filename"/>
       		<input type="submit" name="file_submit" value="提交" />
       </form>
  </body>
</html>

在这里插入图片描述
在这里插入图片描述

package com.eshore;

import java.io.IOException;
import java.io.PrintWriter;

import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.MultipartConfig;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.Part;
import org.apache.commons.lang.StringUtils;

@MultipartConfig(location = "D:/tmp/", maxFileSize = 1024 * 1024 * 10)
@WebServlet(name = "getPartsBodyContentServlet", urlPatterns = { "/uploads.do" }, loadOnStartup = 0)
public class GetPartsBodyContent extends HttpServlet {
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//设置处理编码
		request.setCharacterEncoding("UTF-8");
		request.getParts();
		for(Part part:request.getParts()){
			//只处理上传文件,因为提交按钮也被当作一个Part对象
			if(part.getName().startsWith("filename")){
				// 获得文件名字
				String filename = getFilename(part);
				String[] filenameArray = filename.split("\\\\");
				filename = filenameArray[filenameArray.length-1];
				part.write(filename);
			}
		}
		//返回页面信息
		response.setContentType("text/html;charset=UTF-8");//设置相应的类型和编码
		PrintWriter out = response.getWriter();//取得PrintWriter()对象
		out.println("<!DOCTYPE HTML>");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <script>alert(\"�ϴ��ɹ�\")</script><BODY>");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.flush();
		out.close();
	}
	//取得文件名称
	private String getFilename(Part part) {
		if (part == null)
			return null;
		String fileName = part.getHeader("content-disposition");
		if (StringUtils.isBlank(fileName)) {
			return null;
		}
		return StringUtils.substringBetween(fileName, "filename=\"", "\"");
	}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>getPart()获取上传文件body内容</title>
  </head>
  
  <body>
       <form action="<%=request.getContextPath()%>/uploads.do" 
       		method="POST" enctype="multipart/form-data">
       		选择文件1:<input type="file" name="filename1"/><br/>
       		选择文件2:<input type="file" name="filename2"/><br/>
       		选择文件3:<input type="file" name="filename3"/><br/>
       		<input type="submit" name="file_submit" value="提交" />
       </form>
  </body>
</html>

在这里插入图片描述
在这里插入图片描述

使用RequestDispatcher调派请求

调用时指定跳转的URL地址即可完成跳转动作。RequestDispatcher有两种方法实现跳转Servlet:include()和forward()。

import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(
		name = "getDispatcherDemo", 
		urlPatterns = { "/include.do" }, 
		loadOnStartup = 0)
public class GetRequestDispatcherDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException{
		doPost(request,response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//返回页面消息
		response.setContentType("text/html;charset=UTF-8");//设置相应的类型和编码
		PrintWriter out = response.getWriter();//取得PrintWriter()对象
		out.println("<!DOCTYPE HTML>");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
		out.println("  <BODY>");
		out.println("  The First Servlet<br/>");
		//获取RequestDispatcher对象
		RequestDispatcher dispatcher = 
			request.getRequestDispatcher("/includeSeconde.do");
		dispatcher.include(request, response);
		out.println("  Including Servlet<br/>");
		out.println("  </BODY>");
		out.println("</HTML>");
		out.close();
	}
}
package com.eshore;

import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "getDispatcherSecondeDemo", 
		urlPatterns = { "/includeSeconde.do" }, 
		loadOnStartup = 0)
public class GetRequestDispatcherSecondeDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request, response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//返回页面消息
		response.setContentType("text/html;charset=UTF-8");//设置响应的类型和编码
		PrintWriter out = response.getWriter();//取得PrintWriter()对象
		out.println("  The seconcde Servlet<br/>");
	}
}

在这里插入图片描述
forward()方法是RequestDispatcher中的另一种Servlet跳转方法,只是它的含义是跳转到其他的Servlet,而不会跳转到前的Servlet。

HttpServletResponse对象

HttpServletResponse是对浏览器做出响应的操作对象,可以设置相应类型,也可以直接输出HTML内容。

使用getWriter()输出字符
package com.eshore;

import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(
		name = "starSurvey", 
		urlPatterns = { "/diaocha.do" })
public class StarSurvey extends HttpServlet{
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException{
		doPost(request,response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//设置请求的编码类型
		request.setCharacterEncoding("UTF-8");
		String username = request.getParameter("username");
		String email = request.getParameter("email");
		String[] starname = request.getParameterValues("starname");
		//设置相应的类型和编码
		response.setContentType("text/html;charset=UTF-8");
		//输出页面内容
		PrintWriter out = response.getWriter();
		out.println("<!DOCTYPE HTML>");
		out.println("<HTML>");
		out.println("  <HEAD><TITLE>感谢你的调查</TITLE></HEAD>");
		out.println("  <BODY>");
		out.println("联系人:<a href='"+email+"'>"+username+"</a>");
		out.println("<br/>喜欢的明星:");
		String str = "";
		for(int i=0;i<starname.length;i++){
			str +=starname[i]+", ";
		}
		str = str.substring(0, str.length()-1);
		out.println(str);
		out.println("  </BODY>");
		out.println("</HTML>");
		out.close();
	}
}
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<!DOCTYPE HTML>
<html>
  <head>
    <title>明星调查</title>
  </head>
  
  <body>
       <div style="text-align: center;">
       	       调查问卷
	       <form action="<%=request.getContextPath()%>/diaocha.do" method="POST">
	       		姓名:<input name="username"/><br/>
	       		邮箱:<input name="email"/><br/>
	       		你喜欢的明星:<br/>
	       		<select name="starname" multiple="multiple">
	       		    <option value="成龙">成龙</option>
	       		    <option value="李连杰">李连杰</option>
	       		    <option value="邓超">邓超</option>
	       		    <option value="元彪">元彪</option>
	       		    <option value="洪金宝">洪金宝</option>
	       		    <option value="周润发">周润发</option>
	       		</select>
	       		<input type="submit" value="提交"/>
	       </form>
       </div>
  </body>
</html>

在这里插入图片描述
在这里插入图片描述

使用getOutputStream()输出二进制字符

对于上传文件和下载文件则需要用到字节输出流

package com.eshore;

import java.io.IOException;
import java.io.InputStream;
import jakarta.servlet.ServletException;
import jakarta.servlet.ServletOutputStream;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "downloadServlet", urlPatterns = { "/download.do" })
public class DownloadServlet extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doPost(request,response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//设置相应的内容的类型
		response.setContentType("application/msword");
		//设置响应的标头内容
		response.addHeader("Content-disposition","attachment;filename=test.doc");
		//获取资源文件
		InputStream in = getServletContext().getResourceAsStream("/doc/test.doc");
		//输出到浏览器中
		ServletOutputStream os = response.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()方法

RequestDispatcher跳转,该动作是不会被浏览器所知的,因此地址栏也不会发生变化。而sendRedirect()方法会在响应中设置HTTP状态码和Location标头,当客户端接收到这个表头时,会重新请求指定的URL,所以地址栏上的地址会发生改变。

package com.eshore;

import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "responseRedirectDemo", 
		urlPatterns = { "/redirect.do" })
public class ResponseRedirectDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException{
		doPost(request,response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		response.setContentType("text/html;charset=UTF-8");// ������Ӧ�����ͺͱ���
		PrintWriter out = response.getWriter();// ȡ��PrintWriter()����
		out.println("  Redirect跳转页面的第一个页面<br/>");
		response.sendRedirect(request.getContextPath()+"/redirSeconde.do");
		out.println("  Redirect Servlet<br/>");
		out.close();
	}
}
package com.eshore;

import java.io.IOException;
import java.io.PrintWriter;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;

@WebServlet(name = "responseRedirectSecodDemo", 
		urlPatterns = { "/redirSeconde.do" })
public class ResponseRedirectSecondeDemo extends HttpServlet {
	private static final long serialVersionUID = 1L;
	public void doGet(HttpServletRequest request, HttpServletResponse response)
		throws ServletException, IOException{
		doPost(request,response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		//返回页面消息
		response.setContentType("text/html;charset=UTF-8");//设置响应的类型和编码
		PrintWriter out = response.getWriter();//取得PrintWriter()对象
		out.println(" Redirect跳转页面的第二个页面<br/>");
	}
}

在这里插入图片描述
sendError()方法如果在处理请求时发生错误,就可以用sendError()方法传递服务器的状态和错误。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

身影王座

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值