Java Web基础入门第十七讲 Servlet开发——request对象

HttpServletRequest介绍

HttpServletRequest对象代表客户端的请求,当客户端通过HTTP协议访问服务器时,HTTP请求头中的所有信息都封装在这个对象中,开发人员通过这个对象的方法,可以获得客户这些信息。

request对象的常用方法

获得客户机信息

在这里插入图片描述
例,通过request对象获取客户端请求信息。

package cn.liayun.request;

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

//request的常用方法
@WebServlet("/RequestDemo1")
public class RequestDemo1 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println(request.getRequestURI());// 得到客户访问的资源,/day06/RequestDemo1
		System.out.println(request.getRequestURL());// 输出http://localhost:8080/day06/RequestDemo1
		
		// http://localhost:8080/day06/RequestDemo1?name=liayun
		System.out.println(request.getQueryString());
		System.out.println("------------------------");
		System.out.println(request.getRemoteAddr());
		System.out.println(request.getRemoteHost());
		
		System.out.println(request.getRemotePort());
		System.out.println(request.getMethod());// 得到请求URL地址时使用的方法
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

在Chrome浏览器上运行的结果如下:
在这里插入图片描述

获得客户机请求头

在这里插入图片描述
例,通过request对象获取客户端请求头信息。

package cn.liayun.request;

import java.io.IOException;
import java.util.Enumeration;

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

