JavaWeb 入门

JavaWeb

使用 Maven 构建项目中的 pom 文件

众所周知 maven 包管理工具是个好东西,在项目中使用 maven 做包管理工具是个不错的选择。所以我们这次也是用的 maven 来做包管理工具的,下面这个就是构建 javaweb项目所要用到的 pom 文件中要用到的 jar 包

<dependencies>
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.11</version>
<!--      <scope>test</scope>-->
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet.jsp/javax.servlet.jsp-api -->
<dependency>
  <groupId>javax.servlet.jsp</groupId>
  <artifactId>javax.servlet.jsp-api</artifactId>
  <version>2.3.3</version>
  <scope>provided</scope>
</dependency>
<dependency>
  <groupId>javax.servlet</groupId>
  <artifactId>javax.servlet-api</artifactId>
  <version>4.0.1</version>
</dependency>
<!--jstl 表达式依赖-->
<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>8.0.28</version>
</dependency>
</dependencies>

第一个 Servlet 程序 HelloWorld

众所周知,HelloWorld 也是每项技术的第一个程序。

servlet 程序是要继承 HttpServlet 类的,所以我们每次写 Servlet 程序的时候都要继承 HttpServlet 类。

在程序里面我们还需要重写 DoGet 和 DoPost 这两个方法。

public class HelloServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 向客户端输出信息
        PrintWriter writer = resp.getWriter();
        writer.print("Hello, Servlet!");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 调用 doGet 方法
        doGet(req, resp);
    }
}

配置映射

我们写完上面这个类,要想在浏览器中使用和调用这个类,我们还需要配置 mapping 否则浏览器是不知道该怎么运行和找到该要运行的类的

我们需要在 web.xml 中配置其映射,这个文件在 webapp > WEB-INF > web.xml

<!DOCTYPE web-app PUBLIC
        "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
        "http://java.sun.com/dtd/web-app_2_3.dtd" >

<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">
    <display-name>Archetype Created Web Application</display-name>

    <servlet>
        <!--在 servlet 中的名字-->
        <servlet-name>hello</servlet-name>
        <!--所要运行的类-->
        <servlet-class>com.niuma.test.HelloServlet</servlet-class>
    </servlet>
    <servlet-mapping>
        <!--与前面所要运行的类的名字相对应-->
        <servlet-name>hello</servlet-name>
        <!--在浏览器中反问的相对地址路径-->
        <url-pattern>/hello</url-pattern>
    </servlet-mapping>
</web-app>

配置好这个映射之后,我们就可以运行项目,运行项目之后会自动弹出浏览器的页面,这时候我们在后面输入我们设置好的路径就可以访问到我们上面所写好的类所放回的内容了。

ServletContext 上下文对象

这个对象可以将我们写的每个类中的数据相互串联,例如我们在登录一个平台的时候,我们在登录界面登录了我们的账号,那么在这个平台里面的每个网页都会有我们的信息。ServletContext 就可以完成这个功能。

我们先创建一个类,这个类用来向 ServletContext 中写入输入

public class SetUserName extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建 Servlet 上下文对象
        ServletContext context = this.getServletContext();
        String userName = "牛马";
        // 将数据保存到 ServletContext 里面
        context.setAttribute("userName", userName);
        System.out.println("已将元素存入 ServletContext 中");
        // 设置响应的格式和编码
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        // 向客户端输出信息
        resp.getWriter().print("已将元素存入 ServletContext 中");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

再写一个类来读取 ServletContext 中的数据

public class GetUserName extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建 ServletContext 对象
        ServletContext context = this.getServletContext();
        // 读取 ServletContext 对象中的信息
        String userName = (String) context.getAttribute("userName");
        // 设置响应的格式和编码
        resp.setContentType("text/html");
        resp.setCharacterEncoding("utf-8");
        // 向客户端输出信息
        resp.getWriter().print("名字:" + userName);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

当然我们写好这两个类的时候我们还需要到 web.xml 中配置 mapping

两个类都需要配置

在配置好了之后,我们启动项目访问我们设置好的路径,如果我们先访问的是获取 ServletContext 数据这个类的话,我们看到的信息是:名字:null

这个问题就出在没有在 ServletContext 中存入数据,所以我要先访问存入数据的那个类,然后再访问获取信息的这个类就可以看到我们想要的结果了。

读取文件

我们可以在 resource 中读取我们的配置文件

我们先在 resource 中建立一个名为: db.properties 的文件,然后在里面写入

username = root
passwd = 123456

然后创建一个类来读取其中的文件

