后台(12)——Servlet(4)

探索Android软键盘的疑难杂症
深入探讨Android异步精髓Handler
详解Android主流框架不可或缺的基石
站在源码的肩膀上全解Scroller工作机制


Android多分辨率适配框架(1)— 核心基础
Android多分辨率适配框架(2)— 原理剖析
Android多分辨率适配框架(3)— 使用指南


自定义View系列教程00–推翻自己和过往,重学自定义View
自定义View系列教程01–常用工具介绍
自定义View系列教程02–onMeasure源码详尽分析
自定义View系列教程03–onLayout源码详尽分析
自定义View系列教程04–Draw源码分析及其实践
自定义View系列教程05–示例分析
自定义View系列教程06–详解View的Touch事件处理
自定义View系列教程07–详解ViewGroup分发Touch事件
自定义View系列教程08–滑动冲突的产生及其处理


版权声明


在前几篇博客中我们学习了Tomcat,Http,Servlet,HttpServletResponse在此基础上我们来深入学习Servlet的请求即HttpServletRequest

HttpServletRequest的简单使用

HttpServletRequest代表客户端的请求,当客户端通过HTTP协议访问服务器时与请求相关的所有信息都将被封装在这个对象中,所以我们可通过该对象获得客户端的相关信息。

常用的方法如下:

  • getRequestURL():返回客户端发出请求时的完整URL
  • getRequestURI():返回请求行中的资源名部分
  • getContextPath():返回请求的上下文路径
  • getQueryString():返回请求行中的参数部分
  • getParameter():返回参数中的具体值
  • getRemoteAddr():返回发出请求的客户端的IP地址
  • getRemoteHost():返回发出请求的客户端的完整主机名
  • getRemotePort():返回客户端所使用的网络端口号
  • getMethod():返回客户端使用的请求方式
  • getHeaderNames():返回此请求包含的所有头的名称
  • getHeader():返回指定的请求头的值

请看如下示例:

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		getRequestInfo(request);
		getRequestHeader(request);
	}
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
	}
	
	//获取与请求相关的信息
	private void getRequestInfo(HttpServletRequest request){
		String method=request.getMethod();
		StringBuffer requestURL = request.getRequestURL();
		String requestURI = request.getRequestURI();
		String contextPath = request.getContextPath();
		String queryString = request.getQueryString();
		String name=request.getParameter("name");
		String remoteAddr = request.getRemoteAddr();
		String remoteHost = request.getRemoteHost();
		int remotePort = request.getRemotePort();
		System.out.println("----> method="+method);
		System.out.println("----> requestURL="+requestURL);
		System.out.println("----> requestURI="+requestURI);
		System.out.println("----> contextPath="+contextPath);
		System.out.println("----> queryString="+queryString);	
		System.out.println("----> remoteAddr="+remoteAddr);
		System.out.println("----> remoteHost="+remoteHost);
		System.out.println("----> remotePort="+remotePort);
	}
	
	//获取请求的Header中的信息
	private void getRequestHeader(HttpServletRequest request){
		Enumeration<String> headerNames = request.getHeaderNames();
		while(headerNames.hasMoreElements()){
			String headKey=headerNames.nextElement();
			String headValue=request.getHeader(headKey);
			System.out.println(headKey+":"+headValue);
		}		
	}
}

代码写好了,我们现在通过浏览器发出请求:

http://localhost:8081/TestServlet03/helloServlet?name=lucy

在Console中观察输入结果:

----> method=GET
----> requestURL=http://localhost:8081/TestServlet03/helloServlet
----> requestURI=/TestServlet03/helloServlet
----> contextPath=/TestServlet03
----> queryString=name=lucy
----> name=lucy
----> remoteAddr=127.0.0.1
----> remoteHost=127.0.0.1
----> remotePort=63484
host:localhost:8081
connection:keep-alive
cache-control:max-age=0
accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
upgrade-insecure-requests:1
user-agent:Mozilla/5.0 (Windows NT 10.0;Win64; x64)Chrome/47.0.2526.111
accept-encoding:gzip, deflate, sdch
accept-language:zh-CN,zh;q=0.8

