赞
踩
实验四 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层)是用来与数据库进行交互的,体现在代码架构也就是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其实才是前端三剑客中最难的一门语言吧,想用好它实在是太难了。那么我的分享到此也结束了,感谢!!!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。