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

image-20231210192026196

共享数据

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

image-20231210192218373

要先访问HelloServlet对应的路由,再访问GetServlet对应的路由即可

image-20231210192634021

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);
    }
}

image-20231210204859722

转发后,其他无效,只显示/hello1的页面

image-20231210204324527

getResourceAsStream

image-20231210220730875

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只能保存一个信息
  • 一个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)

image-20231219174850119

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

image-20231219182727934

image-20231219183705792

jsp语法

热部署

要是exploded这个

image-20231219190327668

然后改为这样既可

image-20231219190404430

这样就不用每次重启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>
<%
    }
%>

image-20231219191031818

因为本质就是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%>

双亲委派机制 (与作用域进行类比)

想要重写一个类,但加载时会在类加载器中不断地往上找,在最上面加载器中找到的话,只会使用根加载器的,不会使用你重写的

作用域

image-20231219214300845

指定作用域

<%pageContext.setAttribute("name","123",3);%>
//都是请求转发

<%
    pageContext.forward("/hello/hello.jsp");
    request.getRequestDispatcher("/hello/hello.jsp").forward(request,response);
%>

MVC框架

Model

增删改查

view

controller

image-20231220153426022

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>

javaweb
https://zer0peach.github.io/2023/12/10/javaweb/
作者
Zer0peach
发布于
2023年12月10日
许可协议