/8 分钟/4 阅读/0 评论
servlet
所有请求信息 【请求的url ,请求方式,请求状态码, 请求端口】 所有请求信息 【请求的url (请求行),请求方式,请求状态码, 请求端口, 参数 】 页面准备 代码实现 补充: tomcat8 以上的版本都默认解决了get请求乱码问题
http协议介绍
学习目的:了解http协议的内容。
在request,请求,response 响应会涉及到协议的内容。
协议:双方的约定。
网络协议:计算机网络中进行数据交换而建立的规则、标准或约定等等。
http协议:超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。设计http的最初目的是为了提供一种发布和接受html页面的方法。
互联网数据交互一种规则。
http特点:
1、http协议是基于tcp协议的。属于应用层
2、默认端口是80(如果是80可以省略:80) 地址栏可以省略不写
http://www.baidu.com
http://www.baidu.com:80
3、基于请求响应模型。
请求:浏览器向服务器发送的信息,request
响应:服务器向浏览器发送的信息,response
请求和响应涉及到数据的发送。涉及到数据的格式。请求和响应的格式,满足http的规范。
查看http协议的内容方式:
ie:安装httpwatch
firefox(火狐):firebug可以查看
chrome(谷歌):自带

请求的组成说明
Post请求格式
所有请求信息 【请求的url ,请求方式,请求状态码, 请求端口】
请求行

请求头的信息

请求体: Post请求参数,以请求体的方式存在

Get请求格式
所有请求信息 【请求的url (请求行),请求方式,请求状态码, 请求端口, 参数 】
请求行

请求头

