Servlet学习笔记
目录
一、Service是什么?
Servlet是处理客户端请求与响应的一组API
二、使用步骤
1.引入库
导入servlet-aip.jar包
三、关系图
四、Request
1.1Request概述
1.1.1Request的概念
在Servlet API中,定义了一个HttpServletRequest接口,它继承自ServletRequest接口,专门用来封装HTTP请求消息。由于HTTP请求消息分为请求行、请求头和请求体三部分,因此,在HttpServletRequest接口中定义了获取请求行、请求头和请求消息体的相关方法.
用我们自己的话来理解: Request就是服务器中的一个对象,该对象中封装了HTTP请求的请求行、请求头和请求体的内容
1.1.2Request的组成
- 请求行: 包含请求方式、请求的url地址、所使用的HTTP协议的版本
- 请求头: 一个个的键值对,每一个键值对都表示一种含义,用于客户端传递相关的信息给服务器
- 请求体: POST请求有请求体,里面携带的是POST请求的参数,而GET请求没有请求体
1.1.3Request的作用
- 获取HTTP请求三部分内容(行,头,体)
- 进行请求转发跳转
- 作为请求域对象进行存取数据1.2
1.2Request获取HTTP请求的内容
1.2.1获取请求的API
- getMethod();获取请求方式
- getContextPath(); 获得当前应用上下文路径
- getRequestURI();获得请求地址,不带主机名
- getRequestURL();获得请求地址,带主机名
//继承HttpService类
public class ServletDemo01 extends HttpServlet {
//重写doPost,doGet方法
//处理post请求
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//可以post请求时调用doGet
doGet(request, response);
}
//处理get请求
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//使用request对象获取请求行的信息:
//1. 获取请求的方式(可能会用)
String method = request.getMethod();
//System.out.println("请求方式为:" + method);;
//2. 获取请求的url: 统一资源定位符 http://localhost:8080/requestDemo/demo01
String url = request.getRequestURL().toString();
//System.out.println("此次请求的url是:" + url);
//3. 获取请求的uri: 统一资源标识符,在url的基础上省略了服务器路径"http://loaclhost:8080"
String uri = request.getRequestURI();
System.out.println(uri);
}
}
1.2.2获取请求参数的API
方法名 | 返回值类型 | 方法描述 |
---|---|---|
request.getParameterMap() | Map<String, String[]> | 获取当前请求的所有参数,以键值对的方式存储到Map中 |
request.getParameter("请求参数的名字") | String | 根据一个参数名获取一个参数值 |
request.getParameterValues("请求参数的名字") | String [] | 根据一个参数名获取多个参数值 |
request.getParameterNames() | Enumeration<String> | 获取当前请求的所有参数的参数名 |
HTML代码
<!-- 测试请求参数的表单 -->
<form action="/orange/ParamServlet" method="post">
<!-- 单行文本框 -->
<!-- input标签配合type="text"属性生成单行文本框 -->
<!-- name属性定义的是请求参数的名字 -->
<!-- 如果设置了value属性,那么这个值就是单行文本框的默认值 -->
个性签名:<input type="text" name="signal" value="单行文本框的默认值" /><br/>
<!-- 密码框 -->
<!-- input标签配合type="password"属性生成密码框 -->
<!-- 用户在密码框中填写的内容不会被一明文形式显示 -->
密码:<input type="password" name="secret" /><br/>
<!-- 单选框 -->
<!-- input标签配合type="radio"属性生成单选框 -->
<!-- name属性一致的radio会被浏览器识别为同一组单选框,同一组内只能选择一个 -->
<!-- 提交表单后,真正发送给服务器的是name属性和value属性的值 -->
<!-- 使用checked="checked"属性设置默认被选中 -->
请选择你最喜欢的季节:
<input type="radio" name="season" value="spring" />春天
<input type="radio" name="season" value="summer" checked="checked" />夏天
<input type="radio" name="season" value="autumn" />秋天
<input type="radio" name="season" value="winter" />冬天
<br/><br/>
你最喜欢的动物是:
<input type="radio" name="animal" value="tiger" />路虎
<input type="radio" name="animal" value="horse" checked="checked" />宝马
<input type="radio" name="animal" value="cheetah" />捷豹
<br/>
<!-- 多选框 -->
<!-- input标签和type="checkbox"配合生成多选框 -->
<!-- 多选框被用户选择多个并提交表单后会产生『一个名字携带多个值』的情况 -->
你最喜欢的球队是:
<input type="checkbox" name="team" value="Brazil"/>巴西
<input type="checkbox" name="team" value="German" checked="checked"/>德国
<input type="checkbox" name="team" value="France"/>法国
<input type="checkbox" name="team" value="China" checked="checked"/>中国
<input type="checkbox" name="team" value="Italian"/>意大利
<br/>
<!-- 下拉列表 -->
<!-- 使用select标签定义下拉列表整体,在select标签内设置name属性 -->
你最喜欢的运动是:
<select name="sport">
<!-- 使用option属性定义下拉列表的列表项 -->
<!-- 使用option标签的value属性设置提交给服务器的值,在option标签的标签体中设置给用户看的值 -->
<option value="swimming">游泳</option>
<option value="running">跑步</option>
<!-- 使用option标签的selected="selected"属性设置这个列表项默认被选中 -->
<option value="shooting" selected="selected">射击</option>
<option value="skating">溜冰</option>
</select>
<br/>
<br/><br/>
<!-- 表单隐藏域 -->
<!-- input标签和type="hidden"配合生成表单隐藏域 -->
<!-- 表单隐藏域在页面上不会有任何显示,用来保存要提交到服务器但是又不想让用户看到的数据 -->
<input type="hidden" name="userId" value="234654745" />
<!-- 多行文本框 -->
自我介绍:<textarea name="desc">多行文本框的默认值</textarea>
<br/>
<!-- 普通按钮 -->
<button type="button">普通按钮</button>
<!-- 重置按钮 -->
<button type="reset">重置按钮</button>
<!-- 表单提交按钮 -->
<button type="submit">提交按钮</button>
</form>
JAVA代码
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doPost(request,response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 获取包含全部请求参数的Map
Map<String, String[]> parameterMap = request.getParameterMap();
// 遍历这个包含全部请求参数的Map
Set<String> keySet = parameterMap.keySet();
for (String key : keySet) {
String[] values = parameterMap.get(key);
System.out.println(key + "=" + Arrays.asList(values));
}
System.out.println("---------------------------");
// 根据请求参数名称获取指定的请求参数值
// getParameter()方法:获取单选框的请求参数
String season = request.getParameter("season");
System.out.println("season = " + season);
// getParameter()方法:获取多选框的请求参数
// 只能获取到多个值中的第一个
String team = request.getParameter("team");
System.out.println("team = " + team);
// getParameterValues()方法:取单选框的请求参数
String[] seasons = request.getParameterValues("season");
System.out.println("Arrays.asList(seasons) = " + Arrays.asList(seasons));
// getParameterValues()方法:取多选框的请求参数
String[] teams = request.getParameterValues("team");
System.out.println("Arrays.asList(teams) = " + Arrays.asList(teams));
}
1.3解决获取请求参数乱码
可以在doGet、doPost、service方法中添加下面两行代码来解决乱码问题
resp.setContentType("text/html;charset=utf-8");
req.setCharacterEncoding("UTF-8");
1.4请求转发
1.4.1什么是请求转发
请求转发是从一个资源跳转到另一个资源,在这个过程中客户端不会发起新的请求
1.4.2请求转发的入门案例
1.4.2.1案列目标
从ServletDemo01使用请求转发的方式跳转到ServletDemo02
1.4.2.2 请求转发的API
request.getRequestDispatcher("路径").forward(request,response);
1.4.2.3案例代码
ServletDemo01的代码
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo01执行了...")
//请求转发跳转到ServletDemo02
request.getRequestDispatcher("/demo02").forward(request, response);
}
}
ServletDemo01的代码
public class ServletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo02执行了...")
}
}
1.4.3请求转发的特征
- 请求转发的跳转是由服务器发起的,在这个过程中浏览器只会发起一次请求
- 请求转发只能跳转到本项目的资源,但是可以跳转到WEB-INF中的资源
- 请求转发不会改变地址栏的地址
1.5请求域对象
1.5.1请求域范围
我们之前学过全局域的范围,全局域是整个项目范围的所有动态资源都能够共享的一个范围;而请求域的范围只是在一次请求中的动态资源能够共享的一个范围
1.5.2 请求域对象的API
-
往请求域中存入数据:
request.setAttribute(key,value)
-
从请求域中取出数据:
request.getAttribute(key)
1.5.3 请求域对象案例
1.5.3.1 案例目标
在ServletDemo01中往请求域中存入"username"作为key,"aobama"作为值的键值对;然后在ServletDemo02中从请求域中根据"username"取出对应的值
1.5.3.2 使用请求域的前提
请求域对象一定要和请求转发一起使用,因为请求域的范围是一次请求范围内,所以要在两个动态资源中使用请求域必须要进行请求转发跳转
1.5.3.3 案例代码
ServletDemo01的代码
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo01执行了...")
String username = "aobama";
//将username存储到request域对象中
request.setAttribute("name",username);
//请求转发跳转到ServletDemo02
request.getRequestDispatcher("/demo02").forward(request, response);
}
}
ServletDemo02的代码
public class ServletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = (String)request.getAttribute("name");
System.out.println("在ServletDemo02中获取username:"+username)
}
}
五、Response
1.1Response的概述
1.1.1 Response的概念
在Servlet API中,定义了一个HttpServletResponse接口(doGet,doPost方法的参数),它继承自ServletResponse接口,专门用来封装HTTP响应消息。由于HTTP响应消息分为响应行、响应头、响应体三部分,因此,在HttpServletResponse接口中定义了向客户端发送响应状态码、响应头、响应体的方法
用我们自己的话说: Response就是服务器端一个对象,它里面可以封装要响应给客户端的响应行、头、体的信息
1.1.2 Response的组成部分
-
响应行: 包含响应状态码、状态码描述信息、HTTP协议的版本
-
响应头: 一个个的键值对,每一个键值对都包含了具有各自含义的发送给客户端的信息
-
响应体: 用于展示在客户端的文本、图片,或者供客户端下载或播放的内容
1.1.3 Response的作用
-
设置响应行的信息,主要是设置响应状态码
-
设置响应头的信息
-
设置响应体的信息
1.2 使用Response向客户端输出字符串
1.2.1 输出字符串的API
//1. 获取字符输出流
PrintWriter writer = response.getWriter();
//2. 输出内容
writer.write("hello world");
1.2.2 响应数据乱码问题
由于服务器端在输出内容的时候进行编码使用的字符集和客户端进行解码的时候使用的字符集不一致,所以会发生响应数据乱码问题。 我们解决响应数据乱码问题只需要在获取字符输出流之前,执行如下代码就可以了:
response.setContentType("text/html;charset=UTF-8");
1.3 使用response向客户端响应一个文件
1.3.1 使用字节输出流的API
ServletOutputStream os = response.getOutputStream();
1.3.2 案例目标
在ServletDemo01中使用response向浏览器输出一张图片
1.3.3 案例代码
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决响应内容的乱码问题
//response.setContentType("text/html;charset=UTF-8");
//System.out.println("hello world");
//response就是服务器端要发送给客户端的响应内容,它里面包含三部分: 响应行、头、体
//1. 设置响应行的内容:
//设置响应的状态码,但是一般情况下我们不需要设置状态码,因为服务器会自动设置状态码
//response.setStatus(404);
//2. 设置响应头信息: setHeader("name","value");
//3. 设置响应体的信息: 响应体就是显示在浏览器的数据
//3.1 通过字符流往浏览器输出文本内容
//response.getWriter().write("<h1>你好世界...</h1>");
//3.2 使用字节流往浏览器输出一张图片
//首先设置响应数据的mime-type
//第一步: 使用字节输入流读取那张图片
//使用ServletContext获取资源的真实路径
String realPath = getServletContext().getRealPath("img/mm.jpg");
InputStream is = new FileInputStream(realPath);
//第二步: 使用字节输出流,将图片输出到浏览器
ServletOutputStream os = response.getOutputStream();
//边读编写
int len = 0;
byte[] buffer = new byte[1024];
while ((len = is.read(buffer)) != -1){
os.write(buffer,0,len);
}
os.close();
is.close();
}
}
1.4 重定向
1.4.1 什么是重定向
重定向是由项目中的一个资源跳转到另一个资源,在这个过程中客户端会发起新的请求
1.4.2 重定向的入门案例
1.4.2.1 案例目标
从ServletDemo01重定向跳转到ServletDemo02
1.4.2.2 重定向的API
response.sendRedirect("路径");
1.3.2.3 案例代码
ServletDemo01的代码
public class ServletDemo01 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("ServletDemo01执行了...")
//请求转发跳转到ServletDemo02
response.sendRedirect("/app/demo02");
}
}
ServletDemo02的代码
public class ServletDemo02 extends HttpServlet {
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("在ServletDemo02执行了.....")
}
}
2.4.3 重定向的特征
-
重定向的跳转是由浏览器发起的,在这个过程中浏览器会发起两次请求
-
重定向跳转可以跳转到任意服务器的资源,但是无法访问WEB-INF中的资源
-
重定向跳转浏览器的地址栏中的地址会变成跳转到的路径
2.5 重定向和请求转发的对比
-
重定向会由浏览器发起新的请求,而请求转发不会发起新的请求
-
重定向可以访问任意互联网资源,而请求转发只能访问本项目资源
-
重定向不能访问本项目的WEB-INF内的资源,而请求转发可以访问本项目的WEB-INF内的资源
-
发起重定向的资源和跳转到的目标资源没在同一次请求中,所以重定向不能在请求域中使用;而发起请求转发的资源和跳转到的目标资源在同一次请求中,所以请求转发可以在请求域中使用
总结
以上就是今天要讲的内容,本文仅仅简单介绍了selves的使用。