public class ServletGetResource extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建输入流对象
        InputStream is = this.getServletContext().getResourceAsStream("WEB-INF/classes/db.properties");
        // 创建 Properties 对象,用来读取配置文件
        Properties prop = new Properties();
        // 读取信息
        prop.load(is);
        // 取出其中的配置信息
        String username = prop.getProperty("username");
        String passwd = prop.getProperty("passwd");
        resp.getWriter().print(username + ":" + passwd);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

这时候我们启动项目访问我们设置好的类就可以看到我们我们向客户端输出的信息了

我们每次写好一个类都要配置 mapping 然后重启项目,这样项目就会重新构建,否者我们是无法立刻在浏览器中看到我们想要看到的东西的。

文件下载

在浏览器中我们经常会在网上下载图片什么的,现在我们就来实现一下如何从 web 下载到图片

public class FileServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = "WEB-INF/classes/牛马.png";
        // 获取下载文件的路径
        String realPath = this.getServletContext().getRealPath(name);
        System.out.println("下载文件的地址:" + realPath);
        // 下载的文件是什么
        String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
        // 设置浏览器能够想办法支持 (Content-Disposition) 下载我们需要的东西,中文文件名 URLEncoder.encode 编码,否则就会出现乱码
        resp.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "utf-8"));
        // 获取文件下载的输入流
        FileInputStream inputStream = new FileInputStream(realPath);
        // 创建缓冲区
        int len = 0;
        byte[] buffer = new byte[1024];
        // 获取 outputStream 对象
        ServletOutputStream outputStream = resp.getOutputStream();
        // 将 FileOutputStream 流写入 buffer 缓冲区,使用 OutputStream 将缓冲区的数据输出到客户端
        while ((len = inputStream.read(buffer)) > 0) {
            outputStream.write(buffer, 0, len);
        }
        // 关闭对象
        inputStream.close();
        outputStream.close();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

这样我们就可以实现在 web 中下载图片了。

输入我们设置好的路径,就会跳转出保存图片的选项。

验证码

这次我们实现一个简单的验证码刷新功能,在后台绘制好图片上传到客户端呈现

