javaweb
javaweb
前言
跟着Boogipop大佬学java,这部分拖太久了,忙完下周的一个期末考试,趁其他考试还没来时赶紧学完这些开发的东西
参照Boogipop大佬的学习,学完Servlet和Listener和FIlter这部分就可以结束了
maven
M2_HOME E:\CTF学习笔记\Java\apache-maven-3.8.6-bin\apache-maven-3.8.6\bin
MAVEN_HOME E:\CTF学习笔记\Java\apache-maven-3.8.6-bin\apache-maven-3.8.6
在Path下添加%MAVEN_HOME%\bin
修改conf/setting.xml
<mirror>
<id>aliyunmaven</id>
<mirrorOf>*</mirrorOf>
<name>阿里云公共仓库</name>
<url>https://maven.aliyun.com/repository/public</url>
</mirror>
<localRepository>E:\CTF学习笔记\Java\apache-maven-3.8.6-bin\apache-maven-3.8.6\maven-repo</localRepository>
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.io.PrintWriter;
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter();
writer.println("hahahhahahahha");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
注册servlet
更新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"
metadata-complete="true">
</web-app>
<?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"
metadata-complete="true">
<!--注册servlet-->
<servlet>
<servlet-name>hello1</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<!--设置路由-->
<servlet-mapping>
<servlet-name>hello1</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>hello1</servlet-name>
<url-pattern>*.asd</url-pattern> //自定义以.asd结尾,*前面不加/
</servlet-mapping>
<servlet>
<servlet-name>error</servlet-name>
<servlet-class>ErrorServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>error</servlet-name>
<url-pattern>/*</url-pattern> //优先级较低
</servlet-mapping>
</web-app >
ServletContent
共享数据
public class GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String user = (String)servletContext.getAttribute("user");
resp.getWriter().println(user);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
resp.setContentType("text/html");
resp.setCharacterEncoding("utf-8");
PrintWriter writer = resp.getWriter();
writer.println("hahahhahahahha");
ServletContext servletContext = this.getServletContext();
servletContext.setAttribute("user","asdsadssad");
}
直接访问GetServlet对应的路由,显示为null
要先访问HelloServlet对应的路由,再访问GetServlet对应的路由即可
getinitparam
web.xml中设置初始参数值
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String user = (String)servletContext.getAttribute("user");
resp.getWriter().println(user);
String cmd1 = servletContext.getInitParameter("cmd");
resp.getWriter().println(cmd1);
}
<?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"
metadata-complete="true">
<!--注册servlet-->
<servlet>
<servlet-name>hello1</servlet-name>
<servlet-class>HelloServlet</servlet-class>
</servlet>
<!--设置路由-->
<servlet-mapping>
<servlet-name>hello1</servlet-name>
<url-pattern>/hello1</url-pattern>
</servlet-mapping>
<context-param>
<param-name>cmd</param-name>
<param-value>jdbc:mysql://localhost:3306/test</param-value>
</context-param>
</web-app >
getRequestDispatcher
请求转发
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 GetServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
ServletContext servletContext = this.getServletContext();
String user = (String)servletContext.getAttribute("user");
resp.getWriter().println(user);
String cmd1 = servletContext.getInitParameter("cmd");
resp.getWriter().println(cmd1);
servletContext.getRequestDispatcher("/hello1").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
转发后,其他无效,只显示/hello1
的页面
getResourceAsStream
resources目录下的和java目录下的都会被打包到classes
目录下
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 ResourceServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
InputStream stream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/cb.properties");
Properties properties = new Properties();
properties.load(stream);
String username = properties.getProperty("username");
resp.getWriter().println(username);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
当properties文件不在resources目录下时,有可能无法导出
在pom.xml添加一段代码即可
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
response下载文件
关键在于响应的请求头Content-Disposition
,内容为attachment;filename=
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.FileOutputStream;
import java.io.IOException;
public class DownServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String path = "C:\\Users\\86136\\Pictures\\Saved Pictures\\yunchong.png";
String filename = path.substring(path.lastIndexOf("\\")+1);
resp.setHeader("Content-Disposition","attachment;filename="+filename);
FileInputStream in = new FileInputStream(path);
int len = 0;
byte[] bytes = new byte[1024];
ServletOutputStream out = resp.getOutputStream();
while ((len = in.read(bytes))!=0){
out.write(bytes,0,len);
}
out.close();
in.close();
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
response 验证码
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;
public class ImageServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//内存中生成
BufferedImage image = new BufferedImage(80, 20, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) image.getGraphics();
g.setColor(Color.BLUE);
g.fillRect(0,0,80,20);
g.setColor(Color.BLACK);
g.setFont(new Font(null,Font.BOLD,20));
g.drawString("123456",0,20);
resp.setContentType("image/jpg");
resp.setHeader("Cache-Control","no-cache");
ImageIO.write(image, "jpg", resp.getOutputStream());
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
}
}
response 重定向
设置跳转路径时,注意加上页面设置时的虚拟映射
//index.jsp
<%@page contentType="text/html; charset=utf-8" pageEncoding="UTF-8" %>
<html>
<body>
<h2>Hello World!</h2>
<form action="redirect" method="get">
用户 <input type="text" name="username">
密码 <input type="password" name="password">
<input type="submit">
<input type="search">
</form>
</body>
</html>
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 {
String username = req.getParameter("username");
String password = req.getParameter("password");
System.out.println(username+":"+password);
resp.sendRedirect("/hello/success.jsp"); //要包含页面设置时的虚拟映射
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
request
req.getRequestDispatcher("success.jsp").forward(req,resp);
请求路径已经在虚拟映射的路径下了,不用再写虚拟映射的路径,另外这里success.jsp
加不加/
是一样的
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 RedirectServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String username = req.getParameter("username");
String password = req.getParameter("password");
String[] hobbys = req.getParameterValues("hobbys");
System.out.println(hobbys);
System.out.println(Arrays.toString(hobbys));
System.out.println(username+":"+password);
System.out.println(req.getContextPath());
// resp.sendRedirect("/hello/success.jsp");
req.getRequestDispatcher("success.jsp").forward(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
cookie (客户端携带)
- 一个cookie只能保存一个信息
- 一个web站点可以给浏览器发送多个cookie,最多存放20个cookie
- cookie大小有限制4kb
- 300个cookie浏览器上限
删除cookie
- 不设置有效期
- 设置有效期为0
传递中文
URLEncoder.encode("啊啊啊","utf-8")
URLDecoder.decode(cookie.getValue(),"utf-8")
session
什么是session:
- 服务器会给浏览器创建一个session对象
- 一个session独占一个浏览器,只要浏览器没有关闭,这个session就存在
- 用户登陆之后,整个网站他都可以访问
session和cookie的区别
cookie是把用户的数据写到用户的浏览器中,可以保存多个cookie
session是把用户的数据写到用户独占的session中,服务器端保存(保存重要的信息,减少服务器资源的浪费)
session对象由服务器创建
session创建的逻辑实际上是
Cookie cookie = new cookie("JSESSIONID",id)
addCookie(cookie)
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
resp.setContentType("text/plain;charset=utf-8");
PrintWriter writer = resp.getWriter();
HttpSession session = req.getSession();
session.setAttribute("name", "zeropeach");
String id = session.getId();
writer.println("session的id为"+id);
//判断是不是新创建的session,只有当session被销毁时才会重新自动生成
writer.println(session.isNew());
//获取session内容
HttpSession session = req.getSession();
Object name = session.getAttribute("name");
System.out.println(name.toString());
//销毁session
HttpSession session = req.getSession();
session.removeAttribute("name");
session.invalidate();
当有两个sessionid时,session不能共享对象,可以通过ServletContext(也叫ApplicationContext)
jsp原理
全称 Java Servlet Pages
说明也是一个java程序,是一个servlet
D:\idea_2022.3\.IntelliJIdea\system\tomcat\81de8c7e-5d87-4185-9841-7ba31aa3bac6\work\Catalina\localhost\hello\org\apache\jsp
jsp语法
热部署
要是exploded这个
然后改为这样既可
这样就不用每次重启tomcat,只需要刷新页面即可
基础语法
<%--
<%= 变量或表达式%> 用来输出
--%>
<%= new java.util.Date()%>
<%
int sum=0;
for (int i = 0; i <= 100; i++) {
sum +=i;
}
out.println("<h1>sum"+sum+"</h1>");
%>
<%
int y = 2;
%>
<%
out.println(y);
%>
<%
for (int i = 0; i < 5; i++) {
%>
<h1>wow</h1>
<%
}
%>
因为本质就是java文件,所以能用java语法,作用域也是一样,于是可以配合HTML
循环输出
jsp声明
<%! %> 声明全局变量和全局方法
<%!
static {
System.out.println("666");
}
private int m = 8848;
%>
使用声明后,后被写到java类的作用域下,与原方法同级
<%--注释--%>
jsp的注释不会在客户端的源代码中出现
在jsp中加入这一句,遇到错误就跳转到500.jsp
<%@ page errorPage="error/500.jsp" %> //自定义错误页面
也可以修改web.xml,当遇到404时,就会跳到404.jsp
<error-page>
<error-code>404</error-code>
<location>/error/404.jsp</location>
</error-page>
页面内容合二为一
<%@include file=""%> //文件包含
页面内容拼接,实际还是多个页面
<jsp:include page="500.jsp" />
jsp 内置对象
<%
pageContext.setAttribute("name1","1"); //保存的数据只在一个页面中有效
request.setAttribute("name2","2"); //只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","3"); //只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","4"); //在服务器中有效 ,从打开服务器到关闭服务器
%>
<%
String name1 = (String) pageContext.getAttribute("name1");
String name2 = (String) pageContext.getAttribute("name2");
String name3 = (String) pageContext.getAttribute("name3");
String name4 = (String) pageContext.getAttribute("name4");
String name5 = (String) pageContext.getAttribute("name5");
%>
<h3>${name1}</h3>
<h3>${name2}</h3>
<h3>${name3}</h3>
<h3>${name4}</h3>
<%=name5%>
双亲委派机制 (与作用域进行类比)
想要重写一个类,但加载时会在类加载器中不断地往上找,在最上面加载器中找到的话,只会使用根加载器的,不会使用你重写的
作用域
指定作用域
<%pageContext.setAttribute("name","123",3);%>
//都是请求转发
<%
pageContext.forward("/hello/hello.jsp");
request.getRequestDispatcher("/hello/hello.jsp").forward(request,response);
%>
MVC框架
Model
增删改查
view
controller
Filter
导入的包不要错 javax.servlet.Filter
import javax.servlet.*;
import java.io.IOException;
public class TestFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("初始化");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
request.setCharacterEncoding("utf-8");
response.setCharacterEncoding("utf-8");
response.setContentType("text/plain;charset=utf-8");
System.out.println("执行前");
chain.doFilter(request,response);
System.out.println("执行后");
}
@Override
public void destroy() {
System.out.println("销毁");
}
}
web.xml
<filter>
<filter-name>filter</filter-name>
<filter-class>TestFilter</filter-class>
</filter>
<!--相对路径,不用包含映射-->
<filter-mapping>
<filter-name>filter</filter-name>
<url-pattern>/hello.jsp</url-pattern>
</filter-mapping>
Listener
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
public class OnlineListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
System.out.println(se.getSession().getId());
Integer count = (Integer) context.getAttribute("OnlineCount");
if (count==null){
count = new Integer(1);
}
else {
int i = count.intValue();
count = new Integer(i+1);
}
context.setAttribute("OnlineCount",count);
}
@Override
public void sessionDestroyed(HttpSessionEvent se) {
ServletContext context = se.getSession().getServletContext();
Integer count = (Integer) context.getAttribute("OnlineCount");
if (count==null){
count = new Integer(0);
}
else {
int i = count.intValue();
count = new Integer(i-1);
}
context.setAttribute("OnlineCount",count);
}
}
web.xml
<listener>
<listener-class>OnlineListener</listener-class>
</listener>
Filter权限管理案例
写的时候注意跳转的地方,我在写的时候写出个一直重定向的错误 。。。
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
Object userSession = req.getSession().getAttribute("USER_SESSION");
if (userSession==null){
resp.sendRedirect("/hello/sys/error.jsp");
}
chain.doFilter(req,resp);
}
@Override
public void destroy() {
}
}
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 LoginServlet 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_SESSION",req.getSession().getId());
resp.sendRedirect("/hello/success.jsp");
}
else {
resp.sendRedirect("/hello/sys/error.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
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 LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Object userSession = req.getSession().getAttribute("USER_SESSION");
if (userSession!=null){
req.getSession().removeAttribute("USER_SESSION");
resp.sendRedirect("/hello/sys/login.jsp");
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
super.doPost(req, resp);
}
}
<servlet>
<servlet-name>login</servlet-name>
<servlet-class>LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>login</servlet-name>
<url-pattern>/sys/login</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>logout</servlet-name>
<servlet-class>LogoutServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>logout</servlet-name>
<url-pattern>/sys/logout</url-pattern>
</servlet-mapping>
<filter>
<filter-name>log</filter-name>
<filter-class>SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>log</filter-name>
<url-pattern>/success.jsp</url-pattern>
</filter-mapping>
<filter-mapping>
<filter-name>log</filter-name>
<url-pattern>/sys/logout.jsp</url-pattern>
</filter-mapping>