Javaweb-Servlet-day02
思考:如何在登录成功后显示一个网页而不是一段文本
转发与重定向
转发:将请求从一个地方转到另一个地方
重定向:重新将请求定位到另一个资源
转发与重定向的区别
1.转发不会改变地址栏,重定向会
2.转发只发送一个请求,重定向是两次请求
3.转发操作请求,重定向操作重定向
4.转发可以获取request作用域数据,重定向不能
5.转发只能转发服务器已有的资源,重定向可以重定向到外部资源
Servlet中的三种作用域
- request:请求作用域
- 作用在request范围内,每一个request都有一个独立的作用域名,相互之间不共享
- seesion:会话作用域
- 作用在session范围内,可以在多个request之间共享数据,但不能在多个session中共享数据
- application:应用作用域(全局作用域)
作用在整个应用范围内,多个session
//向request作用域放数据
req.setAttribute("k1", "request作用域存放的数据");
//向session作用域放数据
req.getSession().setAttribute("k2", "session作用域存放的数据");
//向application作用域放数据
req.getServletContext().setAttribute("k3", "application作用域存放的数据");
// 从request作用域取数据
System.out.println("request:" + req.getAttribute("k1"));
// 从request作用域取数据
System.out.println("session:" + req.getSession().getAttribute("k2"));
// 从application作用域取数据
System.out.println("application:" + req.getServletContext().getAttribute("k3"));
Http协议响应状态码
什么是Http?
Http是一种无状态协议。
Http构成:
- 请求
-
请求行:存储请求的url
-
请求头:浏览器信息、系统信息、cookie、请求类型…
-
请求体:例如:上传文件的文件数据、POST请求的数据
- 响应
-
响应状态码:正常:200
-
响应头:响应内容类型、下载文件时文件的文件名,下载文件的长度
-
响应体:响应的正文(写回的数据、下载的文件的数据)
获取请求头及设置响应状态码
响应状态码:用来描述本次请求的状态
- 1xx:消息,表示服务收到请求,正在处理
- 2xx:成功,表示请求成功处理,且无异常
- 3xx:重定向
- 302:重定向
- 304:缓存
- 4xx:请求错误
- 400:bad request,请求参数与服务器预期参数不一致
- 403:无权限访问
- 404:资源不存在
- 405:请求不匹配
- 5xx:服务器错误
- 500:;服务器报错了
Ctrl+F5强制刷新浏览器
思考:能不能不通过resp.sendRedirect实现重定向?
可以
-
设置状态响应码为302
-
响应头添加Location:重定向地址
获取请求头:
String cookie = req.getHeader(“Cookie”);
设置响应头:
resp.addHeader(“Location”,“index.html”);
resp.setStaus(302);
resp.setHeader(“”,“”);
思考:Servlet是单例多线程,还是多例单线程的?
单例多线程
思考:Servlet是在什么时候被创建对象的
默认是在第一次访问时创建
loadOnStartup为负数时,表示第一次访问对象
loadOnStartup为整数时,表示在tomcat启动时创建,值越小,创建时间越早
get与post的区别
-
get会将表单数据放到地址栏(请求行),post不会(请求体)
-
get请求相对post请求快
-
get请求相对没那么安全,post请求更安全
-
get请求参数携带有上限,post请求理论上可以无上限
什么时候用get,什么时候用post
如果请求携带密码等重要数据,用post,否则用get
Servlet中对get请求和post请求的处理
doget
dopost
service
建议优先使用service
补充:
1. *简述题:**BS和 CS结构区别**?*
C/S: Client/Server 客户端/服务器端
特点:
充分发挥客户端PC的处理能力,很多数据可以通过客户端的处理后再发给服务器,降低了服务器的负荷,提高了速度。但维护和升级比较复杂,维护和升级是针对成千上万的客户机的。
必须安装专用的客户端软件。客户端是成千上万的,要安装专用软件,是多么大的工作量,如果一台客户机出现了问题,如:感染病毒、计算机故障等等原因,都需要进行安装或维护。系统软件需要升级的时候,每一台客户机都需要重新安装系统软件,维护和升级成本相当的高。
Browser/Server 浏览器/服务器端
B/S: 特点:
维护和升级简单,我们只要对服务器端进行维护和升级即可,不需要对成千上万的客服端进行维护和升级,减少了人力资源成本。
随时随地都可以访问,只要有一台连接互联网和安装了浏览器的计算机就可以访问。减轻了客户端电脑载荷,客户端电脑只要运行少部分程序就能实现。因此对客服端电脑要求不高,对服务器端负荷较重,由于主要的功能都集中到了服务器端,因此对服务器要求高,但总体而言,还是大大降低了成本。
总结:B/S对C/S而言,B/S具有的优势。
分布性:可以随时随地进行查询和浏览等业务;
功能业务扩展比较方便:增加服务器的功能,就能增加浏览器端的功能;
维护简单方便:改变服务器端数据即可以实现所有用户同步更新;
开发简单,共享性强,成本低,数据可以持久存储在服务器端而不必担心数据的丢失
2. *简述题:Web资源分类?*
静态资源: 使用静态网页开发技术发布的资源
特点:
所有用户访问,得到的结果是一样的,如:文本,图片,音频、视频, HTML,CSS,JavaScript
如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器。浏览器中内置了静态资源的解析引擎,可以展示静态资源
动态资源:使用动态网页技术发布的资源
特点:
所有用户访问,得到的结果可能不一样,如:jsp/servlet,php,asp…
如果用户请求的是动态资源,那么服务器会执行动态资源,转换为静态资源,再发送给浏览器
3. *简述题:网络通信三要素?*
IP:电子设备(计算机)在网络中的唯一标识
端口:应用程序在计算机中的唯一标识。 0~65536
传输协议:规定了数据传输的规则
基础协议:
tcp:安全协议,三次握手。 速度稍慢
udp:不安全协议。 速度快
高级协议
http协议
基于TCP/IP的高级协议
基于请求/响应模型的:一次请求对应一次响应
4. *简述题:常见的web服务器软件有哪些?Tomcat的缺省端口是多少?*
webLogic:oracle公司,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。 webSphere:IBM公司, 大型的JavaEE服务器,支持所有的JavaEE规范,收费的。 JBOSS:JBOSS公司的,大型的JavaEE服务器,支持所有的JavaEE规范,收费的。 Tomcat:Apache基金组织,中小型的JavaEE服务器,仅仅支持少量的JavaEE规范 servlet/jsp。开源的,免费的。缺省端口是8080。
1. *简述**servlet的生命周期及常用方法**。*
Servlet中的生命周期方法:
1. 被创建:执行init方法,只执行一次
* Servlet什么时候被创建?
* 默认情况下,第一次被访问时,Servlet被创建
2. 提供服务:执行service方法,执行多次
* 每次访问Servlet时,Service方法都会被调用一次。
\3. 被销毁:执行destroy方法,只执行一次
* Servlet被销毁时执行。服务器关闭时,Servlet被销毁
* 只有服务器正常关闭时,才会执行destroy方法。
* destroy方法在Servlet被销毁之前执行,一般用于释放资源
2. *简述题:http常见的状态码有哪些。*
\1. 200 OK 客户端请求成功
\2. 301Moved Permanently(永久移除),请求的URL已移走。Response中应该包含一个 Location URL,说明资源现在所处的位置
\3. 302found 重定向
\4. 400Bad Request 客户端请求有语法错误,不能被服务器所理解
\5. 401Unauthorized 请求未经授权,这个状态代码必须和WWW-Authenticate报头域一起使用
\6. 403 Forbidden 服务器收到请求,但是拒绝提供服务
\7. 404 Not Found 请求资源不存在,eg:输入了错误的URL
\8. 500 Internal Server Error 服务器发生不可预期的错误
\9. 503 Server Unavailable 服务器当前不能处理客户端的请求,一段时间后可能恢复正常
3. *简述题:* *GET和POST的区别?*
1.url可见性:
get,参数url可见
post,url参数不可见
get把请求的数据放在url上,即HTTP协议头上,其格式为:以?分割URL和传输数据,参数之间以&相连;post把数据放在HTTP的包体内(requrest body)
2.传输数据的大小:
get一般传输数据大小不超过2k-4k
post请求传输数据的大小根据php.ini 配置文件设定,也可以无限大
get提交的数据最大是2k(原则上url长度无限制,那么get提交的数据也没有限制咯?限制实际上取决于浏览器,浏览器通常都会限制url长度在2K个字节,即使(大多数)服务器最多处理64K大小的url,也没有卵用);
post理论上没有限制。实际上IIS4中最大量为80KB,IIS5中为100KB
3.数据传输上:
get,通过拼接url进行传递参数
post,通过body体传输参数
GET产生一个TCP数据包,浏览器会把http header和data一并发送出去,服务器响应200(返回数据);
POST产生两个TCP数据包,浏览器先发送header,服务器响应100 continue,浏览器再发送data,服务器响应200 ok(返回数据)
5.缓存性:
get请求是可以缓存的
post请求不可以缓存
**GET请求会被浏览器主动cache,而POST不会,除非手动设置
6.安全性:
都不安全,原则上post肯定要比get安全,毕竟传输参数时url不可见,但也挡不住部分人闲的没事在那抓包玩,浏览器还会缓存get请求的数据。安全性个人觉得是没多大区别的,防君子不防小人就是这个道理。对传递的参数进行加密,其实都一样
4. *简述题:http中重定向和请求转发的区别。*
本质区别:转发是服务器行为,重定向是客户端行为。
重定向特点:两次请求,浏览器地址发生变化,可以访问自己web之外的资源,传输的数据会丢失。
请求转发特点:一次强求,浏览器地址不变,访问的是自己本身的web资源,传输的数据不会丢失
5. *简述题:* *http的长连接和短连接区别?*
HTTP协议有HTTP/1.0版本和HTTP/1.1版本。HTTP1.1默认保持长连接(HTTP persistent connection,也翻译为持久连接),数据传输完成了保持TCP连接不断开(不发RST包、不四次握手),等待在同域名下继续用这个通道传输数据;相反的就是短连接。
在HTTP/1.0 中,默认使用的是短连接。也就是说,浏览器和服务器每进行一次HTTP操作,就建立一次连接,任务结束就中断连接。从HTTP/1.1起,默认使用的是长连接,用以保持连接特性。
JSP
什么是JSP?
JSP全称是:Java Server Pages,是一种用来代替Servlet的技术,其本质是一个Servlet,JSP允许同时编写Java代码和Html代码,使用JSP既可以显示界面,又可以动态获取Java中的数据。
JSP如何编写
LoginServlet改造后
package com.blb.servlet;
import com.blb.entity.User;
import com.blb.service.IUserService;
import com.blb.service.impl.UserServiceImpl;
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.io.IOException;
@WebServlet("/login")
public class LoginServlet extends HttpServlet {
IUserService userService = new UserServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF8");
resp.setCharacterEncoding("UTF8");
resp.setContentType("text/html;charset=UTF8");
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
try {
User user = userService.login(name, pwd);
req.getSession().setAttribute("user", user);
resp.getWriter().write("欢迎您:" + name);
} catch (Exception e) {
e.printStackTrace();
// resp.sendRedirect("login_err.html");
//向request作用域存放数据
req.setAttribute("msg",e.getMessage());
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
}
RegisterServlet改造后
package com.blb.servlet;
import com.blb.service.impl.UserServiceImpl;
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.io.IOException;
@WebServlet("/register")
public class RegisterServlet extends HttpServlet {
UserServiceImpl userService = new UserServiceImpl();
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// super.service(req, resp);
req.setCharacterEncoding("UTF8");
resp.setCharacterEncoding("UTF8");
resp.setContentType("text/html;charset=UTF8");
String name = req.getParameter("name");
String pwd = req.getParameter("pwd");
try {
userService.register(name, pwd);
// resp.sendRedirect("register_success.html");
resp.sendRedirect("login.jsp");
} catch (Exception e) {
e.printStackTrace();
// resp.getWriter().write("注册失败:" + e.getMessage());
// resp.sendRedirect("register_err.html");
//向request作用域存放数据
req.setAttribute("msg", e.getMessage());
req.getRequestDispatcher("register.jsp").forward(req,resp);
}
}
}
login.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登录</title>
</head>
<body>
<h1>登录用户</h1>
<form action="login" method="post">
<input name="name">
<input name="pwd">${msg}
<button>登录</button>
<a href="register.jsp">没有账号?去注册</a>
</form>
</body>
</html>
register.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>register</title>
</head>
<body>
<h1>注册用户</h1>
<form action="register" method="post">
<input name="name">
<input name="pwd">${msg}
<button>注册</button>
<a href="login.jsp">已有账号?去登录</a>
</form>
</body>
</html>
t_user.sql
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 80026
Source Host : localhost:3306
Source Schema : db5
Target Server Type : MySQL
Target Server Version : 80026
File Encoding : 65001
Date: 23/08/2022 10:17:30
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`id` int NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`pwd` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` VALUES (1, 'yuexi', '1');
INSERT INTO `t_user` VALUES (2, '希', '555');
INSERT INTO `t_user` VALUES (5, 'Juuga', '8888');
INSERT INTO `t_user` VALUES (6, 'vice', '857');
INSERT INTO `t_user` VALUES (7, 'ajileila', '857');
INSERT INTO `t_user` VALUES (8, '阿基蕾拉', '857');
INSERT INTO `t_user` VALUES (9, '灭', '857');
SET FOREIGN_KEY_CHECKS = 1;
JSP原理
JSP在运行时会编译成.java文件,再编译成class文件,最后在运行。
jsp中的静态代码会被编译成outer.write()的方式输出出来
demo.jsp
<%--
Created by IntelliJ IDEA.
User: 汐月曦
Date: 2022/8/23
Time: 10:19
To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>Hello JSP</h1>
<input value="6666666666">
</body>
</html>
通过启动tomcat生成的日志
例如
Using CATALINA_BASE: "C:\Users\汐月曦\.IntelliJIdea2019.3\system\tomcat\Unnamed_Java20220823-jsp-day03_3"
Using CATALINA_HOME: "C:\environment\apache-tomcat-8.5.82"
Using CATALINA_TMPDIR: "C:\environment\apache-tomcat-8.5.82\temp"
Using JRE_HOME: "C:\Program Files\Java\jdk1.8.0_202"
Using CLASSPATH: "C:\environment\apache-tomcat-8.5.82\bin\bootstrap.jar;C:\environment\apache-tomcat-8.5.82\bin\tomcat-juli.jar"
中的
Using CATALINA_BASE: 指定的位置找到demo.jsp编译后的源码
这个源码必须在执行完对应的操作后,才能生成对应的源码
如:http://localhost:8080/demo.jsp
才会生成demo_jsp.java
例如:
C:\Users\汐月曦\.IntelliJIdea2019.3\system\tomcat\Unnamed_Java20220823-jsp-day03_3\work\Catalina\localhost\ROOT\org\apache\jsp
找到demo_jsp.java文件
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/8.5.82
* Generated at: 2022-08-23 02:21:37 UTC
* Note: The last modified time of this file was set to
* the last modified time of the source file after
* generation to assist with modification tracking.
*/
package org.apache.jsp;
import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
public final class demo_jsp extends org.apache.jasper.runtime.HttpJspBase
implements org.apache.jasper.runtime.JspSourceDependent,
org.apache.jasper.runtime.JspSourceImports {
private static final javax.servlet.jsp.JspFactory _jspxFactory =
javax.servlet.jsp.JspFactory.getDefaultFactory();
private static java.util.Map<java.lang.String,java.lang.Long> _jspx_dependants;
private static final java.util.Set<java.lang.String> _jspx_imports_packages;
private static final java.util.Set<java.lang.String> _jspx_imports_classes;
static {
_jspx_imports_packages = new java.util.HashSet<>();
_jspx_imports_packages.add("javax.servlet");
_jspx_imports_packages.add("javax.servlet.http");
_jspx_imports_packages.add