public class ImageServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 如何让浏览器三秒刷新一次
        resp.setHeader("refresh", "3");
        // 在内存中创建一个图片
        BufferedImage bufferedImage = new BufferedImage(80, 20, BufferedImage.TYPE_INT_RGB);
        // 得到图片 -- 笔
        Graphics2D graphics = (Graphics2D) bufferedImage.getGraphics();
        // 设置图片的背景颜色
        graphics.setColor(Color.white);
        graphics.fillRect(0, 0, 80, 20);
        // 给图片写数据
        graphics.setColor(Color.BLUE);
        graphics.setFont(new Font(null, Font.BOLD, 20));
        graphics.drawString(makeNumber(), 0, 20);
        // 告诉浏览器这个请求用图片的方式打开
        resp.setContentType("image/jpeg");
        // 浏览器有缓存机制,不让浏览器缓存
        resp.setDateHeader("expires", -1);
        resp.setHeader("Cache-Control", "no-cache");
        resp.setHeader("pragma", "no-cache");
        // 把图片写给浏览器
        ImageIO.write(bufferedImage, "jpg", resp.getOutputStream());
    }

    private String makeNumber() {
        int numbers = 7;
        Random random = new Random();
        String number = random.nextInt(9999999) + "";
        StringBuffer stringBuffer = new StringBuffer();
        for (int i = 0; i < numbers - number.length(); i++) {
            stringBuffer.append("0");
        }
        number = stringBuffer.toString() + number;
        return number;
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

后续的操作和前面的都一样,我就不多做赘述了。

消息转发和重定向

现在有 a b c 三个人

消息转发就是,a 想要获取一个东西,但是那个东西在 c 那里,这是他找 b 要,然后 b 转身就去问 c 要来然后给 a

重定向则是, a 去问 b 那他想要的东西,但是 b 没有,b 告诉他 c 有,然后 a 转身去问 c 要

他们两个的区别在于消息转发不会跳转网页,重定向会跳转网页

现在我们来实现消息转发

public class ServletDispatcher extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建 ServletContext 对象
        ServletContext servletContext = this.getServletContext();
        // 进行消息转发,其中的 /hello 就是要转发的路径
        servletContext.getRequestDispatcher("/hello").forward(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

这时候我们访问这个类对应的路径就会呈现出 /hello 路径下所展示的内容

使用重定向就会跳转页面, 但是重定向需要将项目的路径写上

public class RedirectServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        resp.sendRedirect("/javaWebDemoMaven_war/hello");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

现在来写个小例子

在 webapp 中创建一个名为 login.jsp 的 jsp 文件,用来模拟登陆的界面

在表单提交的时候需要路径, 这时候我们可以用 pageContext.request.contextPath 来获取当前项目的路径

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<h1>登陆</h1>

<%--${pageContext.request.contextPath} 代表当前的项目--%>
<form action="${pageContext.request.contextPath}/tologin" method="get">
    <label>
        用户名:
        <input type="text" name="username">
    </label> <br>
    <label>
        密码:
        <input type="password" name="passwd">
    </label> <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>

然后我们来写实现类

public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        // 创建 ServletContext 对象
        ServletContext servletContext = this.getServletContext();
        // servletContext.getContextPath() 这个方法可以获取当前项目的路径
        System.out.println(servletContext.getContextPath());
        resp.sendRedirect(servletContext.getContextPath() + "/login.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
public class RequestText extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext servletContext = this.getServletContext();
        System.out.println("进入了这个请求");
        String username = req.getParameter("username");
        String passwd = req.getParameter("passwd");
        System.out.println(username + ":" + passwd);
        resp.sendRedirect(servletContext.getContextPath() + "/success.jsp");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

然后我们在 /login 中提交表单就可以跳转到另一个页面了。

session

我们还可以在 session 中存入东西,例如:

我们先要得到 session 然后再利用 session

public class SessionDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        // 得到 Session
        HttpSession session = req.getSession();

        // 在 Session 中存东西
        session.setAttribute("name", "牛马");

        // 获取 Session ID
        String sessionId = session.getId();

        // 判断 session 是不是新的
        if (session.isNew()) {
            resp.getWriter().write("session 成功创建,ID:" + sessionId);
        } else {
            resp.getWriter().write("session 已经在服务器中存在,ID:" + sessionId);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

每一个浏览器都会有一个 session 我们可以在操作 session 得到这个 session 的 ID

我们也可以在这个session 中写入东西, 然后如何得到这个 session 中我们所设置的值呢?如下:

public class SessionDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("utf-8");
        resp.setCharacterEncoding("utf-8");
        resp.setContentType("text/html;charset=utf-8");

        HttpSession session = req.getSession();
        // 取出在session 中存入的值
        String name = (String) session.getAttribute("name");

        resp.getWriter().print(name);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

除了我们存入变量外,我们还可以存入一个对象,我们先创建一个实体类

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

session.setAttribute("name", new Person("Niuma", 20));

然后和之前一样取出这个对象

Person person = (Person) session.getAttribute("name");

现在我们就可以操作这个 Person 对象了。

我们除了可以在 session 里面创建一个值,我们也可以移除一个 session 的值

public class SessionDemo3 extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();
        // 移除 session 值
        session.removeAttribute("name");
        // 注销
        session.invalidate();
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

我们也可以在 web.xml 中设置 session 的默认实效时间,时间以分钟为单位

<!--设置 session 默认的实效时间-->
<session-config>
    <!--一分钟后自动实效,以分钟为单位-->
    <session-timeout>1</session-timeout>
</session-config>

JSP

什么是 JSP

Java Server Pages: java 服务器端页面,也和 servlet 一样,用于动态 web 技术。

最大特点:

  • 写 JSP 就和写 HTML 一样

  • 区别:

    • HTML 给用户提供今天数据
    • JSP 页面中可以嵌入 java 代码,为用户提供动态数据

jsp 基础语法

任何语言都有自己的语法,java中有,jsp 作为 java 技术的一个应用,它拥有自己的扩充语法,java 的所有语法都支持。

表达式

<%--
        jsp 表达式
        作用:用来将程序输出到客户端
<%= 变量或表达式%>
        --%>
<%= new java.util.Date()%>

这样我们可以在页面中看到我们调用这个方法后的结果

除此之外我们还可以在 jsp 中写一些脚本片段

<%--脚本片段--%>
<%
    int sum = 0;
    for (int i = 1; i <= 100; i++) {
        sum += i;
    }
    out.println("<h1>sum=" + sum + "</h1>");
%>

脚本片段再实现

<%
    int x = 10;
    out.println(x);
%>
<p>这个一个 jsp 文档</p>
<%
    int y = 20;
    out.println(y);
%>

在 jsp 中嵌入 HTML 标签

<% for (int i = 0; i < 5; i++) { %>
<h1>hello, world <%=i%></h1>
<% } %>

jsp 声明

<%!
    static {
        System.out.println("loading servlet!");
    }

    private final int globalVar = 0;

    public void function() {
        System.out.println("进入了方法 function()");
    }
%>

jsp 声明:会被编译到 jsp 生成的 java 代码中,其它的就会被生成到 _jspService() 方法中!

在 jsp 嵌入 java 代码即可。

自定义错误页面

比如我们要自定义一个 404 的错误页面,我们创建一个 404.jsp 文件,

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>404错误</title>
</head>
<body>
<img src="img/404.png" alt="404">
</body>
</html>

然后在 web.xml 中设置

<error-page>
  <error-code>404</error-code>
  <location>/error/404.jsp</location>
</error-page>

这样我们在遇到 404 错误的时候就会自动跳转到这个页面了

定义头尾文件

像写 HTML 页面那样,定义头尾两个文件

头文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>I's header</h1>

尾文件

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<h1>I‘s footer</h1>

定义主体页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>

<%--将三个页面合为一个页面--%>
<%@include file="common/header.jsp"%>
<h1>I's body</h1>
<%@include file="common/footer.jsp" %>

<hr>

<%--将三个页面拼接,本质上还是三个页面--%>
<jsp:include page="common/header.jsp"/>
<h1>I's body</h1>
<jsp:include page="common/footer.jsp"/>

</body>
</html>

常用的是第二种方式

javabean

JavaBean 特有的写法

  • 必须有一个无参的构造

  • 属性必须私有化

  • 必须有对应的 get set 方法

每个 java 的实体类对应数据库中的一张表,例如:

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 + '\'' +
            '}';
  }
}
<%@ page import="com.niuma.pojo.People" %><%--
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>javabean</title>
</head>
<body>
<%
    People people = new People();
    people.setId(0);
    people.setName("牛马");
    people.setAge(20);
    people.setAddress("湖南");
%>
id = <%=people.getId()%> <br>
姓名 = <%=people.getName()%> <br>
年龄 = <%=people.getAge()%> <br>
地址 = <%=people.getAddress()%>
</body>
</html>

filter 过滤器

filter 的包必须是 javax.servlet 的包

public class FilterShow extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    resp.getWriter().write("你好,牛马!");
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
  }
}
public class CharacterEncodingFilter implements Filter {
  /**
   * 初始化,在 web 服务器启动的时候就已经初始化了,随时等待过滤对象
   */
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {
    System.out.println("CharacterEncodingFilter初始化");
  }