//获取请求头
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("------------------获取请求头方式1------------------");
		String header = request.getHeader("Accept-Encoding");// 根据请求头的名字获取对应的请求头的值
		System.out.println(header);
		
		System.out.println("------------------获取请求头方式2------------------");
		Enumeration<String> e = request.getHeaders("Accept-Encoding");// 根据请求头的名字获取所有对应请求头的值
		while (e.hasMoreElements()) {
			String value = e.nextElement();
			System.out.println(value);
		}
		
		System.out.println("------------------获取请求头方式3------------------");
		e = request.getHeaderNames();// 获取所有的请求头
		while (e.hasMoreElements()) {
			String name = e.nextElement();
			String value = request.getHeader(name);
			System.out.println(name + "=" + value);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

获得客户机请求参数(客户端提交的数据)

在这里插入图片描述
例如现在有如下的form表单——test.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>带数据给RequestDemo</title>
</head>
<body>
	<!-- url后面如果跟了中文数据,要编码后再提交  -->
	<a href="/day06/RequestDemo?username=liayun">点一点</a>
	
	<form action="/day06/RequestDemo" method="post">
		用户名1:<input type="text" name="username" /><br/>
		用户名2:<input type="text" name="username" /><br/>
		密码:<input type="text" name="password" /><br/>
		<input type="submit" value="提交" />
	</form>
</body>
</html>

必须注意url后面如果跟了中文数据,要编码后再提交。如:
在这里插入图片描述
在form表单中填写数据,然后提交到RequestDemo这个Servlet进行处理,填写的表单数据如下:
在这里插入图片描述
首先,在服务器端使用getParameter方法、getParameterValues方法以及getParameterNames方法接收表单参数,代码如下:

package cn.liayun.request;

import java.io.IOException;
import java.util.Enumeration;

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

//获取请求数据(获取请求数据时一般来说都要先检查再使用)
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println("---------获取数据方式1---------");
		String value = request.getParameter("username");
		//获取请求数据时一般来说都要先检查再使用
		if (value != null && !value.trim().equals("")) {
			System.out.println(value);
		}
		
		System.out.println("---------获取数据方式2---------");
		Enumeration<String> e = request.getParameterNames();//获取所有的参数名
		while (e.hasMoreElements()) {
			String name = e.nextElement();//得到username或者password
			value = request.getParameter(name);
			System.out.println(name + "=" + value);
		}
		
		System.out.println("---------获取数据方式3---------");
		//username=zhangsan&username=lisi&username=wangwu:一个key可以对应多个值
		String[] values = request.getParameterValues("username");
		/*
		for (String val : values) {
			System.out.println(val);
		}
		*/
		//获取数组数据的技巧,可以避免values数组为null时引发的空指针异常错误!
		for (int i = 0; values != null && i < values.length; i++) {
			System.out.println(values[i]);
		}
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

接下来,我们就在服务器端使用getParameterMap方法接收表单参数。此时要通过一个JavaBean来封装从表单提交过来的数据,设计一个表示用户的JavaBean——User.java。

package cn.liayun;

public class User {
	private String username[];
	private String password;
	public String[] getUsername() {
		return username;
	}
	public void setUsername(String[] username) {
		this.username = username;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
}

在服务器端使用getParameterMap方法接收表单参数,然后用Map集合的数据填充bean。
在这里插入图片描述
此时涉及到BeanUtils工具包的使用,可参考我的笔记《Java基础加强第三讲 内省》
最后,我们在服务器端使用getInputStream方法接收表单参数,通常用在获取文件上传上。
在这里插入图片描述

各种表单输入项数据的获取

例如,现在有如下的form表单——form.html:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>各种表单输入项数据的获取</title>
</head>
<body>
	<form action="/day06/RequestDemo3" method="post">
		用户名:<input type="text" name="username" /><br/>
		密码:<input type="password" name="password" /><br/>
		性别:
			<input type="radio" name="gender" value="male" /><input type="radio" name="gender" value="female" /><br/>
		用户所在地:
			<select name="city">
				<option value="beijing">北京</option><!-- value代表提交给服务器的值,每一个数据必须要有一个名称,服务器根据名称获取对应的值-->
				<option value="shanghai">上海</option>
				<option value="guangzhou">广州</option>
			</select>
			<br/>
		爱好:
			<input type="checkbox" name="likes" value="sing" />唱歌
			<input type="checkbox" name="likes" value="dance" />跳舞
			<input type="checkbox" name="likes" value="basketball" />篮球
			<input type="checkbox" name="likes" value="football" />足球
			<br/>
		备注:<textarea rows="6" cols="60" name="description"></textarea><br/>
		大头照:<input type="file" name="image" /><br/>
		
		<input type="hidden" name="id" value="123456" /><!-- 隐藏输入项 -->
		
		<input type="submit" value="提交" />
	</form>
</body>
</html>

其中,value代表提交给服务器的值,每一个数据必须要有一个名称(name),服务器根据名称(name)获取对应的值(value)。在form表单中填写数据,然后提交到RequestDemo3这个Servlet进行处理,填写的表单数据如下:
在这里插入图片描述
在服务器端接收表单参数,代码如下:

package cn.liayun.request;

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

@WebServlet("/RequestDemo3")
public class RequestDemo3 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		System.out.println(request.getParameter("username"));
		System.out.println(request.getParameter("password"));
		System.out.println(request.getParameter("gender"));
		System.out.println(request.getParameter("city"));
		
		String[] likes = request.getParameterValues("likes");
		for (int i = 0; likes != null && i < likes.length; i++) {
			System.out.println(likes[i]);
		}
		
		System.out.println(request.getParameter("description"));
		System.out.println(request.getParameter("id"));
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		// TODO Auto-generated method stub
		doGet(request, response);
	}

}

防盗链

下面是一个名称为RequestDemo9的Servlet。

package cn.liayun.request;

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

//http://localhost:8080/day06/RequestDemo9
//防盗链
@WebServlet("/RequestDemo9")
public class RequestDemo9 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		//得到来访者从哪个资源来访问服务器
		String referer = request.getHeader("Referer");
		/*
		 * 若来访者直接在浏览器地址栏输入http://localhost:8080/day06/RequestDemo9,
		 * 即来访者没从任何页面点过来,则referer == nul
		 */
		if (referer == null || !referer.startsWith("http://localhost")) {
			//必须得用重定向,要明确告诉来访者跳到首页上面去了
			response.sendRedirect("/day06/index.jsp");
			return;//重定向完了之后后面的代码不需要执行,所以要return
		}
		
		String data = "凤姐日记";
		response.setContentType("text/html;charset=UTF-8");
		response.getWriter().write(data);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

