import javax.servlet.RequestDispatcher;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class ServletDemo04 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream is = this.getServletContext().getResourceAsStream(“/WEB-INF/classes/com/zhang/servlet/aa.properties”);
Properties properties = new Properties();
properties.load(is);
String user = properties.getProperty(“username”);
String pwd = properties.getProperty(“password”);
resp.getWriter().print(user + “:” + pwd);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
web服务器接收到客户端的http请求,针对这个请求,分别创建一个代表请求的 HttpServletRequest对象,代表响应的 HttpServletResponse;
-
如果要获取客户端请求过来的参数:找 HttpServletRequest
-
如果要给客户端响应一些信息:找 HttpServletResponse
1、简单分类:
负责向浏览器发送数据的方法:
public ServletOutputStream getOutputStream() throws IOException;
public PrintWriter getWriter() throws IOException;
负责向浏览器发送响应头的方法:
public void setCharacterEncoding(String charset);
public void setContentLength(int len);
public void setContentLengthLong(long len);
public void setContentType(String type);
public void setDateHeader(String name, long date);
public void addDateHeader(String name, long date);
public void setHeader(String name, String value);
public void addHeader(String name, String value);
public void setIntHeader(String name, int value);
public void addIntHeader(String name, int value);
响应的状态码:
public static final int SC_CONTINUE = 100;
public static final int SC_SWITCHING_PROTOCOLS = 101;
public static final int SC_OK = 200;
public static final int SC_CREATED = 201;
public static final int SC_ACCEPTED = 202;
public static final int SC_NON_AUTHORITATIVE_INFORMATION = 203;
public static final int SC_NO_CONTENT = 204;
public static final int SC_RESET_CONTENT = 205;
public static final int SC_PARTIAL_CONTENT = 206;
public static final int SC_MULTIPLE_CHOICES = 300;
public static final int SC_MOVED_PERMANENTLY = 301;
public static final int SC_MOVED_TEMPORARILY = 302;
public static final int SC_FOUND = 302;
public static final int SC_SEE_OTHER = 303;
public static final int SC_NOT_MODIFIED = 304;
public static final int SC_USE_PROXY = 305;
public static final int SC_TEMPORARY_REDIRECT = 307;
public static final int SC_BAD_REQUEST = 400;
public static final int SC_UNAUTHORIZED = 401;
public static final int SC_PAYMENT_REQUIRED = 402;
public static final int SC_FORBIDDEN = 403;
public static final int SC_NOT_FOUND = 404;
public static final int SC_METHOD_NOT_ALLOWED = 405;
public static final int SC_NOT_ACCEPTABLE = 406;
public static final int SC_PROXY_AUTHENTICATION_REQUIRED = 407;
public static final int SC_REQUEST_TIMEOUT = 408;
public static final int SC_CONFLICT = 409;
public static final int SC_GONE = 410;
public static final int SC_LENGTH_REQUIRED = 411;
public static final int SC_PRECONDITION_FAILED = 412;
public static final int SC_REQUEST_ENTITY_TOO_LARGE = 413;
public static final int SC_REQUEST_URI_TOO_LONG = 414;
public static final int SC_UNSUPPORTED_MEDIA_TYPE = 415;
public static final int SC_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
public static final int SC_EXPECTATION_FAILED = 417;
public static final int SC_INTERNAL_SERVER_ERROR = 500;
public static final int SC_NOT_IMPLEMENTED = 501;
public static final int SC_BAD_GATEWAY = 502;
public static final int SC_SERVICE_UNAVAILABLE = 503;
public static final int SC_GATEWAY_TIMEOUT = 504;
public static final int SC_HTTP_VERSION_NOT_SUPPORTED = 505;
2、常见应用:
-
向浏览器输出消息
-
下载文件
-
要获取下载文件的路径
-
下载的文件名是啥?
-
设置想办法让浏览器能够支持下载我们需要的东西
-
获取下载文件的输入流
-
创建缓冲流
-
获取 OutputStream对象
-
将 FileOutputStream流写入到 buffer缓冲区
-
使用 OutputStream将缓冲区中的数据输出到客户端
package com.zhang.servlet;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.FileInputStream;
import java.io.IOException;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println(“1111”);
// // 1、获取下载文件的路径
// String realPath = this.getServletContext().getRealPath(“/jt.png”);
String realPath = “E:\idea project\com.zya\response1\src\main\resources\jt.png”;
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[] bytes = new byte[1024];
// 6、获取OutputStream对象
ServletOutputStream out = resp.getOutputStream();
// 7、将FileOutputStream流写入到buffer缓冲区,使用OuputStream将缓冲区中的数据输出到客户端
while ((len = in.read(bytes))!=-1){
out.write(bytes, 0, len);
}
// 8、关闭数据流
out.close();
in.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
前端实现:用JavaScript
后端实现:可以用到 Java 的图片类,生成一个图片
package com.zhang.servlet;
import javax.imageio.ImageIO;
import javax.servlet.ServletException;
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;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 如何让浏览器3秒自动刷新一次
resp.setHeader(“refresh”, “3”);
// 在内存中创建一个图片
BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
// 得到图片
Graphics2D g = (Graphics2D) bufferedImage.getGraphics(); //笔
// 设置图片的背景颜色
g.setColor(Color.WHITE);
g.fillRect(0,0,80,20);
// 给图片写数据
g.setColor(Color.BLUE);
g.setFont(new Font(null, Font.BOLD,20));
g.drawString(makeNum(), 0 ,20);
// 告诉浏览器,这个请求用图片的方式打开
resp.setContentType(“image/png”);
// 网站存在缓存,不让浏览器缓存
resp.setDateHeader(“expires”,-1);
resp.setHeader(“Cache-Control”, “no-cache”);
resp.setHeader(“Pragma”, “no-cache”);
// 把图片写给浏览器
boolean write = ImageIO.write(bufferedImage, “png”,resp.getOutputStream());
}
// 生成随机数
public String makeNum(){
Random random = new Random();
String num = random.nextInt(9999) + “”;
StringBuffer sb = new StringBuffer();
for (int i = 0;i < 4 - num.length();i++){
sb.append(“0”);
}
String s = sb.toString() + num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
B 一个 web资源收到客户端A请求后,B 他会通过 A 客户端去访问另一个web资源C,这个过程叫重定向
常用场景:
void sendRedirect(String var1) throws IOException;
package com.zhang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
/*
原理:
resp.setHeader(“Location”, “/img”);
resp.setStatus(302);
*/
resp.sendRedirect(“/ImageServlet”); // 重定向
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
面试题:请你聊聊重定向和转发的区别?
相同点:
- 页面都会实现跳转
不同点:
-
请求转发的时候,url不会发生变化<---- 307
-
重定向时候,url地址栏会发生变化 <---- 302
如果出现中文乱码,就加上这句编码转换:
<%@ page contentType=“text/html; charset=UTF-8” %>
Hello World!
<%–这里提交的路径,需要寻找项目的路径–%>
<%–${pageContext.request.contextPath}代表当前的项目–%>
<%@ page contentType=“text/html; charset=UTF-8” %>
用户名:
密码:
package com.zhang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class RequestTest extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 处理请求
String username = req.getParameter(“username”);
String password = req.getParameter(“password”);
System.out.println(username + “:” + password);
// 重定向时候一定要注意路径问题,否则404
resp.sendRedirect(“/success.jsp”);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
HttpServletRequest代表客户端的请求,用户通过Http协议访问服务器,HTTP请求中的所有信息会被封装到 HttpServletRequest,通过这个 HttpServletRequest的方法,获得客户端的所有信息
1、获取前端传递的参数,请求转发:
-
req.getParameter(String s)
-
req.getParameterMap()
-
req.getParameterNames()
-
req.getParameterValues(String s)
@Override
protected void doPost(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[] hobbys = req.getParameterValues(“hobbys”);
System.out.println(“=============================”);
System.out.println(username);
System.out.println(password);
System.out.println(Arrays.toString(hobbys));
System.out.println(“=============================”);
System.out.println(req.getContextPath());
// 通过请求转发
// 这里的 / 代表当前的web应用
req.getRequestDispatcher(“/success.jsp”).forward(req,resp);
}
会话:用户打开一个浏览器,点击了很多超链接,访问多个web资源,关闭浏览器,这个过程可以称之为会话。
有状态会话:一个同学来过教室,下次再来教室,我们会知道这个同学,曾经来过,称之为有状态会话;
你能怎么征明你是学校的学生(Java中的万物皆对象:你和学校)
-
发票 ----- 学校给你发票
-
学校登记 ----- 学校标记你来过了
一个网站,怎么征明你来过?
-
客户端 <-----> 服务端
-
服务端给客户端一个信件,客户端下次访问服务端带上信件就可以了; cookie
-
服务器登记你来过了,下次你来的时候我来匹配你;session
cookie
- 客户端技术(响应,请求)
session
- 服务器技术,利用这个技术,可以保存用户的会话信息,我们可以把信息或者数据放在session中
1、从请求中拿到cookie信息
2、服务器响应给客户端cookie
Cookie[] cookies = req.getCookies(); // 获得Cookie
cookie.getName(); // 获得cookie中的key
cookie.getValue(); // 获得cookie中的value
new Cookie(“lastLoginTime”, System.currentTimeMillis()+“”); // 新建一个cookie
cookie.setMaxAge(246060); // 设置cookie的有效期
resp.addCookie(cookie); // 响应给客户端一个cookie
package com.zhang.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
// 保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 服务器,告诉你,你来的时间,把这个时间封装成一个信件,你下带来,我就知道你来了
// 解决中文乱码
req.setCharacterEncoding(“utf-16”);
resp.setCharacterEncoding(“utf-16”);
PrintWriter out = resp.getWriter();
// Cookie,服务器端从客户端获取
Cookie[] cookies = req.getCookies(); // 这里返回数组,说明Cookie可能存在多个
// 判断Cookie是否存在
if (cookies!=null){
// 如果存在怎么办
out.write(“你上一次访问的时间是:”);
for (Cookie cookie:cookies) {
System.out.println(cookie);
}
for (int i = 0; i < cookies.length; i++) {
Cookie cookie = cookies[i];
// 获取cookie的名字
if (cookie.getName().equals(“lastLoginTime”)){
// 获取cookie中的值
long lastLoginTime = Long.parseLong(cookie.getValue());
Date date = new Date(lastLoginTime);
out.write(date.toLocaleString());
}
}
}else {
out.write(“这是你第一次访问本站”);
}
// 服务器给客户端响应一个Cookie
Cookie cookie = new Cookie(“lastLoginTime”, System.currentTimeMillis()+“”);
// cookie有效期为1天
cookie.setMaxAge(246060);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
cookie:一般会保存在本地的 用户目录下 AppData
一个网站cookie是否存在上限?
-
一个Cookie只能保存一个信息
-
一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
-
Cookie大小有限制 4KB
-
300个浏览器上限
删除Cookie
-
不设置有效期,关闭浏览器,自动失效
-
设置有效期时间为0
package com.zhang.servlet;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
// 保存用户上一次访问的时间
public class CookieDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 创建一个cookie,名字必须要和删除的名字一样
Cookie cookie = new Cookie(“lastLoginTime”, System.currentTimeMillis()+“”);
// 将cookie有效期设置为0,立马过期
cookie.setMaxAge(0);
resp.addCookie(cookie);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
什么是Session:
-
服务器会给每一个用户(浏览器)创建一个Session对象
-
一个Session独占一个浏览器,只要浏览器没有关闭,这个Session就存在
-
用户登录之后,整个网站它都可以访问(保存用户信息,保存购物车的信息…)
public interface HttpSession {
long getCreationTime();
String getId();
long getLastAccessedTime();
ServletContext getServletContext();
void setMaxInactiveInterval(int var1);
int getMaxInactiveInterval();
/** @deprecated */
@Deprecated
HttpSessionContext getSessionContext();
Object getAttribute(String var1);
/** @deprecated */
@Deprecated
Object getValue(String var1);
Enumeration getAttributeNames();
/** @deprecated */
@Deprecated
String[] getValueNames();
void setAttribute(String var1, Object var2);
/** @deprecated */
@Deprecated
void putValue(String var1, Object var2);
void removeAttribute(String var1);
/** @deprecated */
@Deprecated
void removeValue(String var1);
void invalidate();
boolean isNew();
}
Session和Cookie的区别:
-
Cookie是把用户的数据写给用户的浏览器,浏览器保存(可以保存多个)
-
Session把用户的数据写到用户独占Session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
-
Session对象由服务器创建
使用场景:
-
保存一个登录用户的信息
-
购物车信息
-
在整个网站中,经常会使用的数据,我们将它保存在Session中
使用Session:
package com.blb.servlet.util;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;
@WebServlet(“/s1”)
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决乱码问题
req.setCharacterEncoding(“utf-16”);
resp.setCharacterEncoding(“utf-16”);
resp.setContentType(“text/html;charset=utf-8”);
// 得到Session
HttpSession session = req.getSession();
// 给Session中存东西
session.setAttribute(“name”,new Person(“张义昂”, 1));
// 获取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 {
super.doGet(req, resp);
}
}
package com.blb.servlet.util;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(“/s2”)
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 解决乱码问题
req.setCharacterEncoding(“utf-16”);
resp.setCharacterEncoding(“utf-16”);
resp.setContentType(“text/html;charset=utf-8”);
// 得到Session
HttpSession session = req.getSession();
Person name = (Person) session.getAttribute(“name”);
System.out.println(name.toString());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
手动注销Session
package com.blb.servlet.util;
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 javax.servlet.http.HttpSession;
import java.io.IOException;
@WebServlet(“/s3”)
public class SessionDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
HttpSession session = req.getSession();
session.removeAttribute(“name”);
// 手动注销session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
会话自动过期:web.xml配置
<?xml version="1.0" encoding="UTF-8"?><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_4_0.xsd”
version=“4.0”>
work01
15
Java Server Pages:Java服务器端页面,也和Servlet一样,用于动态Web技术
最大的特点:
-
写JSP就像在写HTML
-
区别:
-
HTML只给用户提供静态的数据
-
JSP页面中可以嵌入Java代码,为用户提供动态数据
思路:JSP怎么执行的?
-
代码层面没有任何问题
-
服务器内部工作
-
tomcat中有一个work目录
-
IDEA中使用Tomcat的会在IDEA的tomcat中生产一个work目录
-
浏览器向服务器发送请求,不管访问什么资源,其实都是在访问Servlet!
JSP最终也会被转化成为一个Java类!
JSP本质上Servlet
// 初始化
public void _jspInit() {
}
// 销毁
public void _jspDestroy() {
}
// JSP的Service
public void _jspService(.HttpServletRequest request, HttpServletResponse response) {
}
1、判断请求
2、内置对象
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 当前页
HttpServletRequest request // 请求
HttpServletResponse response // 响应
javax.servlet.jsp.JspWriter _jspx_out = null;
javax.servlet.jsp.PageContext _jspx_page_context = null;
3、输出页面前增加的代码
response.setContentType(“text/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;
4、以上的这些个对象我们可以在JSP页面中直接使用
在JSP页面中:
只要是Java代码就会原封不动的输出;
如果是HTML代码,就会转化为:
out.write(“\r\n”);
这样的格式,输出到前端!
任何语言都有自己的语法,Java中有,JSP作为Java技术的一种应用,它拥有一些自己扩充的语法(了解,知道即可!),Java所有语法都支持
JSP表达式
作用:用来将程序的输出,输出到客户端
<%= 变量或者表达式 %>
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%-- JSP表达式 --%>
<%= new java.util.Date() %>
JSP脚本片段
<%-- 分割线 --%>
<%-- JSP脚本片段 --%>
<%
int sum = 0;
for (int i = 0; i <= 100 ; i++) {
sum+=i;
}
out.println(“
”+sum+“
”);%>
脚本片段的再实现
<%-- JSP脚本片段 --%>
<%
int sum = 0;
for (int i = 0; i <= 100 ; i++) {
sum+=i;
}
out.println(“
”+sum+“
”);%>
<%
int x = 10;
out.println(x);
%>
这是一个JSP文档
<%
int y = 10;
out.println(y);
%>
<%-- 在代码中嵌入HTML元素 --%>
<%
for (int i = 0; i < 5; i++) {
%>
hello world <%= i%>
<%
}
%>
JSP声明:会被编译到JSP生成Java的类中,其他的就会被生成到 _jspService方法中
<%!
static {
System.out.println(“Loading Servlet!”);
}
private int globalVar = 0;
public void jspInit(){
System.out.println(“进入了方法!”);
}
%>
在JSP,嵌入Java代码即可
<%%>
<%=%>
<%!%>
<%–注释–%>
JSP的注释,不会在客户端显示,HTML就会!
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%–定制错误页面–%>
<%@ page errorPage=“error/500.jsp” %>
<%
int x = 1/0;
%>
<%@page args… %>
<%@include file=“” %>
<%–@include会将两个页面合二为一–%>
<%@include file=“common/header.jsp”%>
网页主体
<%@include file=“common/footer.jsp”%>
<%–jsp标签
jsp : include: 拼接页面,本质还是三个
–%>
<jsp:include page=“/common/header.jsp” />
网页主体
<jsp:include page=“/common/footer.jsp” />
-
pageContext – 存东西
-
Request – 存东西
-
Response
-
Session – 存东西
-
Application 【ServletContext】-- 存东西
-
Config 【ServletConfig】
-
Out
-
Page
-
Exception
pageContext.setAttribute(“name1”,“Java1”); // 保存的数据只在一个页面中有效
request.setAttribute(“name2”,“Java2”); // 保存在数据只在一次请求中有效,请求转发会携带这个数据
application.setAttribute(“name3”,“Java3”); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器
session.setAttribute(“name4”,“Java4”); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
public static final int PAGE_SCOPE = 1;
public static final int REQUEST_SCOPE = 2;
public static final int SESSION_SCOPE = 3;
public static final int APPLICATION = 4;
// scope : 作用域
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);
}
}
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%@ page isELIgnored=“false” %>
<%-- 内置对象 --%>
<%
// pageContext.include();
// pageContext.forward();
pageContext.setAttribute(“name1”,“Java1”); // 保存的数据只在一个页面中有效
request.setAttribute(“name2”,“Java2”); // 保存在数据只在一次请求中有效,请求转发会携带这个数据
application.setAttribute(“name3”,“Java3”); // 保存的数据只在服务器中有效,从打开服务器到关闭服务器
session.setAttribute(“name4”,“Java4”); // 保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
%>
<%–
脚本片段中的代码,会被原封不动生成到 JSP.java
要求:这里面的代码:必须保证Java语法的正确性
–%>
<%
// 通过pageContext取出我们保存的值
// 通过pageContext取出,我们通过寻找的方式来
// 从底层到高层(作用域) : page --> request --> session --> application
// JVM : 双亲委派机制 : 先找上级加载器,最上级没有才会从下级找
String name1 = (String) pageContext.findAttribute(“name1”);
String name2 = (String) pageContext.findAttribute(“name2”);
String name3 = (String) pageContext.findAttribute(“name3”);
String name4 = (String) pageContext.findAttribute(“name4”);
String name5 = (String) pageContext.findAttribute(“name5”);
%>
<%–使用EL表达式输出–%>
取出的值为:
${name1}
${name2}
${name3}
${name4}
<%–EL表达式会自动不在网页上显示null值–%>
${name5}
request:客户端向服务器发送请求,产生数据,用户看完就没用了;比如:新闻,用户看完没用的;
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;
application:客户端发服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;
EL表达式:${}
-
获取数据
-
执行运算
-
获取web开发的常用对象
JSP标签:
<%–jsp:include–%>
<%–
http://localhost:8080/jsptag.jsp?name=kuangshen&age=12
–%>
<jsp:forward page=“/jsptag2.jsp”>
<jsp:param name=“name” value=“kuangshen”/>
<jsp:param name=“age” value=“12”/>
</jsp:forward>
JSTL表达式:
JSTL标签库的使用就是为了弥补HTML标签的不足;它自定义许多标签,可以供我们使用,标签的功能和Java代码一样!
格式化标签
SQL标签
XML标签
核心标签(掌握部分)
JSTL标签使用步骤:
-
引入对应的taglib
-
使用其中的方法
-
在Tomecat也需要引入jstl的包,否则会报错;JSTL解析错误
if
<%@ page contentType=“text/html;charset=UTF-8” language=“java” %>
<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>
4
<%–
EL表达式获取表单中的数据
${param.参数名}
–%>
<%–如果提交的用户名是管理员,则登陆成功–%>
<%
if (request.getParameter(“username”).equals(“admin”)){
out.print(“登陆成功”);
}
%>
<c:if test=“${param.username == ‘admin’}” var=“isAdmin”>
<c:out value=“管理员欢迎您” />
</c:if>
<%–自闭和标签–%>
<c:out value=“${isAdmin}”></c:out>
switch
<%–定义一个变量score,值为85–%>
<c:set var=“score” value=“85”></c:set>
<c:choose>
<c:when test=“${score>=90}”>
你的成绩为优秀
</c:when>
<c:when test=“${score>=80}”>
你的成绩为一般
</c:when>
<c:when test=“${score>=70}”>
你的成绩为及格
</c:when>
<c:when test=“${score<=60}”>
你的成绩不及格
</c:when>
</c:choose>
for
<%
ArrayList people = new ArrayList<>();
people.add(0,“张三”);
people.add(1,“李四”);
people.add(2,“王五”);
people.add(3,“赵六”);
people.add(4,“田七”);
request.setAttribute(“list”,people);
%>
<%–
var : 每一次遍历出来的变量
items : 要遍历的对象
begin : 从哪开始
end : 到哪结束
step : 步长
–%>
<c:forEach items=“${list}” var=“people”>
<c:out value=“${people}” />
</c:forEach>
<c:forEach var=“people” items=“${list}” begin=“1” end=“3” step=“2”>
<c:out value=“${people}” />
</c:forEach>
实体类
JavaBean有特定的写法:
-
必须要有一个无参构造
-
属性必须私有化
-
必须有对应的get/set方法
一般用来和数据库的字段做映射
ORM(对象关系映射)
-
表 -->类
-
字段 --> 属性行
-
行记录 --> 对象
people表
| id | name | age | address |
| — | — | — | — |
| 1 | 1号 | 3 | 中国 |
| 2 | 2号 | 3 | 中国 |
| 3 | 3号 | 3 | 中国 |
| 4 | 4号 | 3 | 中国 |
class People {
private int id;
private String name;
private int age;
private String address;
}
class A {
new People(1, “1号”, 3, “中国”);
new People(2, “2号”, 3, “中国”);
new People(3, “3号”, 3, “中国”);
new People(4, “4号”, 3, “中国”);
}
MVC:
-
Model:模型
-
View:视图
-
Controller:控制器
用户层直接访问控制层,控制层就可以直接操作数据库
servlet – CRUD --> 数据库
弊端:程序十分臃肿,不利于维护
servlet的代码中:处理请求、响应、试图跳转、处理业务代码、处理逻辑代码
架构:没什么是加一层解决不了的!!!
Model:
-
业务处理:业务逻辑(Service)
-
数据持久化:CRUD(Dao)
View:
-
展示数据
-
提供链接发起Servlet请求(a、form、img…)
Controller:
-
接收用户的请求:(req:请求参数、Session信息)
-
交给业务层处理对应的代码
-
控制视图的跳转
Filter:过滤器,用来过滤网站的数据;
-
处理中文乱码
-
登录验证…
过滤器代码:
package com.blb.filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
// 初始化: web服务器启动,就已经初始化,随时等待过滤对象出现!
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println(“CharacterEncodingFilter已经初始化”);
}
// filterChain : 链
/*
1、过滤器的所有代码,在过滤特定请求的时候都会执行
2、必须要让过滤器继续同行
filterChain.doFilter(servletRequest, servletResponse);
*/
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
servletRequest.setCharacterEncoding(“utf-16”);
servletResponse.setCharacterEncoding(“utf-16”);
servletResponse.setContentType(“text/html;charset=UTF-8”);
System.out.println(“CharacterEncodingFilter执行前…”);
filterChain.doFilter(servletRequest, servletResponse);//让我们的请求继续走,如果不写,程序到这里就被拦截了
System.out.println(“CharacterEncodingFilter执行后…”);
}
// 销毁
public void destroy() {
System.getenv();
System.out.println(“CharacterEncodingFilter已经销毁”);
}
}
配置路径的时候,一定要把过滤器的路径包括项目路径
ShowServlet
com.blb.filter.servlet.ShowServlet
ShowServlet
/servlet/show
ShowServlet
/show
CharacterEncodingFilter
com.blb.filter.CharacterEncodingFilter
CharacterEncodingFilter
/servlet/*
实现一个监听器的接口(有N种)
1、编写一个监听器:实现监听器的接口
// 统计网站在线人数: 统计session
public class onlineCountListener implements HttpSessionListener {
// 创建session监听: 看你的一举一动
// 一旦创建Session就会触发一次这个事件!
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
System.out.println(httpSessionEvent.getSession().getId());
Integer onlineCount = (Integer) servletContext.getAttribute(“onlineCount”);
if (onlineCount == null) {
// 装箱
onlineCount = new Integer(1);
}else {
// 开箱
int count = onlineCount.intValue();
onlineCount = new Integer(count+1);
}
servletContext.setAttribute(“onlineCount”, onlineCount);
}
// 销毁session监听
// 一旦销毁Session就会触发一次这个事件!
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) servletContext.getAttribute(“onlineCount”);
if (onlineCount == null) {
// 装箱
onlineCount = new Integer(0);
}else {
// 开箱
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
servletContext.setAttribute(“onlineCount”, onlineCount);
}
/*
Sesssion销毁:
1、手动销毁 getSession().invalidate();
2、自动销毁 在web.xml配置销毁时间
*/
}
2、在web.xml中注册监听器
com.blb.filter.listener.onlineCountListener
3、看情况使用
public class TestPandel {
public static void main(String[] args) {
Frame frame = new Frame(“中秋节快乐”); // 新建一个窗体
Panel panel = new Panel(null); // 面板
frame.setLayout(null); // 设置窗体的布局
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(0,0,255)); // 设置背景颜色
panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0,255,0)); // 设置背景颜色
frame.add(panel);
frame.setVisible(true);
// 监听事件: 监听关闭事件
frame.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println(“打开”);
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println(“关闭ing”);
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println(“关闭ed”);
}
@Override
public void windowIconified(WindowEvent e) {
super.windowIconified(e);
}
@Override
public void windowDeiconified(WindowEvent e) {
super.windowDeiconified(e);
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println(“激活”);
}
@Override
public void windowDeactivated(WindowEvent e) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/3d8bcd91fef2d20c2eeb2894dc5e5447.jpeg)
笔者福利
以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。
有了这个,面试踩雷?不存在的!
回馈粉丝,诚意满满!!!
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!
servletContext.setAttribute(“onlineCount”, onlineCount);
}
// 销毁session监听
// 一旦销毁Session就会触发一次这个事件!
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
Integer onlineCount = (Integer) servletContext.getAttribute(“onlineCount”);
if (onlineCount == null) {
// 装箱
onlineCount = new Integer(0);
}else {
// 开箱
int count = onlineCount.intValue();
onlineCount = new Integer(count-1);
}
servletContext.setAttribute(“onlineCount”, onlineCount);
}
/*
Sesssion销毁:
1、手动销毁 getSession().invalidate();
2、自动销毁 在web.xml配置销毁时间
*/
}
2、在web.xml中注册监听器
com.blb.filter.listener.onlineCountListener
3、看情况使用
public class TestPandel {
public static void main(String[] args) {
Frame frame = new Frame(“中秋节快乐”); // 新建一个窗体
Panel panel = new Panel(null); // 面板
frame.setLayout(null); // 设置窗体的布局
frame.setBounds(300,300,500,500);
frame.setBackground(new Color(0,0,255)); // 设置背景颜色
panel.setBounds(50,50,300,300);
panel.setBackground(new Color(0,255,0)); // 设置背景颜色
frame.add(panel);
frame.setVisible(true);
// 监听事件: 监听关闭事件
frame.addWindowFocusListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent e) {
System.out.println(“打开”);
}
@Override
public void windowClosing(WindowEvent e) {
System.out.println(“关闭ing”);
System.exit(0);
}
@Override
public void windowClosed(WindowEvent e) {
System.out.println(“关闭ed”);
}
@Override
public void windowIconified(WindowEvent e) {
super.windowIconified(e);
}
@Override
public void windowDeiconified(WindowEvent e) {
super.windowDeiconified(e);
}
@Override
public void windowActivated(WindowEvent e) {
System.out.println(“激活”);
}
@Override
public void windowDeactivated(WindowEvent e) {
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-702dZUuT-1713474575236)]
[外链图片转存中…(img-q6HhFacS-1713474575236)]
[外链图片转存中…(img-aUQh0d3c-1713474575237)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/3d8bcd91fef2d20c2eeb2894dc5e5447.jpeg)
笔者福利
以下是小编自己针对马上即将到来的金九银十准备的一套“面试宝典”,不管是技术还是HR的问题都有针对性的回答。
有了这个,面试踩雷?不存在的!
回馈粉丝,诚意满满!!!
[外链图片转存中…(img-RKUiJVt4-1713474575237)]
[外链图片转存中…(img-VMISsc5p-1713474575237)]
[外链图片转存中…(img-5pAsVm79-1713474575237)]
[外链图片转存中…(img-RKNdtspB-1713474575238)]
《互联网大厂面试真题解析、进阶开发核心学习笔记、全套讲解视频、实战项目源码讲义》点击传送门即可获取!