  /**
   * 过滤中的所有代码,在过滤特定请求的时候会执行
   * 必须要让过滤器同向执行 filterChain.doFilter(servletRequest, servletResponse);
   * @param filterChain 链
   */
  @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");
    System.out.println("CharacterEncodingFilter执行前......");
    filterChain.doFilter(servletRequest, servletResponse);
    System.out.println("CharacterEncodingFilter执行后......");
  }

  /**
   * 销毁,web 服务器在关闭的时候会自动销毁过滤器
   */
  @Override
  public void destroy() {
    System.out.println("CharacterEncodingFilter销毁");
  }
}
<servlet>
  <servlet-name>FilterShow</servlet-name>
  <servlet-class>com.niuma.test.FilterShow</servlet-class>
</servlet>
<servlet-mapping>
  <servlet-name>FilterShow</servlet-name>
  <url-pattern>/test/filter</url-pattern>
</servlet-mapping>

<filter>
  <filter-name>CharacterEncodingFilter</filter-name>
  <filter-class>com.niuma.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
  <filter-name>CharacterEncodingFilter</filter-name>
  <url-pattern>/test/filter</url-pattern>
</filter-mapping>

这样我们就可以不用重复的在类中写乱码处理了

权限拦截

登陆页面

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>登陆页面</title>
</head>
<body>
<h1>登陆</h1>
<form action="${pageContext.request.contextPath}/logintest" method="post">
    <input type="text" name="username">
    <input type="submit" name="登陆">
</form>

</body>
</html>

错误页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>错误页面</title>
</head>
<body>
<h1>错误</h1>
<h3>没有权限或者没有此用户</h3>
<a href="login1.jsp">返回到登陆页面</a>

</body>
</html>

登陆成功页面

<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
    <title>登陆成功</title>
</head>
<body>
<h1>登陆成功</h1>
<p><a href="<c:url value="/loginouttest"/>">注销</a></p>

</body>
</html>

登陆处理

public class LoginServletTest extends HttpServlet {
  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 获取前端请求的参数
    String username = req.getParameter("username");

    if ("admin".equals(username)) {
      req.getSession().setAttribute("USER_SESSION", 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);
  }
}

注销处理

public class LoginOutTest 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("login1.jsp");
  }

  @Override
  protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    doGet(req, resp);
  }
}

拦截器

public class SysFilter implements Filter {
  @Override
  public void init(FilterConfig filterConfig) throws ServletException {

  }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) servletRequest;
    HttpServletResponse response = (HttpServletResponse) servletResponse;
    if (request.getSession().getAttribute("USER_SESSION") == null) {
      response.sendRedirect("../error.jsp");
    }
    filterChain.doFilter(request, response);
  }

  @Override
  public void destroy() {

  }
}

posted on 2022-03-24 19:40  一颗蛋50斤  阅读(63)  评论(0)    收藏  举报

导航