代表首页的index.jsp:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
	这里是网站首页!!!<br/>
	<a href="/day06/ResponseDemo6">查看图书</a>
	<br/>看广告<br/>
	<a href="/day06/RequestDemo9">看凤姐</a>
</body>
</html>

在Chrome浏览器地址栏中输入http://localhost:8080/day06/RequestDemo9,并回车,此时跳转到首页。
在这里插入图片描述
接着点击看凤姐超链接。
在这里插入图片描述

request接收表单提交中文参数乱码问题

以post方式提交表单中文参数的乱码问题

例如,有如下的form表单页面。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>request接收中文参数乱码问题</title>
</head>
<body>
	<form action="/day06/RequestDemo" method="post">
		用户名:<input type="text" name="username" /><br/>
		<input type="submit" value="提交" />
	</form>
</body>
</html>

在这里插入图片描述
此时在服务器端接收中文参数时就会出现中文乱码,如下所示:
在这里插入图片描述

post方式提交中文数据乱码产生的原因和解决办法

下图比较清晰地解释了post方式提交中文数据乱码产生的原因。
在这里插入图片描述
可以看到,之所以会产生乱码,就是因为服务器和客户端沟通的编码不一致造成的,因此解决的办法是:在客户端和服务器之间设置一个统一的编码,之后就按照此编码进行数据的传输和接收。由于客户端是以UTF-8字符编码将表单数据传输到服务器端的,因此服务器也需要设置以UTF-8字符编码进行接收,要想完成此操作,服务器可以直接使用从ServletRequest接口继承而来的"setCharacterEncoding(charset)"方法进行统一的编码设置。修改后的代码如下:
在这里插入图片描述
使用request.setCharacterEncoding("UTF-8");设置服务器以UTF-8的编码接收数据后,此时就不会产生中文乱码问题了。

以get方式提交表单中文参数的乱码问题

例如,有如下的form表单页面。

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>request接收中文参数乱码问题</title>
</head>
<body>
	<form action="/day06/RequestDemo" method="get">
		用户名:<input type="text" name="username" /><br/>
		<input type="submit" value="提交" />
	</form>
</body>
</html>

在这里插入图片描述
此时在服务器端接收中文参数时并不会出现中文乱码,如下所示:
在这里插入图片描述
照理说,这时应该乱码才是,为什么不会出现中文乱码呢?我觉得应该是我使用的是tomcat-8.5.38的缘故。当客户端以UTF-8的编码传输数据到服务器端,由于我使用的是tomcat-8.5.38这个服务器,服务器端的request对象使用的就是UTF-8这个字符编码来接收数据,服务器和客户端沟通的编码相一致因此才不会产生中文乱码。嗯,肯定就是这个缘故!如果大家使用的是tomcat-7.x.x或者更低版本的服务器,想必在服务器端接收中文参数时会出现中文乱码,出现了乱码,大家不要慌,可参考下面的一小节。

get方式提交中文数据乱码产生的原因和解决办法

不管是post方式还是get方式提交中文数据乱码产生的原因都是一样的。对于以get方式传输的数据,request即使设置了以指定的编码接收数据也是无效的(因为它只对客户机的post方式提交有效),客户端以UTF-8的编码传输数据到服务器端,而服务器端的request对象使用的是ISO8859-1这个字符编码来接收数据,服务器和客户端沟通的编码不一致因此才会产生中文乱码的。解决办法很简单,在接收到数据后,先获取request对象以ISO8859-1字符编码接收到的原始数据的字节数组,然后通过字节数组以指定的编码构建字符串,解决乱码问题。
在这里插入图片描述
此时还有一个解决办法,即修改Tomcat服务器的配置文件conf/server.xml,切记此方法在实际开发中不要使用。阅读文档http://tomcat.apache.org/tomcat-8.5-doc/config/http.html,可发现两个属性:URIEncoding和useBodyEncodingForURI。
在这里插入图片描述
我们要在Tomcat服务器的配置文件conf/server.xml中找到如下代码,然后添加属性URIEncoding=UTF-8或者useBodyEncodingForURI=true即可。
在这里插入图片描述