嗯哼,结合这些输出结果再回过头看这些方法就能有更好的体会。在此,再次强调一下:请注意getRequestURL()和getRequestURI()以及getContextPath()、getQueryString()这四个方法的区别

  • getRequestURL()返回的是请求的路径,但是不含请求的参数部分
  • getRequestURI()返回请求行中的资源名部分,但是不含有请求的主机和端口以及请求的参数部分
  • getContextPath()返回请求的上下文,即/+项目名称,比如此处的/TestServlet03

在前几篇博客中我们学习了Tomcat,Http,Servlet,HttpServletResponse在此基础上我们来深入学习Servlet的请求即HttpServletRequest

HttpServletRequest处理表单请求

在刚才的示例中,我们利用getParameter()获取GET请求中请求参数中的具体值,那么在POST请求时又该怎么获取传递给服务端的值呢?请看如下示例

先准备一个表单:

<!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>Welcome</title>
</head>
<body>
	<form action="/TestServlet03/form" method="post">
		用 户:<input type="text" name="username"/>
		      <br/><br/>
		密 码:<input type="password" name="password"/>
		     <br/><br/>
		性 别:<input type="radio" name="gender" value="" /><input type="radio" name="gender" value="" checked="checked"/><br/><br/>
		爱 好:<input type="checkbox" name="hobby" value="摄影"/>摄影
			 <input type="checkbox" name="hobby" value="唱歌"/>唱歌
			 <input type="checkbox" name="hobby" value="拍照"/>拍照
			 <br/><br/>
		城 市:
		<select name="city">
			<option>------请选择------</option>
			<option value="dj">东京</option>
			<option value="db">大阪</option>
			<option value="xt">仙台</option>
		</select>
		<br/><br/>
		<input type="submit" value="欢迎注册VIP会员"/>
	</form>
</body>
</html>

再实现服务端的代码:

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestForm extends HttpServlet{
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		testForm1(request);
	}

	private void testForm1(HttpServletRequest request)throws ServletException,IOException {
		request.setCharacterEncoding("UTF-8");
		Enumeration<String> parameterNames = request.getParameterNames();
		while(parameterNames.hasMoreElements()){
			String name = parameterNames.nextElement();
			String[] values = request.getParameterValues(name);
			for(int i=0;values!=null&&i<values.length;i++){
				System.out.println("name="+name+" "+"value="+values[i]);
			}
		}
	}
}

代码解析如下:

  • 利用setCharacterEncoding()设置编码方式
  • 利用getParameterNames()获取所有请求参数的名称,请参见代码第28行
    对于此处的表单POST提交而言传递的参数的名称分别为username,password,gender,hobby,city
  • 获取每个参数对于的值,请参见代码第29-35行

嗯哼,现在我们通过浏览器来发起一个请求:

这里写图片描述

在Console观察打印信息:

name=username value=杉原杏璃
name=password value=123456789
name=gender value=女
name=hobby value=摄影 name=hobby value=拍照
name=city value=dj

在实际开发中,我们可能需要将这些传递给服务端的信息封装成实体,请看如下示例:

先准备一个实体Entity:

/**
 * 本文作者:谷哥的小弟
 * 博客地址:http://blog.csdn.net/lfdfhl
 */
package cn.com;

import java.io.Serializable;
import java.util.Arrays;

public class User implements Serializable{
	private String username;
	private String password;
	private String gender;
	private String[] hobby;
	private String city;
	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;
	}
	public String getGender() {
		return gender;
	}
	public void setGender(String gender) {
		this.gender = gender;
	}
	public String[] getHobby() {
		return hobby;
	}
	public void setHobby(String[] hobby) {
		this.hobby = hobby;
	}
	public String getCity() {
		return city;
	}
	public void setCity(String city) {
		this.city = city;
	}
	@Override
	public String toString() {
		return "User [username=" + username + ", password=" + password
				+ ", gender=" + gender + ", hobby=" + Arrays.toString(hobby)
				+ ", city=" + city + "]";
	}
	
}

请注意,该实体中字段的名字必须与表单中各个name的值相对应

再来看服务端的代码:

private void testForm2(HttpServletRequest request)throws ServletException,IOException {
		try {
			request.setCharacterEncoding("UTF-8");
			User user = new User();
			Map<String,String[]> parameterMap = request.getParameterMap();
			for (Map.Entry<String, String[]> map : parameterMap.entrySet()) {
				String name = map.getKey();
				String[] values = map.getValue();
				PropertyDescriptor propertyDescriptor = new PropertyDescriptor(name, User.class);
				Method method = propertyDescriptor.getWriteMethod();
				if(values.length==1&&!name.equals("hobby")){
					method.invoke(user, values[0]);
				}else{
					method.invoke(user, (Object)values);
				}
			}
			
			System.out.println("------> "+user);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

代码解析如下:

  • 利用getParameterMap()得到请求中所有的参数及其对应的值,请参见代码第5行
    注意:有的参数只有一个值,比如该示例中的username;有的参数会有多个值,比如该示例中的hobby
  • 获取每个参数及其对应的值,请参见代码第7-8行
  • 反射出每个参数在实体中的setter()方法,请参见代码第9-10行
  • 设置每个参数对应的值,请参见代码第11-15行

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

我们知道:

  • 利用response.sendRedirect()实现请求的重定向
  • 利用request.getRequestDispatcher().forward()实现请求的转发

请注意它们的区别:

  • 重定向时浏览器中的地址栏会发生变化,但是请求转发时浏览器中地址栏不会发生改变。从本质上来讲:重定向是两次不同的请求,而请求转发只向服务端的发送了一次请求由服务端的内部实现请求的跳转。
  • 重定向可以跳转到应用的外部,而请求重定向的范围只能是应用的内部
  • 请求转发可利用request.setAttribute()将数据传递到下一个Servlet且下一个Servlet可用request.getAttribute()取出数据;但是重定向不可以也没有道理这么做。至于为什么,请参考第一点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
ServletJavaEE 规范中的一部分,是处理 Web 请求的组件。Servlet 运行在服务器端,能够接收客户端发来的请求,并给客户端响应结果。下面我们来看看 Servlet 的基本概念和使用方法。 ## 一、Servlet 的基本概念 ### 1.1 Servlet 的生命周期 Servlet 的生命周期包含以下三个阶段: - 初始化阶段(init):当 Servlet 实例化后,Web 容器会调用其 init() 方法进行初始化操作。在此阶段,Servlet 可以执行一些初始化操作,例如读取配置信息、建立数据库连接等。 - 请求处理阶段(service):当客户端发来请求时,Web 容器会创建一个线程调用 Servlet 的 service() 方法处理请求。在此阶段,Servlet 可以获取请求参数、处理请求并生成响应数据。 - 销毁阶段(destroy):当 Web 应用停止或 Servlet 被卸载时,Web 容器会调用 Servlet 的 destroy() 方法进行清理工作。在此阶段,Servlet 可以释放资源、关闭数据库连接等。 ### 1.2 Servlet 的配置 在使用 Servlet 时,需要在 web.xml 文件中进行配置。以下是一个 Servlet 的基本配置: ```xml <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>com.example.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/myservlet</url-pattern> </servlet-mapping> ``` 其中,servlet-name 表示 Servlet 的名称,servlet-class 表示 Servlet 的类名,url-pattern 表示请求的 URL 匹配规则。 ## 二、Servlet 的使用方法 ### 2.1 编写 Servlet 编写 Servlet 有两种方法:一种是继承 HttpServlet 类,另一种是实现 Servlet 接口。这里以继承 HttpServlet 类为例: ```java public class MyServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 处理 GET 请求 PrintWriter out = resp.getWriter(); out.println("Hello, world!"); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { // 处理 POST 请求 PrintWriter out = resp.getWriter(); out.println("Hello, world!"); } } ``` 在 Servlet 中,doGet() 方法用于处理 GET 请求,doPost() 方法用于处理 POST 请求。通过调用 HttpServletResponse 对象的 getWriter() 方法可以向客户端返回响应数据。 ### 2.2 部署 Servlet 将编写好的 Servlet 部署到 Web 容器中,有两种方法:一种是将 Servlet 类打成 war 包放到 Web 容器的 webapps 目录下,另一种是通过 Eclipse 等开发工具将 Servlet 部署到 Web 容器中。部署完成后,可以通过访问 Servlet 的 URL 来测试 Servlet 是否正常工作。 ## 三、总结 本文介绍了 Servlet 的基本概念和使用方法。ServletJava Web 开发中非常重要的组件,掌握 Servlet 的使用方法对于 Java Web 开发人员来说是必不可少的。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

谷哥的小弟

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

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

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

打赏作者

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

抵扣说明:

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

余额充值