Java实验四 JavaWeb编程

实验四      Java Web编程(选做)

一.实验目的

    1.掌握Java Web服务器Tomcat的安装、配置。

    2.学会简单的HTML表单设计,表单提交。

    3.掌握JSP中的request对象、session对象的使用。

二.实验内容

    1.下载安装Tomcat8,对其进行配置。启动Tomcat服务器,在浏览器输入 http://127.0.0.1:8080/,查看浏览器输出界面;

2. 定制配置:

(1)修改Tomcat的服务端口为88(默认安装为8080);

(2)修改HTTP GET方式的字符编码为UTF-8(默认为ISO-8859-1);

3.编写一个用户注册模块,功能如下:

(1)设计用户注册表单页面register.jsp,包含:用户名(文本框)、密码(密码框)、性别(下拉框);

(2)设计用户注册数据保存页面doRegister.jsp,用以保存用户数据至user.txt文件。

user.txt中每行保存一个用户,格式为:“用户名,密码,性别”;

(3)如果user.txt已包含同名的用户,提示用户已存在;否则提示注册成功。

4.编写用户登录模块,功能如下:

(1)设计用户登录表单页面login.jsp,包含:用户名(文本框)、密码(密码框);

(2)设计登录验证文件doLogin.jsp,获取客户端提交的用户名、密码,然后从user.txt中验证是否存在该用户,登录密码是否正确;

(3)将登录验证结果反馈给用户。

三.思考题

    1. 对整个实验进行总结,写出实验心得;

    2. 学有余力的同学,将实验中注册、登录功能的数据源user.txt换成数据库的user表(自行设计字段),采用JDBC访问数据库;

实验四终于来到了JavaWeb喽,本次实验我们不使用txt文件来存储信息,而是使用JDBC目前市场上最流行的框架MyBatis来操作数据库。后端的话我们也就不用springboot框架了,因为题目要求我们显式地使用JSP和Servlet来完成,springboot集成了很多东西为我们省了不少事情,让我们不需要显式的添加Servlet依赖,但是非框架地使用Servlet、JSP也没有完全被现在的企业所淘汰。

我们来回顾一下JavaWeb的三层架构。表现层、服务层和持久层。

代码架构

不过在那之前首先来看一下我们本次实验的代码架构

由于业务需求比较简单,只要完成登录和注册两个功能即可。代码架构也算是比较标准的JavaWeb三层架构的格式。

准备环境

这是一个WebMaven项目我们要创建Webapp包,再使用pom.xml配置文件进行依赖的配置。

我的依赖配置如下,JDK版本1.8。导入的Maven坐标就是下面几个,通过运行Maven下载jar包

以及Tomcat的插件。环境准备完成。

<?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.yuyu</groupId>
    <artifactId>welcome</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>war</packaging>

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.5</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.28</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>

        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
            </plugin>
        </plugins>
    </build>


</project>

配置文件

mybatis-config.xml

这个配置文件用于JDBC连接数据库。

UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.yuyu.mapper.UserMapper">

</mapper>

DAO层

先从最底部说起,持久层(DAO层)是用来与数据库进行交互的,体现在代码架构也就是Mapper包,其中会定义一些接口,比如当前业务逻辑下的UserMapper接口。在这个接口中主要实现具体的数据库增删改查操作,实现具体的数据库增删改查其实有两种方式,一种是在UserMapper接口中,这种是注解型。另一种是在配置文件UserMapper.xml中进行,这时需要一个标准命名空间然后用对应的标签进行SQL语句的书写。由于业务逻辑中只涉及到三个SQL语句,我使用的是注解型,接口代码如下:

com.yuyu.mapper.UserMapper.java:

package com.yuyu.mapper;

import com.yuyu.pojo.user;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;

public interface UserMapper {

    @Select("SELECT * from tb_user where username = #{username} and password = #{password}")
    user select(@Param("username") String username, @Param("password") String password);