以超链接形式传递中文参数的乱码问题

客户端想传输数据到服务器,可以通过表单提交的形式,也可以通过超链接后面加参数的形式,例如:
在这里插入图片描述
点击超链接,数据是以get的方式传输到服务器的,如果大家使用的是tomcat-8.5.38这个服务器,接收中文数据时并不会产生中文乱码问题;而如果使用的是tomcat-7.x.x或者更低版本的服务器,接收中文数据时就会产生中文乱码问题,解决中文乱码问题的方式与上述的以get方式提交表单中文数据乱码处理问题的方式一致,如下所示:
在这里插入图片描述
另外,需要提的一点就是URL地址后面如果跟了中文数据,那么中文参数最好使用URL编码进行处理,如下所示:
在这里插入图片描述

一道测试题

例如,有如下的form表单页面:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>request接收中文参数乱码问题</title>
</head>
<body>
	<form action="/day06/RequestDemo" method="post">
		用户名:<input type="text" name="username" /><br/>
		<input type="submit" value="提交" />
	</form>
</body>
</html>

在这里插入图片描述
运行如下代码,在浏览器显示的会不会是乱码?

package cn.liayun.request;

import java.io.IOException;

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

@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
	
	//测试题,会有乱码吗?
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.setCharacterEncoding("UTF-8");
		String username = request.getParameter("username");
		
		response.setCharacterEncoding("GBK");
		response.setContentType("text/html;charset=GBK");
		response.getWriter().write(username);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

答案是不会,因为以上代码相当于:

package cn.liayun.request;

import java.io.IOException;

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

@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
	
	//测试题,会有乱码吗?
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String username = "李阿昀";
		
		response.setCharacterEncoding("GBK");
		response.setContentType("text/html;charset=GBK");
		response.getWriter().write(username);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

所以在浏览器显示时不会是乱码。

request对象实现请求转发

请求转发的基本概念

在这里插入图片描述
在Servlet中实现请求转发的方式:request对象提供了一个getRequestDispatcher方法,该方法返回一个RequestDispatcher对象,调用这个对象的forward方法可以实现请求转发。
例如,请求RequestDemo5这个Servlet,RequestDemo5将请求转发到message.jsp页面。

package cn.liayun.request;

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

//请求转发,以及使用request域对象把数据带给转发资源
//请求转发的特点:
//1. 客户端只发出一次请求,而服务器端有多个资源调用
//2. 客户端浏览器地址栏没有变化
@WebServlet("/RequestDemo5")
public class RequestDemo5 extends HttpServlet {
	
	//MVC	M:model(例如JavaBean)	V:view(例如JSP)	C:controller(例如Servlet)
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String data = "liayun, ni hao";
		
//		this.getServletContext().setAttribute("data", object);
		
		//每一个请求都有一个request,每个的数据都存在对应的request里面,跳到jsp,jsp显示各自的数据
		request.setAttribute("data", data);
		
