JavaWeb
基本概念
web开发:
- web ---- 网页
- 静态web
- html css 提供给所有人看的 数据始终不会发生变化
- 动态web
- 技术栈 servlet/jsp asp php
- java中动态web资源开发技术统称为javaWeb
服务器是一种被动的操作,用来处理用户的一些请求和给用户一些响应信息
web服务器:
IIS windows自带
tomcat
Tomcat
启动关闭 bin/startup.sh shutdown.sh
HTTP:
百度:
Request URL: https://www.baidu.com/
Request Method: GET
Status Code: 200 OK
Remote Address: 36.152.44.96:443
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8
Cache-Control: max-age=0
Connection: keep-alive
- 请求行
- 请求方式:GET POST HEAD DELETE
- get:请求能够携带的参数比较少,大小有限制,会在url地址栏显示数据内容,不安全但是高效
- post:请求能够携带的参数无限制,大小没有限制,不会在url地址显示数据内容,安全,但不高效
- 请求方式:GET POST HEAD DELETE
- 消息头
Accept: 告诉浏览器 支持的数据类型
Accept-Encoding: 支持哪种编码
Accept-Language: 语言环境
Cache-Control: 缓存控制
Connection: 告诉浏览器 请求完成是断开还是保持连接
HTTP响应
200 请求响应成功
3xx 请求重定向
4xx 找不到资源 404
5xx 服务器代码错误 500 502网关错误
常见面试题
当浏览器地址栏输入地址并回车的一瞬间到页面能够展示回来,经历了什么
Maven项目架构管理工具
阿里云镜像加速
setting.xml
pom.xml
jar:java应用
war:javaweb应用
properties 配置
build 项目构建用的东西
Servlet
什么是Servlet
- Servlet是开发动态web的一门技术
- Servlet就是一个接口,Servlet只需要编写一个类实现Servlet,把开发好的java类部署到web服务器中
helloServlet
Servelt接口有两个默认的实现类 HttpServlet
- 构建一个Maven项目,删掉里面的src目录,以后在这个项目里建立moudel,这个空的工程就是maven主工程
- 关于Maven父子工程的理解:
父项目中会有<modules> <module>servlet-01</module> </modules>
父项目中的java子项目可以直接使用
- Maven环境优化
- 修改web.xml为最新的
- 将maven结构搭建完整
- 编写servlet ,实现Servlet,或者继承HttpServlet
public class HelloServlet extends HttpServlet {
//由于get或者post只是请求实现的不同的方式 可以相互调用 业务逻辑都一样
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
PrintWriter writer = resp.getWriter();
writer.print("Hello,Servlet");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 编写Servlet的映射
为什么需要映射:我们写的是Java程序,但是需要通过浏览器访问,而浏览器需要连接web服务器,所以我们需要在web服务中注册我们写的Servlet,还需要给一个浏览器能访问的路径
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.wang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
</web-app>
- 配置Tomcat
注意:配置项目发布的路径就可以了 - 启动测试
Servlet原理
Servlet是由Web服务器调用,web服务在收到浏览器请求之后会:
Mapping问题
- 一个Servlet可以指定一个映射路径
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定多个映射路径
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet1</url-pattern>
</servlet-mapping>
- 一个Servlet可以指定通用映射路径
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet/*</url-pattern>
</servlet-mapping>
- 默认请求路径
可以替换掉默认首页
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
- 指定一些后缀或者前缀等等
可以自定义后缀实现请求映射
注意:*前面不能加项目映射的路径
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
- 优先级问题
指定了固有的映射优先级最高,找不到就会找默认请求路径
默认请求路径是ErrorServlet,当访问/helloServlet的时候,页面跳转HelloServlet,但是其它时候就跳转ErrorServlet
<servlet>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>com.wang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/helloServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ErrorServlet</servlet-name>
<servlet-class>com.wang.servlet.ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ErrorServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
ServletContext
web容器在启动的时候,他会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用
- 共享数据
- 在这个Servlet中保存的数据可以在其它Servlet中使用
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("Hello");
// this.getInitParameter(); 初始化参数
// this.getServletConfig(); Servlet配置
// this.getServletContext(); Servlet上下文
ServletContext context = this.getServletContext();
String username = "username";
context.setAttribute("username", username); //将一个数据保存在ServletCOntext中 kv对
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
// HelloServlet中的username可以在GetServelt中获取到(需要先加载HelloServlet)
String username = (String) context.getAttribute("username");
System.out.println(this.getClass().getName() + ":" + username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<servlet>
<servlet-name>Hello</servlet-name>
<servlet-class>com.wang.servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Hello</servlet-name>
<url-pattern>/hello</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>GetContext</servlet-name>
<servlet-class>com.wang.servlet.GetServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>GetContext</servlet-name>
<url-pattern>/getContext</url-pattern>
</servlet-mapping>
获取初始化参数
<!-- 配置一些web应用初始化参数-->
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://aliyun:3306/mybatis</param-value>
</context-param>
<servlet>
<servlet-name>ServletDemo03</servlet-name>
<servlet-class>com.wang.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo03</servlet-name>
<url-pattern>/servletDemo03</url-pattern>
</servlet-mapping>
public class ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
System.out.println(url); //jdbc:mysql://aliyun:3306/mybatis
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
请求转发(请求转发的时候不跳转url 只是页面跳转)
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
RequestDispatcher requestDispatcher = context.getRequestDispatcher("/servletDemo03"); //转发的请求路径
requestDispatcher.forward(req, resp); //会进入servletDemo03界面 但是url还是在servletDemo04
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
读取资源文件
Properties
- 在java目录下新建properties
- 在resources目录下新建properties
发现:都被打包到了同一路径下,classes,我们俗称为这个路径为classPath
如果将properties放在java目录下,资源可能会导出失败,在pom.xml中配置
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
默认不需要配置resources目录
思路:需要一个文件流
public class ServletDemo05 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
InputStream is = context.getResourceAsStream("/WEB-INF/classes/db.properties");
Properties properties = new Properties();
properties.load(is);
String user = (String) properties.get("user");
System.out.println(user);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
HttpServletRequest
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有细信息会被封装到HttpServletRequest,通过这个HttpServletRequest的方法,获得客户端的所有信息
- 获取前端传递的参数
- 请求转发
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
// 获取参数
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbies = req.getParameterValues("hobby");
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbies));
// 请求转发
req.getRequestDispatcher("/success.jsp").forward(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
HttpServletResponse
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的HttpServletRequest对象,代表响应的一个HttpServletResponse;
- 如果想要获取客户端请求过来的参数:找HttpServletRequest
- 如果想要给客户端响应一些信息,找HttpServletResponse
- 简单分类
负责向浏览器发送数据的方法:
ServletOutputStream getOutputStream() throws IOException;
PrintWriter getWriter() throws IOException;
向浏览器发送响应头的方法
void setCharacterEncoding(String var1);
void setContentLength(int var1);
void setContentLengthLong(long var1);
void setContentType(String var1);
void setDateHeader(String var1, long var2);
void addDateHeader(String var1, long var2);
void setHeader(String var1, String var2);
void addHeader(String var1, String var2);
void setIntHeader(String var1, int var2);
void addIntHeader(String var1, int var2);
常见应用:
- 向浏览器输出信息
- 下载文件
- 获取下载文件的路径
- 下载的文件名
- 设置想办法让浏览器支持下载我们需要的东西
- 获取下载文件的输入流
- 创建缓冲区
- 获取OutputStream对象
- 将FileInputStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端
- 关闭资源
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取下载文件的路径
String realPath = this.getServletContext().getRealPath("/1.jpg");
System.out.println("文件路径:" + realPath);
// 2. 下载的文件名
String fileName = realPath.substring(realPath.lastIndexOf("//") + 1);
// 3. 设置想办法让浏览器支持下载我们需要的东西
resp.setHeader("Content-disposition", "attachment;filename" + fileName);
// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len = 0;
byte[] buffer = new byte[1024];
// 6. 获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileInPutStream流写入到buffer缓冲区 使用OutputStream将缓冲区中的数据输出到客户端
while ((len = in.read(buffer)) > 0) {
out.write(buffer, 0, len);
}
// 8. 关闭资源
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 验证码
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 如何让浏览器五秒自动刷新一次
resp.setHeader("refresh", "5");
//在内存中创建一个图片
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
Graphics2D graphics = (Graphics2D) image.getGraphics(); //笔
// 设置背景颜色
graphics.setColor(Color.WHITE);
graphics.fillRect(0, 0, 80, 20);
//给图片写数据
graphics.setColor(Color.BLUE);
graphics.setFont(new Font(null, Font.BOLD, 20));
graphics.drawString(makeNum(), 0, 20);
//告诉浏览器这个请求用图片的方式打开
resp.setContentType("image/jpeg");
//网站存在缓存 不让浏览器缓存
resp.setDateHeader("expires", -1);
resp.setHeader("Cache-Control", "no-cache");
resp.setHeader("Pragma", "no-cache");
//把图片写给浏览器
ImageIO.write(image, "jpg", resp.getOutputStream());
}
//生成随机数
private String makeNum() {
Random random = new Random();
String num = String.valueOf(random.nextInt(9999999));
StringBuffer sb = new StringBuffer();
for (int i = 0; i < 7 - num.length(); i++) {
sb.append("0");
}
num = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 实现重定向
一个web资源收到客户端请求后,会通知客户端去访问另外一个web资源,这个过程叫重定向
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
重定向等价于这两步
resp.setHeader("Location", "/image");
resp.setStatus(HttpServletResponse.SC_FOUND);
*/
resp.sendRedirect("/image"); //重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
重定向和转发的区别
- 相同点:页面跳转
- 不同点:
- 转发 url不变 307
- 重定向 url跳转 302
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入请求");
//处理请求
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<html>
<body>
<h2>Hello World!</h2>
<%-- 这里提交的路径需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath} 当前项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
用户名: <input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
<input type="submit">
</form>
</body>
</html>
<servlet>
<servlet-name>request</servlet-name>
<servlet-class>com.wang.servlet.RequestTest</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>request</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
Cookie Session
cookie
- 客户端技术(响应请求)
session - 服务器技术,利用这个技术可以保存用户的会话信息,我们可以把信息或者数据放在session中
常见场景:网站登录之后下次不用登录,第二次访问自动登录
Cookie
- 从请求中拿到cookie信息
- 服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); //获得Cookie
cookie.getName(); //获得Cookie的key
cookie.getValue(); //获得Cookie的value
Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis())); //新建一个cookie
cookie.setMaxAge(24 * 60 * 60); //设置cookie有效期
resp.addCookie(cookie);
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
PrintWriter out = resp.getWriter();
// cookie 服务端从客户端获取
Cookie[] cookies = req.getCookies();
if (cookies != null) {
out.write("上次访问的时间是");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
//获取cookie的名字
if (cookie.getName().equals("lastLoginTime")) {
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
} else {
out.write("这是你第一次访问本站");
}
//服务器给客户端响应一个cookie
Cookie cookie = new Cookie("lastLoginTime", String.valueOf(System.currentTimeMillis()));
cookie.setMaxAge(24 * 60 * 60);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
- 一个Cookie只能保存一个信息 key-value
- 一个web站点可以给浏览器发送多个cookie,300个cookie大概是浏览器上限,每个站点最多存放20个
- cookie大小有限制,4Kb
删除Cookie:
- 不设置有效期,关闭浏览器自动失效
- 设置有效期时间为0
// 网络编程解决乱码
String encode = URLEncoder.encode("我是中文", "utf-8");
String decode = URLDecoder.decode(encode, "utf-8");
Session
什么是session
- 服务器会给每一个用户(浏览器)创建一个Session对象
- 一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
- 用户登录之后,整个网站都可以访问
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决乱码问题
req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//得到session
HttpSession session = req.getSession();
// 给session存东西
session.setAttribute("name", "nameTest");
session.getAttribute("name");
// 手动注销
session.removeAttribute("name");
//获得session的id
String id = session.getId();
//判断session是不是新的
if (session.isNew()) {
resp.getWriter().write("session创建成功,id" + id);
} else {
resp.getWriter().write("session已经在服务器中存在,id" + id);
}
//session在创建的时候做了什么
// Cookie cookie = new Cookie("JSESSIONID", id);
// resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
<!-- 设置session默认的失效时间 15分钟-->
<session-config>
<session-timeout>15</session-timeout>
</session-config>
使用场景:
- 保存一个登录用户的信息
- 购物车信息
- 在整个网站中经常会使用的数据,保存在session中
Session和Cookie的区别:
- Cookie是把用户的数据写给用户的浏览器,浏览器保存
- Session是把用户的数据写到用户独占的Session中,服务器端保存(保存重要的信息,减少服务器资源浪费)
- Session对象由服务器创建
JSP
什么是JSP
Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态web技术
最大的特点:
- 写JSP就像在写HTML
- 区别:
- HTML给用户提供静态的数据
- JSP页面可以嵌入JAVA代码,提供动态数据
JSP原理
思路:JSP是怎么执行的
- 服务器内部:
tomcat中有一个work目录
IDEA中使用Tomcat的会在IDEA中生成一个work目录(工作空间 仍然依托于自己的tomcat)
/Users/wangyinghao/Library/Caches/JetBrains/IntelliJIdea2020.1/tomcat/Unnamed_kuangshen-javaweb/work/Catalina/localhost/ROOT/org/apache/jsp
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet
JSP最终也会被转换成一个Java类
JSP本质就是一个Servlet
/*
* Generated by the Jasper component of Apache Tomcat
* Version: Apache Tomcat/9.0.22
* Generated at: 2020-05-31 03:39:28 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 index_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("javax.servlet.jsp");
_jspx_imports_classes = null;
}
private volatile javax.el.ExpressionFactory _el_expressionfactory;
private volatile org.apache.tomcat.InstanceManager _jsp_instancemanager;
public java.util.Map<java.lang.String,java.lang.Long> getDependants() {
return _jspx_dependants;
}
public java.util.Set<java.lang.String> getPackageImports() {
return _jspx_imports_packages;
}
public java.util.Set<java.lang.String> getClassImports() {
return _jspx_imports_classes;
}
public javax.el.ExpressionFactory _jsp_getExpressionFactory() {
if (_el_expressionfactory == null) {
synchronized (this) {
if (_el_expressionfactory == null) {
_el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
}
}
}
return _el_expressionfactory;
}
public org.apache.tomcat.InstanceManager _jsp_getInstanceManager() {
if (_jsp_instancemanager == null) {
synchronized (this) {
if (_jsp_instancemanager == null) {
_jsp_instancemanager = org.apache.jasper.runtime.InstanceManagerFactory.getInstanceManager(getServletConfig());
}
}
}
return _jsp_instancemanager;
}
//初始化
public void _jspInit() {
}
//销毁
public void _jspDestroy() {
}
//JspService
public void _jspService(final javax.servlet.http.HttpServletRequest request, final javax.servlet.http.HttpServletResponse response)
throws java.io.IOException, javax.servlet.ServletException {
//request 请求 response 响应
if (!javax.servlet.DispatcherType.ERROR.equals(request.getDispatcherType())) {
final java.lang.String _jspx_method = request.getMethod();
if ("OPTIONS".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
return;
}
if (!"GET".equals(_jspx_method) && !"POST".equals(_jspx_method) && !"HEAD".equals(_jspx_method)) {
response.setHeader("Allow","GET, HEAD, POST, OPTIONS");
response.sendError(HttpServletResponse.SC_METHOD_NOT_ALLOWED, "JSP 只允许 GET、POST 或 HEAD。Jasper 还允许 OPTIONS");
return;
}
}
// 内置对象
final javax.servlet.jsp.PageContext pageContext; //页面上下文
javax.servlet.http.HttpSession session = null; //session
final javax.servlet.ServletContext application; //applicationContext
final javax.servlet.ServletConfig config; //config
javax.servlet.jsp.JspWriter out = null; //out
final java.lang.Object page = this; //page
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
try {
// 输出页面前增加的代码
response.setContentType("text/html"); //设置响应的页面类型 html
pageContext = _jspxFactory.getPageContext(this, request, response,
null, true, 8192, true);
_jspx_page_context = pageContext;
application = pageContext.getServletContext();
config = pageContext.getServletConfig();
session = pageContext.getSession();
out = pageContext.getOut();
_jspx_out = out;
// 以上的这些对象可以在JSP页面中直接使用
// ${pageContext}
out.write("<html>\n");
out.write("<body>\n");
out.write("<h2>Hello World!</h2>\n");
out.write("</body>\n");
out.write("</html>\n");
} catch (java.lang.Throwable t) {
if (!(t instanceof javax.servlet.jsp.SkipPageException)){
out = _jspx_out;
if (out != null && out.getBufferSize() != 0)
try {
if (response.isCommitted()) {
out.flush();
} else {
out.clearBuffer();
}
} catch (java.io.IOException e) {}
if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
else throw new ServletException(t);
}
} finally {
_jspxFactory.releasePageContext(_jspx_page_context);
}
}
}
在JSP页面中,只要是JAVA代码就会被原封不动的输出;如果是HTML代码,就会被转换成
out.write("<html>\r\n");
JSP基础语法
<html>
<body>
<h2>Hello World!</h2>
<%--JSP表达式--%>
<%--作用 将程序的输出输出到客户端--%>
<%=new java.util.Date()%>
<hr/>
<%--脚本片段--%>
<%
int sum = 0;
for (int i = 0; i < 100; i++) {
sum += i;
}
out.println("<h1> Sum=" + sum + "</h1>");
%>
<%--代码中嵌入html--%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>Hello,world <%=i%></h1>
<%
}
%>
<%--EL表达式 ${i}--%>
<%--JSP声明--%>
<%--会被编译到JSP生成Java类的类中 而不是_jspService中--%>
<%!
static {
System.out.println("Loading servlet");
}
private int globalVar = 0;
public void test(){
System.out.println("test");
}
%>
</body>
</html>
9大内置对象
- PageContext 存东西
- Request 存东西
- Response
- Session 存东西
- Application ServletContext 存东西
- config ServletConfig
- out
- page
- exception
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
pageContext.setAttribute("name1", "name1"); //保存的数据只在一个页面有效
request.setAttribute("name2", "name2"); //保存的数据只在一次请求中有效 请求转发会携带这个数据
session.setAttribute("name3", "name3"); // 保存的数据只在一次会话中有效 从打开浏览器到关闭浏览器
application.setAttribute("name4", "name4"); //保存的数据在服务器中有效 从打开服务器到关闭服务器
%>
<%
// 通过pageContext取,我们通过寻找的方式
String name1 = (String) pageContext.findAttribute("name1");
String name2 = (String) pageContext.findAttribute("name2");
String name3 = (String) pageContext.findAttribute("name3");
String name4 = (String) pageContext.findAttribute("name4");
// pageContext有个类似JVM的双亲委派机制的特性 从底层到高层(作用域) page-->request-->session-->application
// pageContext.setAttribute() scope为作用域 也可以提升pageContext的作用域
public void setAttribute(String name, Object attribute, int scope) {
switch(scope) {
case 1:
this.mPage.put(name, attribute);
break;
case 2:
this.mRequest.put(name, attribute);
break;
case 3:
this.mSession.put(name, attribute);
break;
case 4:
this.mApp.put(name, attribute);
break;
default:
throw new IllegalArgumentException("Bad scope " + scope);
}
%>
<%--通过el表达式输出--%>
<h1>取出的值为:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
</body>
</html>
request:客户端向服务器发送请求,产生的数据,用户看完就没用的,比如:用户看新闻
session:客户端向服务器发送请求,产生的数据用户用完一会还会用,比如:购物车
application:客户端向服务器发送请求,产生的数据,一个用户用完其他用户还可能使用,比如:聊天数据
JSP标签 JSTL标签 EL表达式
EL表达式: ${}
- 获取数据
- 执行运算
- 获取web开发的常用对象
JSP标签
<jsp:forward page="jsptag2.jsp">
<jsp:param name="name" value="nameTest"/>
<jsp:param name="age" value="ageTest"/>
</jsp:forward>
<%--取出参数--%>
<%=request.getParameter("name")%>
<%=request.getParameter("age")%>
JSTL标签
JSTL标签库的使用就是为了弥补HTML标签的不足:自定义了许多标签,功能和java一样
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--导入JSTL核心库--%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<hr/>
<form action="coreif.jsp" method="get">
<%-- EL表达式获取表单中的数据--%>
<input type="text" name="username" value="${param.username}">
<input type="submit" value="登录">
</form>
<%--判断如果提交的用户名是管理员 则登录成功--%>
<c:if test="${param.username == 'admin'}" var="isAdmin">
<c:out value="管理员欢迎您"></c:out>
</c:if>
<c:out value="${isAdmin}"></c:out>
<%
ArrayList<String> people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"李四");
request.setAttribute("list",people);
%>
<c:forEach var="people" items="${list}">
<c:out value="${people}"></c:out><br>
</c:forEach>
</body>
</html>
JavaBean
实例类
JavaBean有特定的写法:
- 必须要有一个无参构造
- 属性必须私有化
- 必须有对应的get/set方法
一般用来和数据库的字段做映射
ORM:对象关系映射 - 表–>类
- 字段–>属性
- 行记录–>对象
<%@ page import="com.wang.pojo.People" %><%--
Created by IntelliJ IDEA.
User: wangyinghao
Date: 2020/5/31
Time: 5:13 下午
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>
<%
// People people = new People();
// people.setId(1);
// people.setAddress("上海");
// people.setAge(10);
// people.setName("wyh");
%>
<jsp:useBean id="people" class="com.wang.pojo.People" scope="page"/>
<jsp:setProperty name="people" property="address" value="上海"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="age" value="10"/>
<jsp:setProperty name="people" property="name" value="wyh"/>
姓名:<jsp:getProperty name="people" property="name"/>
</body>
</html>
MVC三层架构
Model:
- 业务处理:业务逻辑 Service
- 数据持久层:CRUD Dao
View - 展示数据
- 提供链接发起Servlet请求
Controller - 接收用户的请求:req请求 session信息…
- 交给业务层处理对应的代码
- 控制视图的跳转
登录-->接收用户的登录请求-->处理用户的请求(获取用户登录的参数,username pwd)-->交给业务层处理登录业务(判断用户名密码是否正确:事务)-->Dao层查询用户名和密码是否正确-->数据库
Filter
过滤器,用来处理网站的数据
public class CharacterEncodingFilter implements Filter {
//服务器启动的时候 init就已经初始化 随时等待监听
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init");
}
//Chain 链
// 过滤所有的代码 在过滤特定请求的时候都会执行 web.xml配置
// 必须要让过滤器继续执行 filterChain.doFilter(servletRequest, servletResponse);
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
servletResponse.setContentType("text/html;charset=UTF-8");
System.out.println("doFilter执行前");
filterChain.doFilter(servletRequest, servletResponse); //让我们的请求继续走 如果不写程序就到这里被拦截停止
System.out.println("doFilter执行后");
}
//web服务器关闭的时候销毁
public void destroy() {
System.out.println("destroy");
}
}
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.wang.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 只要是/下的任何请求都会经过这个过滤器-->
<url-pattern>/*</url-pattern>
</filter-mapping>