常见的http请求头中的参数说明
Accept: text/html,image/* 客户端识别文件类型
Accept-Charset: ISO-8859-1 客户端字符集
Accept-Encoding: gzip 客户端支持编码类型 gzip 压缩格式
Accept-Language:zh-cn 客户端语言
Host: www.yanqi.com:80 访问服务器地址
If-Modified-Since: Tue, 11 Jul 2000 18:23:51 GMT和
Last-Modified 一起使用 控制缓存 (tomcat 提供缓存 过滤器 缓存处理)
Referer: http://www.itcast.com/index.jsp (重要) 防止盗链 获取网站域名地址
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0) 浏览器类型(文件下载时,不同浏览器进行不同处理) 不同的浏览器器存在兼容性!!
Connection: close/Keep-Alive 请求后连接是关闭还是保持
Date: Tue, 11 Jul 2000 18:23:51 GMT 请求时间
在http1.1版本之后,一次连接可以发送多个请求。
在http1.0的时候,一次连接一次请求。
请求的http中post和get区别
1、post请求行,请求头,请求体
2、get请求行,请求头,没有请求体
3、post请求的参数在请求体中,理论上来说是无限大,安全性相对较高
4、get请求的参数在请求行中,通过url拼接,安全性相对较低
状态码
常见状态码:
200 - 请求成功
302 – 请求重定向 (response+302)==重定向
404 - 请求的资源(网页等)不存在 (请求的url找不到具体的资源,例如找不到servlet,或者html,如果遇到404的错误,通常检查url是否写错,或者url-patten 是否配置错。)
500 - 内部服务器错误(如果遇到500的情况,表示的是java代码出错误)
状态码分类

详细状态码



HttpServletRequest
获取请求头API
| getMethod() | 获取请求的方式 |
|---|---|
| getRequestURI() | 获取请求的uri(相对路径) |
| getRequestURL() | 获取请求的url(绝对路径) |
| getRemoteAddr() | 获取请求的地址 |
| getProtocol() | 获取请求的协议 |
| getRemotePort() | 获请请求的端口 |
| getHeader("Host"); | 获取请求的端口+地址 |
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("获取请求方式:"+request.getMethod());//GET
System.out.println("获取请求的相对路径:"+request.getRequestURI());// /ServletDemo
System.out.println("获取请求的绝对方式:"+request.getRequestURL());// http://localhost:8081/ServletDemo
System.out.println("获取http版本:"+request.getProtocol());// HTTP/1.1
System.out.println("获取客户端的ip:"+request.getRemoteAddr());// 10.50.5.137
System.out.println("获取当前请求地址+端口:"+request.getHeader("Host")); // 10.50.5.197:8081
}
获取请求参数 API
| public String getParameter(String name) | 获取请求指定单个参数 |
|---|---|
| public String[] getParameterValues(String name) | 获取请求指定多个参数 |
| public Map<String,String[]> request.getParameterMap() | 获取页面所有提交过来的数据 |
页面准备
<form action="ServletDemo2" method="post">
user:<input type="text" name="username"><br>
sex:<input type="text" name="sex"><br>
age:<input type="text" name="age"><br>
爱好:<input type="checkbox" name="hobby" value="吃饭">吃饭
<input type="checkbox" name="hobby" value="睡觉">睡觉
<input type="checkbox" name="hobby" value="打豆豆">打豆豆<br>
<input type="submit">
</form>
代码实现
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//指定获取输入框内容,如果获取不到返回null
String username = request.getParameter("username");
String sex = request.getParameter("sex");
String age = request.getParameter("age");
System.out.println(username);
System.out.println(sex);
System.out.println(age);
System.out.println("=========================");
//如果是复选框,获取的值很多,指定获取只能获取第一个
String hobby = request.getParameter("hobby");
System.out.println(hobby);
//request.getParameterValues("hobby"); 获取多个值
String[] hobbies = request.getParameterValues("hobby");
if(hobbies != null){
for(String str : hobbies){
System.out.println(str);
}
}
System.out.println("==========================");
//获取页面上所有提交的数据
Map<String, String[]> map = request.getParameterMap();
Set<String> set = map.keySet();
for(String key : set){
String[] values = map.get(key);
for(String value : values){
System.out.println(value);
}
}
}
post请求乱码的解决方案
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//解决post请求乱码问题
request.setCharacterEncoding("utf-8");
//指定获取输入框内容,如果获取不到返回null
String username = request.getParameter("username");
String sex = request.getParameter("sex");
String age = request.getParameter("age");
System.out.println(username);
System.out.println(sex);
System.out.println(age);
}
补充:
tomcat8 以上的版本都默认解决了get请求乱码问题,无需关注
转发

| public RequestDispatcher getRequestDispatcher(String path) | 转发 |
|---|
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//转发到指定页面
// request.getRequestDispatcher("index.jsp").forward(request,response);
//转发指定servlet
request.getRequestDispatcher("ServletDemo").forward(request,response);
}
域对象
什么是域对象
一个有作用范围的对象,可以在范围内共享数据
常见的域对象
* Request
* Session
* ServletContext(application)
域对象共有方法
| 方法 | 说明 |
|---|---|
| void setAttribute(String name,Object obj) | 设置数据 |
| Object getAttribute(String name) | 获取数据 |
| void removeAttribute(String name) | 删除数据 |
Request域
代表一次请求的范围,一般用于一次请求中转发的多个资源中共享数据
@WebServlet("/aServlet")
public class AServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("去就AServlet");
//向request域对象中 存一个数据
request.setAttribute("hanbao", "香辣鸡腿堡");
// 链式编程横
request.getRequestDispatcher("bServlet").forward(request, response);
}
}
@WebServlet("/bServlet")
public class BServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("我就BServlet");
//向request域对象中 获取数据
String hanbao = (String) request.getAttribute("hanbao");
System.out.println("hanbao:" + hanbao);
}
}
ServletContext域
@WebServlet("/oneServlet")
public class OneServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 向servletContext域存数据
ServletContext sc1 = request.getServletContext();
sc1.setAttribute("user", "jack");
System.out.println("我是oneServlet");
}
}
@WebServlet("/twoServlet")
public class TwoServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doPost(request, response);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 从servletContext域获取数据
String user = (String) request.getServletContext().getAttribute("user");
System.out.println("twoServlet获取数据:"+user);
}
}
- ServletContext生命周期
1. 何时创建?
项目加载时,创建
2. 何时销毁?
项目卸载时,销毁
3. 作用范围?
与项目共存亡(多个servlet都可以操作它)
HttpServletResponse
常用API
| public void setStatus(int status) | 设置响应状码 |
|---|---|
| public void [setHeader](mk:@MSITStore:F:\api\java_ee_api_中英文对照版.chm::/javax/servlet/http/HttpServletResponse.html#setHeader(java.lang.String, java.lang.String))(String name,String value) |
设置响应该头 |
重定向

重定向:一次请求,两次响应,把上一个url清空,重新响应了一个新的url,最终看到是新的url
重定向不能返回上一个url
实现方式:
1:状态码302+响应地址
2:response.sendRedirect()
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//重定向
response.setStatus(302);
response.setHeader("Location","http://localhost:8081/index.jsp");
//这种方法等价于以上两行代码
response.sendRedirect("http://localhost:8081/index.jsp");
}
重定向和转发的区别
重定向(redirect): 一次请求两个url,url会在地址栏中显示,属于客户端型行为,不能返回历史记录
转 发(forward): 一次请求一个url,url地址始终只有一个,属于服务器型行为
设置响应体
| setContentType(String charset) | 设置响应字符集(解决响应乱码问题) |
|---|---|
| getWriter() | 把响应内容以流的形式输出(响应给浏览器) |
| getHeader() | 设置响应头 |
响应浏览内容
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应体及响应乱码
response.setContentType("text/html;charset=utf-8");
//响应给浏览器
PrintWriter writer = response.getWriter();
writer.println("<h2>servlet是动态网页技术</h2>");
writer.println("<font style='color:red'>servlet高大尚</font>");
response.getWriter().println("哈哈哈,我是从后台servlet响应给浏览器的");
}
解决响应乱码问题
//设置响应体及响应乱码
response.setContentType("text/html;charset=utf-8");
自动刷新
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//设置响应体及响应乱码
response.setContentType("text/html;charset=utf-8");
response.getWriter().println("对不起,你访问的资源不存在,3秒之后跳转到yiyan网站!!");
response.setHeader("refresh","3;url=https://www.baidu.com");
}
生成图片验证码
servlet代码
package cn.yanqi.web;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
/**
* @Auther: yanqi
* @Desc
*/
@WebServlet(urlPatterns = "/Checkcode")
public class Checkcode extends HttpServlet {
private static final int WIDTH = 100;//设置验证码图片宽度
private static final int HEIGHT = 30;//设置验证码图片高度
private static final int LENGTH = 4;//设置验证码长度
public static final int LINECOUNT=20;//干扰线的数目
//验证码的字符库
private static final String str="0123456789"+
"ABCDEFGHIJKLMNOPQRSTUVWXYZ"+
"abcdefghijklmnopqrstuvwxyz";
//通过随机数取字符库中的字符组合成4位验证码
private static Random random=new Random();
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//设置数据类型为图片
resp.setContentType("image/jpeg");
//设置不进行缓存
resp.setHeader("pragma", "no-cache");
resp.setHeader("cache-control", "no-cache");
resp.setHeader("expires", "0");
//获取画笔
BufferedImage image=new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_3BYTE_BGR);
Graphics g=image.getGraphics();
//设置背景颜色并绘制矩形背景
g.setColor(Color.WHITE);
g.fillRect(0, 0, WIDTH, HEIGHT);
//验证码的绘制
String code=drawChar(g);
System.out.println("验证码:"+code);
//随机线的绘制
for (int i=0;i<LINECOUNT;i++){
drawLine(g);
}
//在session中存入当前的code码,便于验证
req.getSession().setAttribute("code",code);
//绘制图片
g.dispose();
//将图片输出到response中
ImageIO.write(image, "JPEG", resp.getOutputStream());
}
//获取不同颜色
public Color getColor(){
return new Color(random.nextInt(255), random.nextInt(255), random.nextInt(255));
}
//获取字体样式
public Font getFont() {
return new Font("Fixedsys", Font.CENTER_BASELINE, 20);
}
//绘制字符
public String drawChar(Graphics g){
String code="";
g.setFont(getFont());
for (int i=0;i<LENGTH;i++){
char c=str.charAt(random.nextInt(str.length()));
g.setColor(getColor());
g.drawString(c+"", 20* i + 10, 20);
code=code+c;
}
return code;
}
//绘制随机线
public void drawLine(Graphics g) {
int x = random.nextInt(WIDTH);
int y = random.nextInt(HEIGHT);
int xl = random.nextInt(13);
int yl = random.nextInt(15);
g.setColor(getColor());
g.drawLine(x, y, x + xl, y + yl);
}
}
JS代码
<form action="ServletDemo2" method="post">
user:<input type="text" name="username"><br>
sex:<input type="text" name="sex"><br>
age:<input type="text" name="age"><br>
爱好:<input type="checkbox" name="hobby" value="吃饭">吃饭
<input type="checkbox" name="hobby" value="睡觉">睡觉
<input type="checkbox" name="hobby" value="打豆豆">打豆豆<br>
验证码:<input type="text" name="ckimg">
<img src="/Checkcode" id="_img"><br>
<input type="submit">
</form>
<script>
window.onload = function () {
var _img = document.getElementById("_img");
_img.onclick = function () {
var date = new Date();
_img.src ="/Checkcode?"+date.getTime();
};
}
</script>
JAVA代码
//获取用户输入的验证码
String _img = request.getParameter("ckimg");
//获取服务器生成的验证码
HttpSession session = request.getSession();
String code = (String) session.getAttribute("code");
//为了保证验证是有效的唯一,把上一个给清了
session.removeAttribute("code");
//判断
if(!_img.equalsIgnoreCase(code)){
//提示用户
request.setAttribute("msg","验证码不正确!");
request.getRequestDispatcher("/login.jsp").forward(request,response);
return;
}