		//request也可实现转发。
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

request对象同时也是一个域对象(Map容器),开发人员通过request对象在实现转发时,把数据通过request对象带给其它Web资源处理。要转发到的message.jsp页面代码如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>request对象实现请求转发</title>
</head>
<body>
	使用EL表达式取出存储在request对象中的数据:
	${data }
	<br/>
	使用普通方式取出存储在request对象中的数据:
	<%
		String data = (String) request.getAttribute("data");
		out.write(data);
	%>
</body>
</html>

在Chrome浏览器上运行的结果如下:
在这里插入图片描述
request对象作为一个域对象(Map容器)使用时,主要是通过以下的四个方法来操作:
在这里插入图片描述

请求重定向和请求转发的区别

在这里插入图片描述

请求转发的细节

forward方法用于将请求转发到RequestDispatcher对象封装的资源上。如果在调用forward方法之前,在Servlet程序中写入的部分内容已经被真正地传送到了客户端,forward方法将抛出IllegalStateException异常。

package cn.liayun.request;

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

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

//forward方法的细节,以下代码会抛异常
@WebServlet("/RequestDemo")
public class RequestDemo extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String data = "liayun, ni hao";
		
		PrintWriter writer = response.getWriter();
		writer.write(data);
		writer.close();
		
		//以下跳转会导致:java.lang.IllegalStateException: Cannot forward after response has been committed
		request.getRequestDispatcher("/message.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

以上代码运行后会抛出异常:
在这里插入图片描述
虽然你不会写出以上愚蠢的代码,但是你会写出如下糟糕的代码,这是在所难免的。
在这里插入图片描述
所以大家一定要给我记住:每次跳转之后一定要return。
在这里插入图片描述
如果在调用forward方法之前向Servlet引擎的缓冲区中写入了内容,只要写入到缓冲区中的内容还没有被真正输出到客户端,forward方法就可以被正常执行,原来写入到输出缓冲区中的内容将被清空,但是,已写入到HttpServletResponse对象中的响应头字段信息保持有效。

package cn.liayun.request;

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

//forward的细节:forward时,会清空response中的数据
@WebServlet("/RequestDemo7")
public class RequestDemo7 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		String data = "liayun, ni hao";
		response.getWriter().write(data);
		
		request.getRequestDispatcher("/index.jsp").forward(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

请求转发的运行流程

在这里插入图片描述

RequestDispatcher的include方法

在这里插入图片描述
在Web应用程序的根目录中新建一个public目录,然后再在此目录下新建两个jsp——head.jsp和foot.jsp。温馨提示:用include实现页面包含,被包含页面不要出现全局架构标签。
在这里插入图片描述
其中,head.jsp页面的内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
head<br/>

foot.jsp页面的内容如下:

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
foot<br/>

最后,再编写一个名称为RequestDemo8的Servlet。

package cn.liayun.request;

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

//用include方法实现页面包含
@WebServlet("/RequestDemo8")
public class RequestDemo8 extends HttpServlet {
	
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		request.getRequestDispatcher("/public/head.jsp").include(request, response);
		
		response.getWriter().write("hahahahaha<br/>");
		
		request.getRequestDispatcher("/public/foot.jsp").include(request, response);
	}

	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		doGet(request, response);
	}

}

web工程中URL地址的推荐写法

在JavaWeb开发中,只要是写URL地址,那么建议最好以“/”开头,也就是使用绝对路径的方式,那么这个“/”到底代表什么呢?可以用如下的方式来记忆“/”:如果“/”是给服务器用的,则代表当前的Web工程,如果“/”是给浏览器用的,则代表webapps目录(也即代表整个Web站点)。

"/"代表当前Web工程的常见应用场景

  1. ServletContext.getRealPath(String path)获取资源的绝对路径。
    在这里插入图片描述
    ServletContext.getRealPath("/form.html")是用来获取服务器上的某个资源,那么这个“/”就是给服务器用的,“/”此时代表的就是Web工程。ServletContext.getRealPath("/form.html")表示的就是读取Web工程下的form.html这个资源,只要明白了“/”代表的具体含义,就可以很快写出要访问的Web资源的绝对路径。
  2. 在服务器端forward到其他页面。
    在这里插入图片描述
    客户端请求某个Web资源,服务器跳转到另外一个Web资源,这个forward也是给服务器用的,那么这个“/”就是给服务器用的,所以此时“/”代表的就是Web工程。
  3. 使用include指令或者<jsp:include>标签引入页面。
    在这里插入图片描述
    此时“/”表的都是Web工程。
  4. ServletContext.getResourceAsStream(String path)获取资源的流对象。
    在这里插入图片描述

"/"代表webapps目录(整个Web站点)的常见应用场景

