利用ServletContext实现两个web网页之间消息的互通
发送端口:
package com.wang.servlet;
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 HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
//得到servletcontext对象
String username="小王";
// context.setRequestCharacterEncoding("utf-8");
context.setAttribute("username",username);
//把username这个对象放到context中
}
}
接收端口:
package com.wang.servlet;
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;
import java.io.InputStream;
import java.util.Properties;
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");
//把这个路径的文件转换成流
//这个路径要根据编译生成的target文件查看
Properties properties = new Properties();
//获取properties类
properties.load(is);
//通过properties类把is这个流下载
String user = properties.getProperty("user");
String password = properties.getProperty("password");
//下载后,通过properties类查看这个流中的文本信息
resp.getWriter().print(user+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
在web.xml中写入一些初始化信息后,可以通过方法Context的getInitParameter方法拿到这些信息
// 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_3_1.xsd"
version="3.1"
metadata-complete="true">
<context-param>
<param-name>url</param-name>
<param-value>jdbc:mysql://localhost:3306/mybatis</param-value>
</context-param>
// 通过context-param在web.xml中定义一些初始化信息
<servlet>
<servlet-name>gp</servlet-name>
<servlet-class>com.wang.servlet.ServletDemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>gp</servlet-name>
<url-pattern>/gp</url-pattern>
</servlet-mapping>
</web-app>
// 获取代码:
package com.wang.servlet;
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 ServletDemo03 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext context = this.getServletContext();
String url = context.getInitParameter("url");
resp.getWriter().print("url:"+url);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
转发,通过ServletContext中getRequestDispatcher方法实现转发,
A需要C中的信息,但是A只能连接到B,而B可以连接C,此时,用方法getRequestDispatcher可以通过A转发B中的内容,而B的内容从C中获取
package com.wang.servlet;
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 {
ServletContext context = this.getServletContext();
System.out.println("进入了ServletDemo04");
context.getRequestDispatcher("/gp").forward(req,resp);
// 转发的路径 传递的参数
//demo04转发demo03 ,demo03中的内容来自web.xml
//demo04不直接去web.xml中,通过找demo03实现找web.xml中的内容
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
获取resources中的资源文件中的内容
package com.wang.servlet;
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;
import java.io.InputStream;
import java.util.Properties;
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");
//把这个路径的文件转换成流
//这个路径要根据编译生成的target文件查看
Properties properties = new Properties();
//获取properties类
properties.load(is);
//通过properties类把is这个流下载
String user = properties.getProperty("user");
String password = properties.getProperty("password");
//下载后,通过properties类查看这个流中的文本信息
resp.getWriter().print(user+":"+password);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
下载文件
package com.wang.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;
import java.net.URLEncoder;
public class FileServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
// 1. 获取下载文件的路径
//F:\java源代码\Java\javaweb_02_servlet\response\src\main\resources\小王.png 绝对路径
String realPath = "F:\\java源代码\\Java\\javaweb_02_servlet\\response\\src\\main\\resources\\小王.png";
// 2. 下载的文件名是啥?
//substring截取字符串 lastIndex最后一个索引
//从最后一个\\的后面一个字符开始截取,为下载的文件的文件名字
//参考:https://blog.csdn.net/billxin0621/article/details/98485271?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522167504689016800188538520%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=167504689016800188538520&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduend~default-2-98485271-null-null.142^v71^one_line,201^v4^add_ask&utm_term=substring%E7%9A%84%E7%94%A8%E6%B3%95&spm=1018.2226.3001.4187
String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
// 3. 设置想办法让浏览器能都支持我们下载的东西 文件名是中文的时候,可以设置URLEncoder.encode(fileName, "UTF-8"),否则有可能乱码
resp.setHeader("Content-Disposition","attachment;filename="+ URLEncoder.encode(fileName,"UTF-8"));
//设置头文件,不懂
// 4. 获取下载文件的输入流
FileInputStream in = new FileInputStream(realPath);
// 5. 创建缓冲区
int len=0;
byte[] buffer = new byte[1024];
// 6. 获取OutputStrem对象
ServletOutputStream out = resp.getOutputStream();
// 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端
while ((len=in.read(buffer))>0){
out.write(buffer,0,len);
}
out.flush();
in.close();
out.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
重定向,重定向的路径需要加/*
package com.wang.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.sendRedirect("/r/img");
//拆分:
resp.setHeader("location","/r/img");
//重定向后的位置
resp.setStatus(302);
//状态码设置
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
package com.wang.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 {
System.out.println("进入了RequestTest请求");
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("/r/success.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
动态验证码
package com.wang.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 {
resp.setHeader("refresh","3");
//设置网页头,实现3秒刷新一次网页
BufferedImage img = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
//参考:https://blog.csdn.net/weixin_31659095/article/details/114512388?ops_request_misc=&request_id=&biz_id=102&utm_term=BufferedImage.TYPE_INT_RGB&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-1-114512388.nonecase&spm=1018.2226.3001.4187
//创建一张图片,长80宽20 BufferedImage.TYPE_INT_RGB RGB三原色
Graphics2D i = (Graphics2D) img.getGraphics();//得到一支笔
//设置笔的颜色
i.setColor(Color.white);
//设置 填充矩形 从00点到80,20
i.fillRect(0,0,80,20);
//给图片写入字符串数据
i.setColor(Color.BLACK);
i.setFont(new Font(null,Font.BOLD,20));
i.drawString(makeNum(),0,20);
//设置浏览器打开方式为图片
resp.setContentType("image/jpeg");
//设置为不缓存
resp.setDateHeader("Expires",0);
resp.addHeader("Cache-Control","no-cache");
resp.setHeader("Pragma","no-cache");
//写 写到哪 ,名字 写什么
ImageIO.write(img,"jpg", resp.getOutputStream());
}
//生成一个随机数
private String makeNum(){
Random random = new Random();
String num = random.nextInt(99999) + "";
StringBuffer buffer = new StringBuffer();
//确保生成的
for (int i = 0; i < 5-num.length(); i++) {
buffer.append("0");
}
num=buffer.toString()+num;
return num;
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
转发重定向等三种方法
package com.wang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Arrays;
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[] hobbys = req.getParameterValues("hobbys");
System.out.println("-----------------------------");
System.out.println(username+":"+password);
System.out.println(Arrays.toString(hobbys));
System.out.println("-----------------------------");
/**
* 重定向的方式:
* 1、重定向:resp.sendRedirect();
* 2、转发:this.getServletContext()
* 3、通过请求转发:req.getRequestDispatcher("/success.jsp").forward(req,resp);
*/
//resp.sendRedirect();
//this.getServletContext()
req.getRequestDispatcher("/success.jsp").forward(req,resp);
// 转发到哪里
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1 style="text-align: center">Hello,World</h1>
<form action="${pageContext.request.contextPath}/login" method="post" style="text-align: center">
账户:<input type="text" name="username"><br>
密码:<input type="password" name="password"><br>
爱好:<br>
<input type="checkbox" name="hobbys" value="游戏">游戏
<input type="checkbox" name="hobbys" value="代码">代码
<input type="checkbox" name="hobbys" value="唱歌">唱歌
<input type="checkbox" name="hobbys" value="电影">电影<br>
<input type="submit">
</form>
</body>
</html>
success.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>登陆成功</h1>
</body>
</html>
---------------------------------------------------------------------------------------------------------
Cookie 小饼干
Cookie,当客户端第一次访问网页时,服务器给这个客户端一个cookie(信件),以后这个客户端再次访问这个网页时,拿着这个cookie就可以了,
cookie是保存在本地的
package com.wang.servlet;
import javax.servlet.ServletException;
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("GBK");
resp.setCharacterEncoding("GBK");
PrintWriter out = resp.getWriter();
Cookie[] cookies = req.getCookies();
if (cookies!=null){
out.write("您上次访问本网站的时间为:");
for (int i = 0; i < cookies.length; i++) {
Cookie cookie=cookies[i];
if (cookie.getName().equals("LastLoginTime")){
long lastlogintime = Long.parseLong(cookie.getValue());
Date date = new Date(lastlogintime);
out.write(date.toLocaleString());
}
}
}else {
out.write("这是您第一次访问本网站");
}
//把Cookie new出来,放一个key值和一个value值
Cookie lastLoginTime = new Cookie("LastLoginTime", System.currentTimeMillis() + "");
//设置Cookie的有效时间
lastLoginTime.setMaxAge(24*60*60);//按照秒来计算的
//给客户端响应回去,添加一个Cookie,这个Cokkie用于记录客户端在本次会话(未关闭浏览器)的上次访问时间
resp.addCookie(lastLoginTime);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
设置cookie的有效期
package com.wang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class CookieDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Cookie[] cookies = req.getCookies();
//获取请求过来的cookie
Cookie cookie = new Cookie("LastLoginTime", System.currentTimeMillis() + "");
//创建一个新的cookie
cookie.setMaxAge(0);
//设置cookie的有效期为0
resp.addCookie(cookie);
//给客户端响应回去,添加一个cookie
//删除cookie的方式:
/**
* 创建一个新的web网页,设置一个与要删除的cookie的相同的key值,然后设置有效期为0(cookie.setMaxAge(0);
* 在使用完上一个网页后,需要删除的时候,进入这个网页,有效期为0,上一个cookie会自动失效
*/
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Session 会话
Session,当客户端第一次访问网页时,由服务器等级该客户端信息,用户拿到SessionID,下次再次访问这个网页的时候可以通过SessionID去服务器直接找到最硬的用户信息,
Session保存在每个浏览器的Session中,每个浏览器的Session都不一样
SessionID相当于一把钥匙,拿着钥匙就可以去服务器哪里打开相应的房间
Session可以保存一些信息,而Cookie不能
在得到Session时,后台自动创建一个Cookie,并将Session保存在Cookie中
package com.wang.servlet;
import com.wang.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo01 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
//得到一个Session
HttpSession session = req.getSession();
//在Session中存入信息 一个String类型,一个是Object类型。
session.setAttribute("name",new Person("小王",18));
//获取Session的ID
String sessionId = session.getId();
if (session.isNew()){
resp.getWriter().write("Session创建成功,SessionID:"+sessionId);
}else{
resp.getWriter().write("Session已经在服务器中创建成功了,SessionID:"+sessionId);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
Persion:
package com.wang.pojo;
public class Person {
private String name;
private int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
当在服务器中保存Session后,可以在其他的后台Servlet中获取保存的这个Sessiion
package com.wang.servlet;
import com.wang.pojo.Person;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDemo02 extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setCharacterEncoding("utf-8");
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html");
//获取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节点和清除Session
package com.wang.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
public class SessionDeemo03 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");
//获取Sesdsion
HttpSession session = req.getSession();
//清楚保存的节点信息
session.removeAttribute("name");
//删除Session,当下次再次打开的时候,会立刻自动生成一个新的Session
session.invalidate();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
还可以在web.xml中设置Session的有效期
<?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_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>Cookie</servlet-name>
<servlet-class>com.wang.servlet.CookieDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Cookie</servlet-name>
<url-pattern>/cookie</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>Cookie02</servlet-name>
<servlet-class>com.wang.servlet.CookieDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Cookie02</servlet-name>
<url-pattern>/c2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>sessiondemo01</servlet-name>
<servlet-class>com.wang.servlet.SessionDemo01</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sessiondemo01</servlet-name>
<url-pattern>/s1</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>sessiondemo02</servlet-name>
<servlet-class>com.wang.servlet.SessionDemo02</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sessiondemo02</servlet-name>
<url-pattern>/s2</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>sessiondemo03</servlet-name>
<servlet-class>com.wang.servlet.SessionDeemo03</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>sessiondemo03</servlet-name>
<url-pattern>/s3</url-pattern>
</servlet-mapping>
<session-config>
<!-- 可以设置session的属性-->
<!-- 设置session的失效时间,设置为1分钟后session失效,会重新创建一个新的session,以分钟为单位-->
<session-timeout>1</session-timeout>
</session-config>
</web-app>
---------------------------------------------------------------------------------------------------------
JSP操作
<%@ page import="java.util.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%--JSP表达式,用来将程序的输出,输出到客户端
<%= 变量或者表达式%>
--%>
<%= new Date()%>
<%--ALT+Enter自动导包--%>
<%-- JSP脚本片段--%>
<%
int sum=0;
for (int i = 1; i <=100 ; i++) {
sum=sum+i;
}
out.print("<h1>sum="+sum+"</h1>");
%>
<%
int x=10;
out.println(x);
%>
<h1>hello</h1>
<%
out.print("<span>x="+x+"</span>");
%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>你好小杨 <%=i%></h1>
<%
}
%>
<hr>
<%-- 上面的都是定义在方法里面的--%>
<hr>
<%--在方法外面定义:--%>
<%!
//JSP声明
static {//静态代码块
System.out.println("Loading Servlet");
}
private int globalVar=0;
public void wang(){
System.out.println("进入了方法wang");
}
%>
<hr>
<h1>EL表达式</h1>
<h1>JSP注释:</h1>
<%-- 我是JSP的注释--%>
<h1>JSP的注释不会在客户端的查看源代码中显示,HTML的注释就会显示</h1>
<h1>HTML注释:</h1>
<!--我是HTML的注释-->
</body>
</html>
自定义错误页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@page errorPage="error/500.jsp" %>
<%-- 错误页面发生时,自动跳转到这也页面,不会跳转到系统默认的错误页面 --%>
<html>
<%--
在自定义的500页面
--%>
<head>
<title>Title</title>
</head>
<body>
<%
int i=1/0;
%>
</body>
</html>
错误页面转发也可以在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">
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
<error-page>
<error-code>500</error-code>
<location>/error/500.jsp</location>
</error-page>
</web-app>
网页中,多个网页的公共部分可以不重复写
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--
用这种方法,@include会将两个页面合二为一
最后是一个页面
合成一个页面后,其他页面不能定义相同的变量例如:在两个页面都定义 int i=0,合到一起后就会报500错误
--%>
<%@include file="common/header.jsp"%>
<%--included 包含,可以提取公共的地方,然后直接用include引用--%>
<h1>网页主题</h1>
<%@include file="common/footer.jsp"%>
<hr>
<%--JSP标签
jsp:include这种方法是拼接页面
本质还是三个页面
一般用这种方法,灵活性高
拼接一个页面后,本质其实还是三个页面,其他页面能定义相同的变量例如:在两个页面都定义 int i=0,拼接一起后不会报错
--%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主题</h1>
<jsp:include page="/common/footer.jsp"/>
</body>
</html>
header.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>我是Header</h1>
footer.jsp:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>我是Footer</h1>
jsp内置对象
<%@ page import="javafx.application.Application" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--内置对象--%>
<%
pageContext.setAttribute("name1","小王1号");//只在本页面有效,其他页面失效
request.setAttribute("name2","小王2号");//只在一次请求中有效,请求可以转发,但是如果转发失败,则也会失效
session.setAttribute("name3","小王3号");//在一次会话中有效,从打开浏览器到关闭浏览器都有效
application.setAttribute("name4","小王4号");//在服务器中有效,从打开服务器到关闭服务器之间有效
%>
<%--<%--%>
<%-- pageContext.getAttribute("name1");--%>
<%-- pageContext.getAttribute("name2");--%>
<%-- pageContext.getAttribute("name3");--%>
<%-- pageContext.getAttribute("name4");--%>
<%-- pageContext.getAttribute("name5");--%>
<%--%>--%>
<%
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");
//转发,先存入数据后,转发到另一个网页,这是,name2可以在另一个网页拿到了
pageContext.forward("/pageDemo03.jsp");
%>
<h1>拿到的数据是:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<%--
由上述代码可知,并不存在name5这个数据,所以,用EL表达式输出的时候,就没有输出name5
但是,如果用<%=%>输出这些数据时,name5就会输出为NULL
--%>
</body>
</html>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
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");
%>
<h1>拿到的数据是:</h1>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<h3>${name5}</h3>
<%--
只能拿到name3和name4
说明只有name3和name4有效
--%>
</body>
</html>
pageContext.setAttribute("name1","小王1号");//只在本页面有效,其他页面失效
request.setAttribute("name2","小王2号");//只在一次请求中有效,请求可以转发,但是如果转发失败,则也会失效
session.setAttribute("name3","小王3号");//在一次会话中有效,从打开浏览器到关闭浏览器都有效
application.setAttribute("name4","小王4号");//在服务器中有效,从打开服务器到关闭服务器之间有效
四种方法都可以存储一些信息,但是作用域不同
if语句
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%--导入这个头文件--%>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>if测试</h1>
<form action="/coreif.jsp" method="get">
<input type="text" name="name" value="${param.name}">
<input type="submit" value="登陆">
</form>
<%-- 比较输入提交过来的是不是Dying,用这个Var接收--%>
<c:if test="${param.name=='Dying'}" var="admin">
<c:out value="欢迎登陆"/>
</c:if>
<%--输出一下上面的Var--%>
<c:out value="${admin}"/>
</body>
</html>
when语句
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<form action="/corewwhen.jsp" method="get">
请输入您的期末成绩:
<input type="text" name="grade">
<input type="submit" value="提交">
</form>
<%--类似于java中的switch--%>
<c:choose>
<c:when test="${param.grade>=90}">
您的成绩为优秀
</c:when>
<c:when test="${param.grade>=80}">
您的成绩为良好
</c:when>
<c:when test="${param.grade>=60}">
您的成绩为及格
</c:when>
<c:when test="${param.grade<60}">
您的成绩不及格
</c:when>
</c:choose>
</body>
</html>
foreach遍历
<%@ page import="java.util.ArrayList" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
ArrayList<String> people = new ArrayList<>();
people.add(0,"张三");
people.add(1,"李四");
people.add(2,"王五");
people.add(3,"赵六");
people.add(4,"田七");
request.setAttribute("user",people);
for (String user:people) {
}
%>
<%--
items :从这里开始一个一个遍历,遍历出来的值放到var中
然后下面输出var的值
类似于java中遍历
for (String user:people) {
}
begin: 从哪里开始
end : 到哪里结束
step :步长
--%>
<c:forEach var="name" items="${user}">
<c:out value="${name}"/> <br>
</c:forEach>
</body>
</html>
JavaBean :
<%@ page import="com.wang.pojo.people" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%--类似于:
<%
people people = new people();
people.setName();
people.setId();
people.setAddress();
people.setAge();
%>
--%>
<jsp:useBean id="people" class="com.wang.pojo.people" scope="page"/>
<%-- 叫什么 路径 作用域 --%>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="小王"/>
<jsp:setProperty name="people" property="age" value="18"/>
<jsp:setProperty name="people" property="address" value="河南"/>
<%--在这个类中设置属性的值--%>
id:<jsp:getProperty name="people" property="id"/>
name:<jsp:getProperty name="people" property="name"/>
address:<jsp:getProperty name="people" property="address"/>
age:<jsp:getProperty name="people" property="age"/>
</body>
</html>
people:
创建了三个属性,然后与数据库连接,
在JavaBean中使用
package com.wang.pojo;
public class people {
private int id;
private String name;
private int age;
private String address;
public people() {
}
public people(int id, String name, int age, String address) {
this.id = id;
this.name = name;
this.age = age;
this.address = address;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "people{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
'}';
}
}
MVC三层架构
View
展示数据
提供链接发起Servlet请求
Controller
接收用户的请求(req:请求参数 Session信息。。。)
交给业务层处理对应的代码
控制试图的跳转
登录
---》 接收用户的登录请求
---》 处理用户的请求(获取用户登录的参数,username,password)
---》 交给业务处理登录业务(判断用户名密码是否正确:事务)
---》 Dao层查询用户名和密码是否正确
---》 数据库
Model
业务处理:业务逻辑(Service)
数据持久层:CRUD(Dao)
过滤器:
记住导包不要导错
已知,在我们的Servlet中往前台页面输出汉字的时候会出现乱码问题
package com.wang.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 ShowServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//此时,页面显示会出现乱码问题
//我们通常会使用设置编码属性来调整,但是这样每一次都要写,所以,我们可以使用过滤器来简化操作
resp.getWriter().print("你好世界!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
过滤器:
package com.wang.Filter;
import javax.servlet.*;
import java.io.IOException;
public class CharacterEncodingFilter implements Filter {
//初始化 ,当服务器启动的时候,过滤器就随着服务器一起启动了,随时监听过滤
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("CharacterEncodingFilter初始化");
}
/**
* 1、过滤器中所有代码,在过滤特定请求的时候都会执行
* 2、必须要让过滤器继续执行 也就是 filterChain.doFilter(servletRequest,servletResponse);
* @param servletRequest
* @param servletResponse
* @param filterChain
* @throws IOException
* @throws ServletException
*/
@Override
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("执行过滤前...");
//让过滤器继续执行,如果不写这一句,程序到这里就会停止
//chain :链,因为可能有多个过滤器,必须写这一句让过滤器继续执行
filterChain.doFilter(servletRequest,servletResponse);
System.out.println("执行过滤后");
}
//销毁,web服务器关闭的时候,我们的过滤器才会销毁
@Override
public void destroy() {
System.out.println("CharacterEncodingFilter销毁");
}
}
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">
<servlet>
<servlet-name>ShowServlet</servlet-name>
<servlet-class>com.wang.Servlet.ShowServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ShowServlet</servlet-name>
<url-pattern>/show</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ShowServlet</servlet-name>
<url-pattern>/servlet/show</url-pattern>
</servlet-mapping>
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>com.wang.Filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<!-- 只要是经过 /servlet下面的所有请求都会进行过滤-->
<url-pattern>/servlet/*</url-pattern>
</filter-mapping>
</web-app>
监听器(例子)
监听器实现统计在线人数
package com.wang.listener;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
//用监听器统计网站在线人数-统计session个数
//开始时,有三个人在线,可能是访问失败了,但是Session已经存在了
//我们把 服务器重新部署一下就可以了
public class OnlineCountListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer attribute = (Integer) context.getAttribute("onlinecount");
if (attribute==null){
attribute=new Integer(1);
}else {
int i = attribute.intValue();
attribute=new Integer(i+1);
}
context.setAttribute("onlinecount",attribute);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer attribute = (Integer) context.getAttribute("onlinecount");
if (attribute==null){
attribute=new Integer(0);
}else {
int i = attribute.intValue();
attribute=new Integer(i-1);
}
context.setAttribute("onlinecount",attribute);
}
}
测试页面:
index.jsp
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<%-- 可以用:this.getServletConfig().getServletContext().getAttribute("onlinecount")--%>
<h1>当前有 <span><%=request.getServletContext().getAttribute("onlinecount")%></span> 个人在线</h1>
</body>
</html>
在web.xml中注册:
在web.xml中注册监听器后,服务器启动时,监听器自动启动
<listener>
<listener-class>com.wang.listener.OnlineCountListener</listener-class>
</listener>
登陆跳转的实现
首页:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>$Title$</title>
</head>
<body>
<form action="/lo" method="post">
账户:
<input type="text" name="username">
<input type="submit" value="登录">
</form>
</body>
</html>
登陆成功:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<%
/**
* 此处用来判断,如果账户被注销,
* 里面保存的数据 USER_NAME以及其value值被删除
* 那么这个username会为空,加一层判断,为空则不允许继续访问该页面,跳转回登陆首页
* 不建议在这里实现这个功能,建议使用过滤器完成
*/
// Object username = request.getSession().getAttribute("USER_NAME");
// if (username==null){
// response.sendRedirect("/index.jsp");
// }
%>
<h1>您好,欢迎登陆</h1>
<a href="/delete">注销</a>
<%
out.print(request.getSession().getAttribute("USER_NAME"));
%>
</body>
</html>
登陆失败:
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
<title>Title</title>
</head>
<body>
<h1>抱歉,登陆失败!</h1>
</body>
</html>
监听器:注销后不能直接通过地址进入登陆页面
package com.wang.login;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSessionListener;
import java.io.IOException;
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
Filter.super.init(filterConfig);
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
//首先要把这里的ServletRequest和ServletResponse强转为HttpServletRequest和HttpServletResponse
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//强制转换后才能拿到它的Session
Object userName = request.getSession().getAttribute("USER_NAME");
if (userName==null){
response.sendRedirect("/error.jsp");
}
//什么都不做,但这一句必须写,让程序可以继续执行下去
filterChain.doFilter(req,resp);
}
@Override
public void destroy() {
Filter.super.destroy();
}
}
登陆时请求处理:
package com.wang.login;
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 login extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
if (username.equals("admin")){
req.getSession().setAttribute("USER_NAME",req.getSession().getId());
resp.sendRedirect("/sys/success.jsp");
}else {
resp.sendRedirect("/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
注销时请求的处理;
package com.wang.login;
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 delete extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.getSession().removeAttribute("USER_NAME");
resp.sendRedirect("/index.jsp");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
web.xml中注册上面的Servlet,Filter,
<?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">
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>com.wang.login.login</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/lo</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>delete</servlet-name>
<servlet-class>com.wang.login.delete</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>delete</servlet-name>
<url-pattern>/delete</url-pattern>
</servlet-mapping>
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.wang.login.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/sys/*</url-pattern>
</filter-mapping>
</web-app>
由此可以实现页面之间的相互跳转,可以把上面的公共变量提取出来,写到一个单独的类中,写成静态常量,这样可以减少修改时产生的一些麻烦
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.wang</groupId>
<artifactId>javawweb-filter-02</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- Servlet的依赖-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
<!-- JSP的依赖 -->
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>javax.servlet.jsp-api</artifactId>
<version>2.3.3</version>
<scope>provided</scope>
</dependency>
<!-- JSLTL表达式的依赖 -->
<dependency>
<groupId>javax.servlet.jsp.jstl</groupId>
<artifactId>jstl-api</artifactId>
<version>1.2</version>
</dependency>
<!-- standard标签库 -->
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</project>