    @Select("SELECT * from tb_user where username = #{username}")
    user selectuser(@Param("username") String username);
    //insert into table_name values (value1,value2,value3,...);
    @Insert("insert into tb_user values (#{username},#{password},#{gender})")
    void adduserr(@Param("username")String username,@Param("password")String password,@Param("gender")String gender);
}

可以看到三个SQL语句被封装到三个函数中,分别是

1.select函数根据用户名和密码进行查询。对应登录校验。

2.selectuser函数只根据用户名进行查询。对应注册校验。

3.adduserr函数插入一条数据,字段为用户名、密码、性别。对应注册成功。

业务层

JavaWeb第二层是业务层,体现在代码架构中的service包,这一层的核心职责是与DAO层和表现层进行交互,主要是调用DAO层中具体的增删改查操作以及被表现层所调用。

代码如下:

com.yuyu.service.UserService.java

package com.yuyu.service;

import com.yuyu.mapper.UserMapper;
import com.yuyu.pojo.user;
import com.yuyu.util.SqlSessionFactoryUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import javax.swing.*;

public class UserService {
    SqlSessionFactory factory = SqlSessionFactoryUtils.getSqlSessionFactory();
    public user login(String username, String password){
        SqlSession sqlSession = factory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        user user = userMapper.select(username,password);
        sqlSession.close();
        return user;
    }

    public user register(String username){
        SqlSession sqlSession = factory.openSession();
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        user user = userMapper.selectuser(username);
        sqlSession.close();
        return user;
    }

    public void adduser(String username,String password,String gender){
        SqlSession sqlSession = factory.openSession(true);//true需要提交事务
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.adduserr(username,password,gender);
        sqlSession.close();
    }
}

这里就是在业务层中调用DAO层中的SQL语句,值得注意的是成员属性factory是执行utIl包下的SqlSessionFactoryUtils.java中的getSqlSessionFactory()方法得到的

代码如下:

com.yuyu.util.SqlSessionFactoryUtils.java

package com.yuyu.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

public class SqlSessionFactoryUtils {

    private static SqlSessionFactory sqlSessionFactory;
    static {
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    public static SqlSessionFactory getSqlSessionFactory(){
        return sqlSessionFactory;
    }
}

在静态代码块中只执行一次的SqlSessionFactory被get方法返回,用于在业务层中获取sqlsession初始化usermapper,从而调用DAO层中的SQL语句,避免了SqlSessionFactory被重复创建造成不必要的资源消耗。

表现层

表现层主要是靠Servlet和JSP来实现,由于我们使用JDBC来操作所以不需要登录\注册校验的JSP了,我们只需要准备两个页面的JSP文件和Servlet文件就可以。

首先来看看界面UI:

登录页面CSS:

        *{
            padding: 0;
            margin: 0;
            text-decoration: none;
        }
        body{
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            background-color: #a29bfe;
            background-image: url('../images/background.png');
            background-size: cover;
        }
        .Login{
            width: 550px;
            height: 400px;
            display: flex;
            border-radius: 15px;
            justify-content: center;
            align-items: center;
            background: linear-gradient(
                to right bottom,
                rgba(255,255,255,.7),
                rgba(255,255,255,.5),
                rgba(255,255,255,.4)
            );
            /* 使背景模糊化 */
            backdrop-filter: blur(10px);
            box-shadow: 0 0 20px #a29bfe;
        }
        .table{
            font: 900 40px '';
            text-align: center;
            letter-spacing: 5px;
            color: #3d3d3d;
        }
        .box{
            overflow: hidden;
        }
        .box input{
            width: 100%;
            margin-bottom: 20px;
            outline: none;
            border: 0;
            padding: 10px;
            border-bottom: 3px solid rgb(150, 150, 240);
            background-color: transparent;
            font: 900 16px '';
        }
        .go{
            text-align: center;
            display: block;
            height: 24px;
            padding: 12px;
            font: 900 20px '';
            border-radius: 10px;
            margin-top: 20px;
            color: #fff;
            letter-spacing: 3px;
            background-image: linear-gradient(to left, #fd79a8, #a29bfe);
        }

JSP:

<%--
  Created by IntelliJ IDEA.
  User: wangyu
  Date: 2023/10/14
  Time: 19:38
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/login.css">
    <title>登入界面</title>
</head>
<body>
<div class="Login">
    <div class="box">
        <p class="table">Login</p>
        <br>
        <form action="/welcome/loginServlet" method="post" id="login-form" accept-charset="UTF-8">
            <input type="text" id="username" name="username" placeholder="用户名">
            <input type="password" id="password" name="password" placeholder="密码">
        </form>
        <br>
        <a href="#" onclick="document.getElementById('login-form').submit();" class="go">GO</a>
    </div>
</div>
</body>
</html>

其呈现的视觉效果我们启动Tomcat服务器来看一下:

接着我们结合UI来说明JSP文件,表单通过Post的方式将两个input标签(username\password)中的name属性提交到/welcome/loginServlet中,然后通过submit提交到服务器后台,这里其实还有一个很深的坑啊,表单中一定要添加accept-charset="UTF-8"属性,不然会出现乱码的啊!!!

这里也是让我Debug了很久,那么我们来看Servlet的代码:

com/yuyu/web/loginServlet.java

package com.yuyu.web;

import com.yuyu.pojo.user;
import com.yuyu.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/loginServlet")
public class loginServlet extends HttpServlet {
    private UserService userService = new UserService();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
        user user = userService.login(username,password);
        System.out.println(user);
        resp.setContentType("text/html; charset=UTF-8");
        PrintWriter out = resp.getWriter();
        if (user != null){
            out.write("登录成功");
            System.out.println("登录成功");
            req.getRequestDispatcher("/yulikeyou.jsp").forward(req,resp);
        }else {
//            req.getRequestDispatcher("/login.jsp").forward(req,resp);
            out.write("登录失败");
            System.out.println("登录失败");
        }

    }

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

处理逻辑很简单,用getParameter的方式获取传递过来的用户名密码,然后调用service层进行查询,如果返回的user非空,说明存在这个用户,就可以登录成功,如果返回的user空,说明没有这个用户,去登录吧。req.setCharacterEncoding("UTF-8");也是必须设置的,不然也会出现乱码导致登录失败!!!

接着是注册的页面:

register.css;

    *{
        padding: 0;
        margin: 0;
        text-decoration: none;
    }
    body{
        display: flex;
        justify-content: center;
        align-items: center;
        height: 100vh;
        background-color: #a29bfe;
        background-image: url(../images/background.png);
        background-size: cover;
    }
    .Login{
        width: 550px;
        height: 400px;
        display: flex;
        border-radius: 15px;
        justify-content: center;
        align-items: center;
        background: linear-gradient(
                to right bottom,
                rgba(255,255,255,.7),
                rgba(255,255,255,.5),
                rgba(255,255,255,.4)
        );
        backdrop-filter: blur(10px);
        box-shadow: 0 0 20px #a29bfe;
    }
    .table{
        font: 900 40px '';
        text-align: center;
        letter-spacing: 5px;
        color: #3e1111;
    }
    .box{
        overflow: hidden;
    }
    span{
        font-size: 16px;
        margin-left: 10px;
    }
    .box input{
        width: 100%;
        margin-bottom: 20px;
        outline: none;
        border: 0;
        padding: 10px;
        border-bottom: 3px solid rgb(150, 150, 240);
        background-color: transparent;
        font: 900 16px '';
    }
    select{
        width: 150px;
        text-align: center;
        font: 900 16px '';
        background-color: rgb(150, 150, 240);
        border-radius: 4px;
        border: 1px solid #dcdcdc;
        padding: 8px;
        font-size: 16px;
        color: #333;
    }
    .go{
        text-align: center;
        display: block;
        height: 24px;
        padding: 12px;
        font: 900 20px '';
        border-radius: 10px;
        margin-top: 20px;
        color: #fff;
        letter-spacing: 3px;
        background-image: linear-gradient(to left, #fd79a8, #a29bfe);
    }

JSP:

<%--
  Created by IntelliJ IDEA.
  User: wangyu
  Date: 2023/10/14
  Time: 20:37
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/register.css">
    <title>注册界面</title>
</head>
<body>
<div class="Login">
    <div class="box">
        <p class="table">Register</p>
        <br>
        <form action="/welcome/registerServlet" id="register-form" method="post" accept-charset="UTF-8">
            <input type="text"  id="username" name="username" placeholder="用户名">
            <input type="password" id="password" name="password" placeholder="密码">
            <span>性别:</span>
            <select id="gender" name="gender">
                <option>男</option>
                <option>女</option>
            </select>
        </form>
        <br>
        <a href="#" onclick="document.getElementById('register-form').submit();" class="go">GO</a>
    </div>
</div>
</body>
</html>

相同的配方熟悉的味道,登录和注册的页面逻辑几乎一致:

我们通过Tomcat服务器来查看一下UI:

然后是注册对应的Servlet的代码:

com/yuyu/web/registerServlet.java:

package com.yuyu.web;

import com.yuyu.pojo.user;
import com.yuyu.service.UserService;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet("/registerServlet")
public class registerServlet extends HttpServlet {
    private UserService userService = new UserService();
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        String gender = req.getParameter("gender");
        System.out.println(username);
        System.out.println(password);
        System.out.println(gender);
        user user = userService.register(username);
        System.out.println(user);
        resp.setContentType("text/html; charset=UTF-8");
        PrintWriter out = resp.getWriter();
        if (user != null){
            out.write("注册失败,该用户已存在");
            System.out.println("注册失败,该用户名已存在");
        }else {
            System.out.println(password);
            userService.adduser(username,password,gender);
            out.write("注册成功");
            System.out.println("注册成功");
            req.getRequestDispatcher("/login.jsp").forward(req,resp);
        }
    }

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

注册成功后会跳回login.jsp页面。

我们通过DataGrip来看一下当前数据库存储的信息:

这里已经存了6位用户了,都是我在测试时候添加的,那么我们通过注册再添加一位用户。

可以看到账号已经被添加了。再次通过登录界面就可以登录,然而如果注册时候发现用户名已被占用,就会提示:

为了节省时间我只用了write(”注册失败,该用户已存在“)写入了一段提示哈。其实应该重定向回当前页面再弹出一条提示,这样会比较好看。此外还可以通过正则表达式来进行密码校验,这些在实验中不做要求。

登录失败则是write(”登录失败“)。

登录成功是进入一个”爱你“的界面。

pojo包下的实体类user,就是封装了一下属性,写了getset方法,重写了ToString,以及这个爱你界面的CSS和JSP就无需展示了。

本次实验的重点是使用JavaWeb三层架构以及MVC思想来完成整个业务逻辑。登录注册校验是一个比较经典的JavaWeb项目,通过这个项目的学习可以加深我们对JavaWeb的理解,不过现在spring全家桶在企业市场的份额如此之大,实验题目的实现方式也许可以更换一下了。毕竟现在JSP已经被HTML+AJAX平替了。

到此四个Java实验就结束了,Java实验四对于Java实训应该是很有帮助的,我本来是准备用Vue的饿了吗框架来做表单的,但是在无意间看到这样一个精美的HTML页面改变了我的想法,就直接使用了。页面原作者:山羊的前端小屋,B站上有他的自媒体账号,是这位大神让我明白我学的CSS根本不叫CSS,原来JS还可以这样用于页面设计上。不得不说CSS其实才是前端三剑客中最难的一门语言吧,想用好它实在是太难了。那么我的分享到此也结束了,感谢!!!

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值