  1. 使用sendRedirect实现请求重定向。
    在这里插入图片描述
    服务器发送一个URL地址给浏览器,浏览器拿到URL地址之后,再去请求服务器,所以这个“/”是给浏览器使用的,此时“/”代表的就是webapps目录(整个Web站点)。“/day06/form2.html”这个地址指的就是“webapps\day06\form2.html”。温馨提示,response.sendRedirect("/项目名称/文件夹目录/页面");这种写法是将项目名称写死在程序中的做法,万一哪天项目名称变了,此时就得改程序,所以推荐使用下面的灵活写法:
    在这里插入图片描述
    request.getContextPath()获取到的内容就是“/day06”,这样就比较灵活了,使用request.getContextPath()代替“/项目名称”,推荐使用这种方式,灵活方便!
  2. 使用超链接跳转。
    在这里插入图片描述
    这是客户端浏览器使用的超链接跳转,这个“/”是给浏览器使用的,此时“/”代表的就是webapps目录(整个Web站点)。使用超链接访问Web资源,绝对路径的写法推荐使用下面的写法改进:
    在这里插入图片描述
    这样就可以避免在路径中出现项目的名称,使用${pageContext.request.contextPath}取代“/day06”。
  3. form表单提交。
    在这里插入图片描述
    这是客户端浏览器将form表单提交到服务器,所以这个“/”是给浏览器使用的,此时“/”代表的就是webapps目录(整个Web站点)。对于form表单提交中action属性绝对路径的写法,也推荐使用如下的方式改进:
    在这里插入图片描述
    ${pageContext.request.contextPath}得到的就是“/day06”, ${pageContext.request.contextPath}的效果等同于request.getContextPath(),两者获取到的都是“/项目名称”。
  4. js脚本和css样式文件的引用。
    在这里插入图片描述
  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
Java Web开发教程: 入门与提高篇(JSP Servlet)PDF》是一本针对Java Web开发的教程,旨在帮助读者从入门到提高掌握JSP和Servlet使用。 这本教程包括两个主要部分:JSP和Servlet。JSP(Java Server Pages)是一种动态网页开发技术,它允许开发人员在HTML网页上嵌入Java代码。Servlet是一种运行在服务器端的Java程序,用于处理客户端请求和生成响应。 在入门部分,教程首先介绍了Java Web开发基础知识,包括HTML和CSS的基本语法、HTTP协议的工作原理等。然后,它详细介绍了JSP的语法和标签,包括如何在JSP页面中嵌入Java代码,如何使用JSTL(JSP标准标签)等。同时,它还介绍了如何使用Eclipse等常用的开发工具来编写和调试JSP页面。 在提高部分,教程进一步深入解了Servlet使用。它介绍了Servlet的生命周期、请求处理过程和Servlet API的常用类和方法。此外,教程还介绍了如何使用Cookie和Session来实现用户认证和数据共享,以及如何使用过滤器和监听器来实现请求过滤和监听事件。 该教程的特点是通俗易懂,结合实例和练习,帮助读者进行实践。此外,教程还提供了一些实际项目案例,帮助读者理解和应用所学知识。 总之,《Java Web开发教程: 入门与提高篇(JSP Servlet)PDF》是一本适合Java Web开发初学者和有一定基础开发人员学习的教材,通过学习该教程,读者可以全面掌握JSP和Servlet使用,为自己的Web开发之路做好铺垫。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

李阿昀

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

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

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

打赏作者

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

抵扣说明:

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

余额充值