【当前进度1.102】JAVA Web 作业

当前进度1.102 不骗你,第一个任务估计也就0.01,乐观点也最多百分之6
https://type.dayiyi.top/index.php/archives/181/
1.00了,测试版

当前共计:13997字

2023年6月20日01:10:16

2023年6月21日00:45:47

2023年6月21日11:40:24

2023年6月21日15:32:39

2023年6月22日09:35:43

2023年6月25日00:46:40、

16620个字啦

这个作业可能比想象中的复杂一点,涉及了很多的代码。而且内容几乎涉及了整个web全栈。
也正是如此,一次可能写不完,所以会不断更新。
如果你遇到了不明白的地方,请联系咱,咱会进行补充

这次打算使用实时更新的网站:【这里放链接】

更新网址:

0x00 补充和更新

目前还没有遇到,但本文章涉及内容多,不确定因素亦多,肯定会遇上问题,因此,希望各位可以进行补充和说明。 0x13 如何打开文件夹 2023年6月19日17:08:51 0x30 锟斤拷 2023年6月20日01:02:02 0x22 tomcat配置注释2023年6月20日23:40:53 1.00测试版 2023年6月22日10:48:21 1.10 进行了一些修改和维护,更清晰点啦。2023年6月24日22:35:02

0x01 文件下载

由于涉及的文件真的非常的多,我也临时没想好应该如何共享这些文件。

  • 使用之前的下载方式
  • 使用阿里云盘
  • 使用阿里云盘开网页直接下载,无需登录

后来看,文件也没那么多,于是,直接在文章末尾可以进行文件下载。

0x02 目录说明

大致如下

0x01 章节1 - 0x011 章节1.1 - 0x012 章节1.2 0x02 章节2 - 0x021 章节2.1 - 0x022 章节2.2

0x03 开发工具

因为整个课程涉及了WEB几乎全栈的开发,因此,这里使用了以下的工具

  • VSCODE
  • Chrome 浏览器
  • IDEA(关键)
  • Tomcat(8.5)
  • maven(进行包管理,非常的方便)

0x10 蛋糕商场的注册界面

该部分对应实验报告内容如下
序号实验项目完成时间
1蛋糕商城注册页面2.28

0x11 准备文件

需要准备这些文件,这些文件的压缩包在群文件中有。

群文件名:23.2.28_java_web.rar

链接下载:https://p.dabbit.net/blog/pic_bed/2023/05/a77f2e125a83aee1_202305261907278.7z

这里准备好这8个文件,4个css样式文件,4个字体文件

这两个红色的圈,是两个文件夹,您下下文件7z来就可以了。

解压后用VSC打开这个文件夹。就会有类似这样的样子。可能有所差距, 是因为主题包的问题。

image-20230526190448507

image-20230526190448507

注意目录和文件最好不要涉及到中文,尽可能只有英文、数字、下划线,其他的字符尽可能不要出现,容易出现问题,但JAVA对这个的兼容还算是可以。

当前还不需要注意这个,但是之后的java代码的书写,可能会出现一些不可预料的错误,因此很建议遵循全英文数字,非中文的规则。

0x12 开发工具

用什么开发工具都是可以的,我们这里的任务1就只写一个html文件,但对于大型项目来说,选择一个合适的IDE是非常有必要的,可以提高非常高的开发效率。

注意VScode不是VS,VSCode是开源的,VS是商业软件。

本章节(0x012)在于提高开发效率,如果你比较急,可以进行一定的忽略。

我这里用了VSCODE,为了提高兼容性,你也可以遵循这个原则。

注意,在本次的报告中,VSCODE由于需要手动配置的内容较多,仅在前两章的原理和简单前端开发中使用了。

使用的插件包括:

Debugger for Chrome(可选,你可以直接浏览器打开你的页面) Code Runner(可选,我们的前端可以直接用浏览器打开) JavaScript Debugger(可选,我们这次作业没有用到很多的JS) IntelliSense for CSS class names in HTML (不一定好用) TabNine (完全可选,AI代码补全,如果配置好还是挺好用) Live Server(可选,实时预览) Live Preview(可选) 为什么这么多可选,因为这里是已经写完一遍报告的dayi,2023年6月24日21:04:11。 语言包(也是插件): Chinese (Simplified) (简体中文) Language Pack for Visual Studio Code 主题(也是插件): Material Theme Icons

如果,你想要参考的相关链接:VSCode 必装的 10 个高效开发插件 - 知乎 (zhihu.com)

  • 这里是我临时(2023年5月26日19:28:59)的插件包

    image-20230526192910052

    image-20230526192910052

  • 这里是报告结束的dayi(2023年6月24日21:05:22)这篇报告写了一个月诶,其实也没必要装太多插件,装个HTML高亮和补全就可以。这么多插件也就用到一两个诶。image-20230624210631946
    image-20230624210631946

0x121 如果你想要修改vscode为绿色版,也就是携带版

无关章节啦

携带版就是所有的插件、数据文件存在当前的目录,可以塞优盘里等。

从官网:Download Visual Studio Code - Mac, Linux, Windows

下载zip版本

解压之后,在跟VSCODE.EXE同样目录下,新建文件夹data即可。

数据就会一直保存在这里啦。

0x122 更换主题

无关章节,换个主题多好看呀。

CTRL+K+T(依次按)

image-20230526192040484

image-20230526192040484

0x123 实时预览

无关章节,可选章节,因为咱们写的页面并不多,一开始我觉得要写很多页面所以写了这个地方。

image-20230526194505104

image-20230526194505104

0x13 开始写代码

0x131 user_register.html

如果你打不开下图的界面,VSCODE:左上角文件->打开文件夹(你可以新建一个,然后把css和fonts两个文件夹放进去)->然后打开这个文件夹就可以了(注意不是打开文件)
准备好文件之后,开始写代码
  1. 新建文件./project/user_register.html

    image-20230526193328549

    image-20230526193328549
    (别在意这个图,图错啦,是user_register.html,不是header.html;

    2023年6月24日21:08:37 补上图:

    image-20230624210839766

    image-20230624210839766

  2. 简单点的代码(不过建议直接看下一点(3.简单写一下代码如下 ) 的内容,注释更多)

    这里进行了一定的简单注释,如果你想要了解更多,可以自己去菜鸟教程之类的网站、书、课等去看看哦。

    <!DOCTYPE html> <html> <!-- ver1.0_easy --> <!-- 头标签 --> <head> <title>注册用户</title> <!-- 标准缩放 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 编码格式 --> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!-- 引用两个文件的css --> <link type="text/css" rel="stylesheet" href="css/bootstrap.css"> <link type="text/css" rel="stylesheet" href="css/style.css"> </head> <!-- 这里是html的内容 --> <body> <div class="container"> <div class="register"> <div class="form"> <form action="/user_register" method="post"> <div class="register-top-grid"> <h2> 新用户!</h2> <!-- 用户名 --> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>用户名 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <input type="text" name="username" placeholder="你要输入你想要的用户名!" required="required"> </div> <!-- OK,这就是第一个框 --> <!-- 然后就可以复制粘贴了 --> <!-- 邮箱 --> <div class="input"> <span>邮箱 <font color="red">*</font> </span> <input type="text" name="email" placeholder="你要输入你想要的邮箱!" required="required"> </div> <!-- 密码 --> <div class="input"> <span>密码 <font color="red">*</font> </span> <!-- 密码是password会自动隐藏 --> <input type="password" name="password" placeholder="你要输入你想要的密码!" required="required"> </div> <!-- 收货人 --> <div class="input"> <span>收货人 </span> <!-- 收货人不是必须的,所以可以不用required --> <input type="text" name="name" placeholder="你要输入你想要的收货人!"> </div> <!-- 电话 --> <div class="input"> <span>收货人电话</span> <input type="text" name="phone" placeholder="你要输入你想要的收货人电话!"> </div> <!-- 地址 --> <div class="input"> <span>收货人地址</span> <input type="text" name="address" placeholder="你要输入你想要的收货人地址!"> </div> <!-- 然后我们加个按钮 --> <!-- class就用他的啦 --> <div class="register-but text-center"> <input type="submit" value="提交"> <div class="clearfix"> </div> </div> </div> </form> </div> </div> </div> <!-- OK,这样表单就写完了 --> </body> </html>

    效果如下,其实也能看

    image-20230526210429547

    image-20230526210429547

  3. 简单写一下代码如下(好吧好吧,如果第一次看这个东东,估计也不是很简单)

    这个代码的话,我尽可能解释一点,更多的内容还是自己去学一学。

    <!DOCTYPE html> <html> <!-- ver1.0 --> <!-- 头标签 --> <head> <title>注册用户</title> <!-- 标准缩放 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 编码格式 --> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!-- 引用两个文件的css --> <link type="text/css" rel="stylesheet" href="css/bootstrap.css"> <link type="text/css" rel="stylesheet" href="css/style.css"> </head> <!-- 这里是html的内容 --> <body> <!-- 如果你有实时插件,ctrl+s可以实时预览 --> <!-- 先写个头 --> <!-- 因为头不是重点,所以你可以不写 --> <!-- 定义header块 --> <div class="header"> <!-- 在定义个容器块 --> <!-- 这里的块你就可以理解为c语言的花括号,可以无限叠,可以让代码更清晰 --> <!-- 但是div的实际上是可以被css样式定义的。 --> <div class="container"> <nav class="navbar navbar-default" > <div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/index" >这里是头</a></li> <li><a href="/index2" >这里也是头</a></li> <li><a href="#" >热销</a></li> <li><a href="#" >新品</a></li> <li><a href="#" class="active">注册</a></li> <li><a href="#" >登录</a></li> </ul> </div> </nav> </div> </div> <!-- 这种/div是结束,类似于{}的} --> <!-- 然后写一个注册填充表 --> <!-- 如果你有实时插件,ctrl+s可以实时预览 --> <!-- 实际上这些div会导致css样式的套娃顺序 --> <div class="container"> <div class="register"> <!-- 写一个表单,因为我们注册实际上是发送表单到服务器 --> <div class="form"> <!-- 开始写表单 --> <!-- 这个表单会通过POST的方式直接发送给服务器路径为:user_register的文件 --> <form action="/user_register" method="post"> <!-- --> <!-- 这个div的作用实际上是将这个框居中,引用了class="register-top-grid"的css样式,具体的样式你可以去看看源文件 --> <!-- 这样,我们的表单就可以居中了 --> <div class="register-top-grid"> <h2> 新用户!</h2> <!-- 然后就是造表单了 --> <!-- 这里为了好看引用了css为input的样式 --> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>用户名 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <input type="text" name="username" placeholder="你要输入你想要的用户名!" required="required"> </div> <!-- OK,这就是第一个框 --> <!-- 然后就可以复制粘贴了 --> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>邮箱 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <input type="text" name="email" placeholder="你要输入你想要的邮箱!" required="required"> </div> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>密码 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <!-- 密码是password会自动隐藏 --> <input type="password" name="password" placeholder="你要输入你想要的密码!" required="required"> </div> <!-- 后面的框为了排版,我省一点注释 --> <div class="input"> <span>收货人 </span> <!-- 收货人不是必须的,所以可以不用required --> <input type="text" name="name" placeholder="你要输入你想要的收货人!"> </div> <div class="input"> <span>收货人电话</span> <input type="text" name="phone" placeholder="你要输入你想要的收货人电话!"> </div> <div class="input"> <span>收货人地址</span> <input type="text" name="address" placeholder="你要输入你想要的收货人地址!"> </div> <!-- clearfix 是一种CSS 技巧,可以在不添加新的html 标签的前提下,解决让父元素包含浮动的子元素的问题。 --> <!-- 清除之前的浮动关系,修复在firefox、chrome等标准浏览器中子元素全部浮动时,父元素不自动增高的问题。 --> <!-- 我也是第一次用 --> <div class="clearfix"> </div> <!-- 然后我们加个按钮 --> <!-- class就用他的啦 --> <div class="register-but text-center"> <input type="submit" value="提交"> <div class="clearfix"> </div> </div> </div> </form> </div> </div> </div> <!-- OK,这样表单就写完了 --> <!-- 这个东西叫做footer,也就是你平时看到页面最下面的东西 --> <!--footer--> <div class="footer"> <div class="container"> <div class="text-center"> <p>这里是底哦,你可以写你想要的内容,比如(C)dayi</p> <!-- br是换行的意思,不需要加</br> --> <br> <h3>你也可以让字体大一点</h3> </div> </div> </div> <!--//footer--> </body> </html>
  4. 效果图如下:

    image-20230526204321586

    image-20230526204321586

  5. 稍微把头修改一下

    也就是<div class="header">的部分

    <div class="header"> <!-- 在定义个容器块 --> <!-- 这里的块你就可以理解为c语言的花括号,可以无限叠,可以让代码更清晰 --> <!-- 但是div的实际上是可以被css样式定义的。 --> <div class="container"> <nav class="navbar navbar-default"> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/index">主页</a></li> <li><a href="/index2">其他页面</a></li> <li><a href="#">热销</a></li> <li><a href="#">新品</a></li> <li><a href="#" class="active">注册</a></li> <li><a href="#">登录</a></li> </ul> </div> </nav> <!-- 新的内容 --> <div class="header-info"> <div class="header-right search-box"> <a href="javascript:;"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></a> <div class="search"> <form class="navbar-form" action="/goods_search"> <input type="text" class="form-control" name="keyword"> <button type="submit" class="btn btn-default" aria-label="Left Align">搜索</button> </form> </div> </div> <div class="header-right cart"> <a href="goods_cart.jsp"> <span class="glyphicon glyphicon-shopping-cart " aria-hidden="true"> <span class="card_num"></span> </span> </a> </div> <div class="clearfix"> </div> </div> </div> <!-- 新的内容 --> </div> </div>

    image-20230526205143717

    image-20230526205143717

  6. 把header和footer分出来,新建为两个文件,方便后序其他文件的使用
  • header.html

    image-20230526205316873

    image-20230526205316873

    <div class="header"> <!-- 在定义个容器块 --> <!-- 这里的块你就可以理解为c语言的花括号,可以无限叠,可以让代码更清晰 --> <!-- 但是div的实际上是可以被css样式定义的。 --> <div class="container"> <nav class="navbar navbar-default"> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/index">主页</a></li> <li><a href="/index2">其他页面</a></li> <li><a href="#">热销</a></li> <li><a href="#">新品</a></li> <li><a href="#" class="active">注册</a></li> <li><a href="#">登录</a></li> </ul> </div> </nav> <!-- 新的内容 --> <div class="header-info"> <div class="header-right search-box"> <a href="javascript:;"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></a> <div class="search"> <form class="navbar-form" action="/goods_search"> <input type="text" class="form-control" name="keyword"> <button type="submit" class="btn btn-default" aria-label="Left Align">搜索</button> </form> </div> </div> <div class="header-right cart"> <a href="goods_cart.jsp"> <span class="glyphicon glyphicon-shopping-cart " aria-hidden="true"> <span class="card_num"></span> </span> </a> </div> <div class="clearfix"> </div> </div> </div> <!-- 新的内容 --> </div> </div>
  • footer.html

    image-20230526205400257

    image-20230526205400257

    <!-- 这个东西叫做footer,也就是你平时看到页面最下面的东西 --> <!--footer--> <div class="footer"> <div class="container"> <div class="text-center"> <p>这里是底哦,你可以写你想要的内容,比如(C)dayi</p> <!-- br是换行的意思,不需要加</br> --> <br> <h3>你也可以让字体大一点</h3> </div> </div> </div> <!--//footer-->

到此,任务一完成,然而,这之前暴雨前的黎明(

0x14 点击提交会发生什么?

科普章节,你不需要写。

点击之后会发生这样的事情:

浏览器会发送这些数据到后端

image-20230526203803271

image-20230526203803271

image-20230526203826005

image-20230526203826005

也就是这些内容会POST到服务器

username=123&email=213&password=213123123&name=123124&phone=123658&address=23190

0x20 配置tomcat

唔写不动了

0x21 准备文件

0x22 尝试直接启动

从这里开始,是开始非常麻烦的了。

你如果想要启动成功,你必须有

  • JAVA(推荐JDK1.8,文章末尾可以下载,解压不要放到带有中文的目录里哦,甚至尽可能的放在标准目录:C:\Program Files\Java\jdk1.8.0_361
  • JAVA_HOME 环境变量
  • JRE_HOME 环境变量(可能需要)

如果你已经有了这些,恭喜你,你可以尝试自己启动一下。大概率是一次性成功的。

如果你没有这些,你需要先去看0x23,然后结合0x23再看这一个章节。


开始尝试直接启动。

如果你之前没配过java,几乎几乎不可能一次成功。

需要先配置环境变量,一般不太可能一次成功哦

具体请看0x23的JAVA home

打不开的话,跳转到0x23

打开这个文件夹:

就是TOMCAT的目录下的bin。

apache-tomcat-8.5.50\bin\

0x221 尝试直接启动

点击startup.bat

如果你的是小黑窗口一闪而过,那就需要配置环境变量啦。

image-20230526212103884

image-20230526212103884

0x222 报错分析

如果跟上面的图片一样,恭喜你,你没有报错。
1. shift+右键,选择在此打开cmd/powershell/终端 2. 输入cmd 3. 输入startup.bat

一般会提示JAVA_HOME找不到,这个时候,你只需要去0x23去修改下JAVA_HOME即可。

0x223尝试打开网页

打开: http://localhost:8080

image-20230526212140590

image-20230526212140590

出现了,恭喜你,你省去了很多事情,并且简单的成功了

0x23 报错

上一步成功了,本章节可以忽略
  • 我没有JAVA,那就下载JAVA

    http://java.com

    Java Downloads | Oracle 中国

    建议安装两个版本:

    • 1.8 JDK(后安装)
    • 1.17 JDK(先安装)
    • 文章末尾也有JDK1.8的下载。如果你需要的话,但我建议你使用安装版。
  • Java Home没有找到

    这一步很关键,之后的很多地方都需要这个环境变量。

    【此电脑】->【属性】->【高级系统设置】->【环境变量】->【新建】->【JAVA_HOME】注意大小写->【把你java的路径填上】,一般在这个位置:

    C:\Program Files\Java

    填写:JAVA_HOME

    填写你的目录 比如:C:\Program Files\Java\jdk1.8.0_361

    什么?你没有JDK?

image-20230526212524787

image-20230526212524787

image-20230526213040311

image-20230526213040311

  • 端口被占用

    修改文件:

    apache-tomcat-8.5.50\conf\server.xml

    修改为其他的端口

    image-20230526213259596

    image-20230526213259596

    但我建议你搜索端口号占用进程,并且杀掉他

    netstat -aon | findstr 8080 tasklist | findstr + 进程号 taskkill /f /im 进程名.exe

    image-20230526213635573

    image-20230526213635573

0x241 在IntelliJ IDEA中配置Tomcat+maven

需要TOMCAT启动成功,乱码可以配置好,之后修改的话跳转到0x25解决。

启动成功之后最简单的方法,打开这个0x24的文件,在0xFF章节可以下载。

如果你在本步骤失败:

可以直接跳转到0x30,有项目搭建的详细过程,但你同时可以参考本章节的视频。

后面还是用了IDEA)

本章节临时废弃了,因为没配出来。用vscode有成功的配置。

2023年6月20日23:42:04现在配出来了

配置过程大概如下:

直接录了个视频,你可以可以自己另存为,具体的详细可以参考0x30章节的内容。

组ID类似于包名。

中文的话:下载插件即可。

注意哦,pom.xml 加入这两行哦

<dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency>

记得加完之后点右上角的蓝色的 小M,同步下依赖。

0x242 在VSCODE里配置Tomcat

写完的dayi:这里还保留这个章节的原因是,因为,如果你这样配置之后,你会对整个过程更加了解哦。
  1. 下载插件Community Server Connectors
  2. 右下角可能会报错,如果提示当前JAVA版本不够,需要更高版本:添加rsp-ui.rsp.java.home,到你的高版本JDK目录,注意\\\的区别

    image-20230530090023607

    image-20230530090023607

  3. 右键,Create Server,提示是否需要下载,你可以用本地的,也可以下载一个,差不多。我这里选择用本地的。

    image-20230530090327809

    image-20230530090327809

  4. 如果你选下载,是否同意都同意即可。

    image-20230530090417920

    image-20230530090417920

  5. 导入本地tomcat:

    • 打开tomcat文件夹目录
    • 选择
    • 我直接选的finish
    • 然后右键TOMCAT,启动服务器。
    • 访问127.0.0.1:8080,发现是可以打开的
    • 文件放在:apache-tomcat-8.5.50\webapps\rabbit\index.jsp(新建文件)

      <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <title>index</title> </head> <body> <h1>hello world</h1> <!-- jsp输出1024*1024的结果 --> <% out.println(1024 * 1024); %> </body> </html>
    • 访问http://127.0.0.1:8080/rabbit/,可以看到网页,表示成功了。

      image-20230530093118633

      image-20230530093118633

    • 如果需要修改JSP的运行目录:

      修改这里就可以啦

      image-20230530093611653

      image-20230530093611653

    image-20230530090711842

    image-20230530090711842

    image-20230530090756683

    image-20230530090756683

    image-20230530090840708

    image-20230530090840708

image-20230530091149182

image-20230530091149182

image-20230530092849740

image-20230530092849740

image-20230530093507074

image-20230530093507074

0x25 Tomcat 日志乱码

  • 看到一堆锟斤拷了吗
  • 进行修一修。

0x251 方法1,修改为GBK编码输出(推荐)

  • 修改文件:apache-tomcat-8.5.50\conf\logging.properties

    修改为GBK编码

image-20230530094425568

image-20230530094425568

0x252 方法2,修改启动参数(没有成功)

好像不生效。我觉得这样改也不对。

就不要这样改了。

这个方法就参考一下,图个乐。

可能是在Linux下,不过我觉得这样改也怪怪的 ,本来好像就是UTF-8,但是cmd编码是GBK。因此会出现锟斤拷。

  • 在Tomcat文件夹目录中,/bin/catalina.bat里面修改,添加set JAVA_OPTS= -Dfile.encoding=UTF-8

    111 |setlocal 112 |set JAVA_OPTS= -Dfile.encoding=UTF-8 113 |rem Suppress Terminate batch job on CTRL+C 添加112行

    image-20230530094830489

    image-20230530094830489

0x26 VSC-Tomcat部署项目

参考过程,用IDEA会快一点,但如果你这样配置之后,你会对MVN(maven)有更深的了解。

很麻烦对吧,这就是学计算机

0x261 插件安装

Extension Pack for Java Maven for Java Debugger for Java
0x2611 安装maven
我之前好像编译过java项目,所以我没这个步骤,但是如果你没配过,还是要配一次。
  1. 下载maven,并解压

    官网下载:Maven – Download Apache Maven https://maven.apache.org/download.cgi

    大一的文件:https://pic.icee.top/blog/pic_bed/apache-maven-3.8.6-d72781d0-058e-4571-b28f-23b818f04d73.rar

  2. 进入到设置里,修改配置参数:

    image-20230530111558871

    image-20230530111558871

    这里可能需要复制的内容:

    @ext:vscjava.vscode-maven
  3. 然后在Path里填写:

    这里的路径你不可以直接复制

    你要把D:\program_\apache-maven-3.8.6-bin\这些改成你maven文件的路径地址。

    D:\program_\apache-maven-3.8.6-bin\apache-maven-3.8.6\bin\mvn.cmd

0x262 新建项目

  • 右键文件列表目录,新建项目
    image-20230530104551844
    image-20230530104551844
  • 选择【webapp】->选择【1.4】->填写包名【com.example.testdayi】-> 选择你要存放的文件夹(最好路径全英文)

    什么是包名,一般就是网址域名的反过来写就可以。

    image-20230530104659041

    image-20230530104659041

image-20230530104627519

image-20230530104627519

0x263 项目修改

  • 修改下文件,以便后面的测试
  • 文件:demo\src\main\webapp\index.jsp

    image-20230530105931680

    image-20230530105931680

  • 内容如下:

    <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> <!DOCTYPE html> <html> <head> <title>index</title> </head> <body> <h1>hello world</h1> <!-- jsp输出1024*1024的结果 --> <% out.println(1024 * 1024); out.println("你好"); %> </body> </html>
  • 进行编译和部署

    点击这里的package

    image-20230530111124656

    image-20230530111124656

    如果出现SUCCESS ,并且demo里面出现文件,则构建(BUILD)成功。

    image-20230530111245287

    image-20230530111245287

    这个目录有demo,index.jsp,WEB-INF META-INF几个文件即可。

0x264 部署项目

0x265 如果需要修改

要在src文件夹里修改哦,虽然你该target目录下的也可以生效,但是这样不对。

  • 文件:demo\src\main\webapp\index.jsp
  • 修改完之后进行再打包。package即可。

image-20230530113708196

image-20230530113708196

0x30 解决中文乱码

看似简单,实际是写一个servlet

【本章节弃用】,但是舍不得删掉)

0x31 使用VSC

本章节弃用,但是建议手动试试装包过程,和包编译和maven进行维护。

请跳转到0x32

0x311 添加依赖包

搜索:

Servlet api

image-20230606082002045

image-20230606082002045

选择Tomcat的也就是,搜索完之后:

选择

org.apache.tomcat

这样的包,然后会自动提示在pom.xml里更新文件,保存即可。

image-20230606082247591

image-20230606082247591

CTRL+S保存文件就可以啦。

然后会提示是否同步依赖,同步就可以。

image-20230606082353372

image-20230606082353372

0x32 下载IDEA

这个可以省时间,就用这个了。
  • 有人连bing都懒得用,这里下载:https://www.jetbrains.com/zh-cn/idea/,点击Download。
  • 我下的是 Ultimate,激活用数据库群里的一个我传的压缩包,或者用学校邮箱认证正版,这里链接就不放了。
  • 下载之后安装,一直下一步就可以。
  • 然后 随便打开一个不带中文目录的空文件夹
  • 左上角,File->Setting->Plugins
  • 搜索 chinese
  • 选择第二个插件,点击Install
  • 等一会就是中文了,可能需要重启。

image-20230619235742314

image-20230619235742314

0x33 在IDEA创建项目

IDEA的下载您可以去官网下,激活您可以用edu.cn邮箱验证或者数据库群里的之前发的小工具。

这里我用的不是 社区版。

经过之前的步骤,你可能对这个java有了一定的了解

  • 包,几乎是域名的反写。如果你的域名是pigs.dabbit.net 一般写作:net.dabbit.pigs
  • 包,你要自己改为你自己名字哦,你可以看我这篇文章的图片,几乎都是p.dabbit.net下面的,这是咱滴域名就直接用啦。
  • 记得反写哦,bing.com,就是com.bing.xxxx
  • 目录结构

    ├─src(源代码) │ └─main(main) │ ├─java(这里放java相关的东西) │ │ └─net │ │ └─dabbit │ │ └─servlet2 (这是一个包名,叫net.dabbit.servlet2,分为了3个文件夹) | | └─YourClass.java (你的类放这里) │ ├─resources (资源) │ └─webapp (web的相关,jsp的位置) │ └─WEB-INF └─target (生成的目标文件)
  • maven是一个包管理器,帮助解决各种冲突,并且维护包的信息

而这些很多的基础步骤并不需要我们来解决,我们要注重于代码的内容。

于是:

我们使用一些IDE来帮我们简化过程。

为什么这里改用IDEA

DEA确实方便一点,而且能加快开发。

这里是写完初稿的dayi:2023年6月24日21:31:04,IDEA,不是很想承认,但是确实挺好用。

0x331 建立项目

  • 文件,新建项目,如图所示
  • 名称随意,但是建议不要出现任何中文
  • 位置,不建议出现中文
  • JDK建议选择1.8,可以自动下载
  • 选择webapp框架
  • 高级设置填默认,但这里可以填一下包名,具体的可以参考0x241的视频。
  • 这个过程在0x241下有参考视频

    image-20230620002837904

    image-20230620002837904

然后大概这个样子:
image-20230620002921394

image-20230620002921394

0x332 测试编译

点一下

image-20230620003233932

image-20230620003233932

如果出现success就可以啦

image-20230620003308730

image-20230620003308730

0x333 添加servlet依赖

在pom.xml里添加,如果你跳转到0x241还会有另外一个之后会用到的依赖哦(JSTL)

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

image-20230620003434176

image-20230620003434176

加完之后点这里哦

image-20230624213257889

image-20230624213257889

如果你需要全部的xml文件

不可以直接替换,会出现问题,得手动或者用GPT帮你替换。

<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.dabbit.javaweb</groupId> <artifactId>our_homework2</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>our_homework2 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>4.0.1</version> <scope>provided</scope> </dependency> </dependencies> <build> <finalName>our_homework2</finalName> </build> </project>
  • 保存后重新右上角构建,如果成功即可。

0x334 添加包

0x335 随便建个servlet

记得不要复制太多。否则容易出问题。

package net.dabbit.javaweb.servlet; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "Hello",urlPatterns = "/Hello") public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { String data="Hello"; PrintWriter out = response.getWriter(); out.println(data); } }

image-20230620004423086

image-20230620004423086

0x336 如果你发现一堆红色的提示,记得更新MVN

别尝试下,1.9G的仓库,下半辈子。

如果你跟我一样一堆红色的,记得更新下包,别别别,别更新包,1.9G的包索引,够你的。

这里点击加载更改就行(蓝色的图标)如果还是不行,重启下IDEA应该就行了。。

感觉这些文字在打架,dayi1:确实,dayi2:确实

image-20230620004820389

image-20230620004820389

image-20230624213716435

image-20230624213716435

下面这段别管了。dayi:2 这是dayi1干的蠢事。

image-20230620004606458

image-20230620004606458

image-20230620004650761

image-20230620004650761

0x337 配置TOMCAT

  • 编辑配置。

image-20230620004927330

image-20230620004927330

0x338 启动Tomcat

  • 点击绿色的

image-20230620005414289

image-20230620005414289

  • 这样就是对的了

image-20230620005454094

image-20230620005454094

0x339 访问页面

我这里写的是

http://localhost:8081/our_homework2_war_exploded/Hello 就是自动打开的网页,再加个/Hello

image-20230620005527136

image-20230620005527136

打开的文件如图,正确的。

如果,你这里失败了,那样可能需要做一些不少的工作来成功,下面的步骤都是基于TOMCAT的,得把TOMCAT配置好。

0x34 解决中文乱码

0x341 尝试直接用中文

  • 修改
  • 重新部署

image-20230620005725629

image-20230620005725629

0x342 发现乱码

image-20230620005807946

image-20230620005807946

0x343 锟斤拷原理

待补充
  • GBK 以 UTF-8 方式打开
  • UTF-8 以 GBK方式打开

由于两个编码格式不一样,开头内容字节不一样,开头字节长度不一样。导致直接以另外一种格式读出,出现锟斤拷

反之则会出现???等问题

该过程不可逆。一旦发生,不能还原原先内容,必须重新以二进制的形式读取

0x344 强制UTF-8编码

加入

response.setContentType("text/html;charset=utf-8");

使得内容变为

//直接复制可能会出现问题哦 package net.dabbit.javaweb.servlet; import javax.servlet.*; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.io.PrintWriter; @WebServlet(name = "Hello",urlPatterns = "/Hello") public class TestServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException { response.setContentType("text/html;charset=utf-8"); String data="Hello 我是可爱的橙子。"; PrintWriter out = response.getWriter(); out.println(data); } }

image-20230620010049773

image-20230620010049773

  • 重新编译(重新部署)

0x345 解决锟斤拷

image-20230620010228815

image-20230620010228815

0x35 问题解决,文件下载

睡觉啦。2023年6月20日01:02:51

  • 0x35_our_homework2.zip

https://p.dabbit.net/blog/pic_bed/2023/06/9c76394a5a75ad2b_202306200107974.zip

0x40 实现购物车

代码注释有点少,应该自己仔细看看就看得懂,大篇其实都是JAVA的类的相关。

有时间的话就补充注释。

0x41 新建包

小提示:ALT+左键 、ALT + 左键 可以一次多点好几行哦,然后一起修改内容。

小提示2:ALT+ENTER可以修复代码的很多错误哦。

总共三个包,这里是我的命名,你完全可以不按照这个命名。

  • net.dabbit.configs 这个是配置文件,记录URL的对应关系
  • net.dabbit.entity 实体类,你感觉像实体的都是实体
  • net.dabbit.servlet2 这个包是servlet
  • 为什么这样做,因为dabbit.net是咱的域名。
  • 你完全可以修改成你自己的,或者你自定义点。

image-20230620233004151

image-20230620233004151

你可以也参考这个:

那些CAKE什么的都是java的类哦。

image-20230624213412212

image-20230624213412212

0x42 新建实体

如果你需要目录结构

PS D:\_project\javaweb_\java1\java3_jsp\src> tree /F 文件夹 PATH 列表 卷序列号为 09DC-E6C6 D:. └─main ├─java │ └─net │ └─dabbit │ ├─beans │ │ Book.java │ │ CakeBean.java │ │ DBUtil.java │ │ RegisterFormBean.java │ │ Student.java │ │ User.java │ │ UserBean.java │ │ │ ├─configs │ │ CharactorEncoding.java │ │ Config.java │ │ │ ├─entity │ │ Cake.java │ │ CakeCart.java │ │ CakeDB.java │ │ │ └─servlet2 │ CartServlet.java │ ChineseSet.java │ ControllerServlet.java │ LastAccessServlet.java │ ListCakeServlet.java │ LoginServlet.java │ PurchaseServlet.java │ ├─resources └─webapp │ footer.html │ footer.jsp ...

蛋糕

net.dabbit.entity.Cake

package net.dabbit.entity; public class Cake { //这个是我们的实体,中的蛋糕。 //不是后室的实体。 private static final long serialVersionUID = 1L; private String id; private String name; public Cake() { } public Cake(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public String getName() { return name; } }

购物车

net.dabbit.entity.CakeCart

package net.dabbit.entity; import java.util.ArrayList; import java.util.List; //购物车 // car vs cart //cart is A cart is just a vehicle with 4 wheels. Like a shopping cart, or a horse cart. public class CakeCart { public List<Cake> cart; public CakeCart() { cart = new ArrayList<Cake>(); } public List<Cake> get_cart() { return cart; } public void add_cake(Cake x) { cart.add(x); } }

蛋糕数据库

net.dabbit.entity.CakeDB

package net.dabbit.entity; import java.util.Collection; import java.util.LinkedHashMap; import java.util.Map; public class CakeDB { private static Map<String, Cake> cake = new LinkedHashMap<String, Cake>(); static { cake.put("1", new Cake("1", "A类蛋糕 巧克力")); cake.put("2", new Cake("2", "B类蛋糕 猴子味")); cake.put("3", new Cake("3", "C类蛋糕 章魚味")); cake.put("4", new Cake("4", "D类蛋糕 鴨子味")); cake.put("5", new Cake("5", "E类蛋糕 奶牛味")); cake.put("6", new Cake("6", "F类蛋糕 孙橙子味")); } // 获得所有的蛋糕 public static Collection<Cake> getAll() { return cake.values(); } // 根据指定的id获蛋糕 public static Cake getCake(String id) { return cake.get(id); } }

再次说一下,这个net.dabbit 是 dabbit.net 的反写,是咱的域名。

0x43 配置文件类,其实必要性不是很大,但是对于大项目管理肯定是必不可少

net.dabbit.configs.Config

package net.dabbit.configs; import java.util.LinkedHashMap; import java.util.Map; //维护 URL 的实际URL的对应关系。 //配置文件,方便对URL进行统一维护。 public class Config { private static Map<String,String> URLList = new LinkedHashMap<String, String>(); public static String LIST_CAKE_URL = "ListCakeServlet"; public static String LIST_THE_CAKE = LIST_CAKE_URL; public static String CART_OF_CAKE = "CartServlet"; public static String BUY_THE_CAKE = "PurchaseServlet"; static { URLList.put("LIST_CAKE_URL" ,LIST_CAKE_URL); URLList.put("LIST_THE_CAKE" ,LIST_CAKE_URL); URLList.put("CART_OF_CAKE" ,CART_OF_CAKE); URLList.put("BUY_THE_CAKE",BUY_THE_CAKE); } public String getId(String s){ return URLList.get(s); } }

0x44 servlet

0x441 列出蛋糕ListCakeServlet

package net.dabbit.servlet2; import net.dabbit.entity.Cake; import net.dabbit.entity.CakeDB; import net.dabbit.configs.Config; 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 javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; import java.util.Collection; //这里是注册URL,相当于在web.xml里写的。 //从4.0之后,这个过程可以自动完成。 @WebServlet(name = "ListCakeServlet",urlPatterns = "/ListCakeServlet") public class ListCakeServlet extends HttpServlet { private static final long serialVersionUID = 1L; public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8");//URL设置 PrintWriter out = resp.getWriter(); // 输出流 Collection<Cake> cakes = CakeDB.getAll(); // 获得所有的蛋糕 out.write("给您提供的蛋糕有:<br>"); Config cfg = new Config(); //这里只列出当前的蛋糕数量,如果不经过购买,直接去显示购物车的话会导致没有session信息。防止没有session信息,这里直接新建一个。 HttpSession http_session = req.getSession(); for (Cake cake : cakes) { String url = cfg.getId("BUY_THE_CAKE")+"?id=" + cake.getId(); out.write(cake.getName() + "<a href='" + url + "'>点击购买</a><br>"); } String url = cfg.CART_OF_CAKE; out.write("<br>查看我的购物车:" + "<a href='./" + url + "'>查看我的购物车</a><br>"); } }

0x442 购买请求PurchaseServlet

package net.dabbit.servlet2; import net.dabbit.entity.Cake; //蛋糕 import net.dabbit.entity.CakeCart; import net.dabbit.entity.CakeDB; // 蛋糕数据库 import net.dabbit.configs.Config; //配置信息 import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.*; import java.io.IOException; import java.util.List; @WebServlet(name = "PurchaseServlet",urlPatterns="/PurchaseServlet") public class PurchaseServlet extends HttpServlet { public static String LIST_CAKE_URL = "ListCakeServlet";//蛋糕列表选项 URL public static String CART_OF_CAKE = "CartServlet";//购物车跳转URL private static final long serialVersionUID = 1L; public void init() throws ServletException {//初始化函数 LIST_CAKE_URL = new Config().getId("LIST_CAKE_URL"); //获得蛋糕列表的跳转URL CART_OF_CAKE = new Config().getId("CART_OF_CAKE"); } public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String id = req.getParameter("id");//获得ID if(id==null){ //如果ID不存在,则跳转到蛋糕列表 resp.sendRedirect(LIST_CAKE_URL); return; } HttpSession session = req.getSession();//获得当前的session,如果不存在的话就自动创建一个新的。//准确说,这里应该是新建一个session CakeCart shop_car; //新建个车子在超市里跑 shop_car = new CakeCart(); if(session.getAttribute("shopping_cart")!=null){//如果session里存着数据,就读出来。 shop_car = (CakeCart) session.getAttribute("shopping_cart"); //获得session里的数据 } session.setAttribute("shopping_cart",shop_car);//设置shopping cart到session里 Cake cake = CakeDB.getCake(id);//获得要购买的蛋糕ID shop_car.add_cake(cake);//在购物车里添加cake Cookie cookie = new Cookie("JSESSIONID",session.getId()); cookie.setMaxAge(60*60*24*30); //30天 cookie.setPath("./"); resp.addCookie(cookie);//设置cookie resp.sendRedirect(CART_OF_CAKE);//跳转到购物车 } }

0x443 购物车CartServlet

package net.dabbit.servlet2; import net.dabbit.configs.Config; import net.dabbit.entity.Cake; import net.dabbit.entity.CakeCart; 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 javax.servlet.http.HttpSession; import java.io.IOException; import java.io.PrintWriter; import java.util.List; @WebServlet(name = "CartServlet",urlPatterns="/CartServlet") public class CartServlet extends HttpServlet { public void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { resp.setContentType("text/html;charset=utf-8"); //chi修复 PrintWriter out = resp.getWriter(); //获得输出流 CakeCart cart = new CakeCart();//新建购物车 HttpSession session = req.getSession(false); if(session==null){ out.println("没有找到session信息,您可能没有访问过网站,也没有购买过蛋糕,是不是呀大黑阔<br>"); return; } cart = (CakeCart) session.getAttribute("shopping_cart");//获得cart属性 if(cart==null){ out.println("您购物车好像是空哒嘎嘎嘎<br>"); return; } out.println("OK,这是您购物车里的吃的:<br>"); //枚举购物车里的吃的 for (Cake c:cart.get_cart()) out.println(c.getName() + "<br>"); //打印购买列表的表。 Config cfg = new Config(); String url = cfg.getId("LIST_CAKE_URL"); out.write("<br>返回购买列表:" + "<a href='./" + url + "'>返回购买列表</a><br>"); } }

0x445 实现效果

访问:

你要访问你自己的界面呀,ListCakeServlet是你自己的相对呀。

比如你默认的在:http://localhost:8082/java1_war_exploded/

那就这样打开

http://localhost:8082/java1_war_exploded/ListCakeServlet

image-20230620233808578

image-20230620233808578

0x4F 文件下载

请跳转到0xFF中的0x554
dayi2:很遗憾,做的时候压缩错文件夹了,过程文件丢失了一点。

但是最后的文件是有哒。

0x50 建立蛋糕商城界面

0x51 JSP原理

req -> [JSP->JAVA->CLASS->Servlet] -> res(一般是HTML) 请求 -> JSP容器 -> 请求返回 CLASS常驻内存 每次请求新建一个JSP容器线程
  • 当JSP修改的时候会根据配置文件来判断是否重新编译。
  • 当资源不足时,可能会调用jspDestroy(),来尝试摧毁容器。
  • 检查修改:如果JSP的文件修改日期比生成的servlet早,那就重新编译。
  • 执行顺序

    public void jspInit(){} void _jspService(HttpServletRequest request, HttpServletResponse response){} public void jspDestroy(){ // 清理代码 }
  • 来试试,hello.jsp如下
<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 8:40 To change this template use File | Settings | File Templates. --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <html> <head> <title>life.jsp</title> </head> <body> <%! private int cnt_init=0; private int cnt_serv=0; private int cnt_destory=0; %> <%! public void jspInit(){ cnt_init++; System.out.println("jspInit(): JSP被初始化了"+cnt_init+"次"); } public void jspDestroy(){ cnt_destory++; System.out.println("jspDestroy(): JSP被销毁了"+cnt_destory+"次"); } %> <% cnt_serv++; System.out.println("_jspService(): JSP共响应了"+cnt_serv+"次请求"); String content1="初始化次数 : "+ cnt_init; String content2="响应客户请求次数 : "+cnt_serv; String content3="销毁次数 : "+cnt_destory; %> <h1>JSP</h1> <p><%=content1 %></p> <p><%=content2 %></p> <p><%=content3 %></p> <%--来自菜鸟教程--%> </body> </html>

image-20230620142130350

image-20230620142130350

0x52 JSP语法

语法描述
<%-- 注释 --%>JSP注释,注释内容不会被发送至浏览器甚至不会被编译
<!-- 注释 -->HTML注释,通过浏览器查看网页源代码时可以看见注释内容
<%代表静态 <%常量
%>代表静态 %> 常量
\'在属性中使用的单引号
\"在属性中使用的双引号
<%=content3 %>这种就是输出变量了
“<%!”和“%>”是用来定义属性和方法的,“<%”和“%>”主要是用来输出内容的

0x53 简单的JSP页面

0x531 时间显示

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 9:07 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.util.Date" %> <%@ page import="java.text.SimpleDateFormat" %> <html> <head> <title>Time</title> </head> <body> <% Date dt = new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String today =df.format(dt); %> 当前时间:<%=today%> </body> </html>

image-20230620110408249

image-20230620110408249

0x532 显示1+1和动态注释时间

显示1+1和动态注释时间

image-20230620113952425

image-20230620113952425

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 11:05 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="java.util.Date" %> <html> <head> <title>Title</title> </head> <body> <% int a = 5; int b = 10; out.println(a + b); %> <%--动态注释--%> <!-- 这是一跳注释,但是注释的时间是:<%=new Date()%> --> </body> </html>

0x533 引用其他文件

  • 引用其他文件

    <%@ include file="time.jsp"%>

image-20230620114828476

image-20230620114828476

0x534 买个大点的硬盘

618有活动,980PRO 479,跟送一样(我1700买的,哭死)

image-20230620140833610

image-20230620140833610

0x535 JSP转发

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 14:20 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> forward: <jsp:forward page="hello.jsp" /> </body> </html>

image-20230620142215641

image-20230620142215641

0x536 错误页面

新建一个make-error.jsp,来制造一个错误

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 16:00 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" pageEncoding="UTF-8" errorPage="error.jsp"%> <%--这里写错误页面是error.jsp,如果报错了就去那个地方--%> <html> <head> <title>Title</title> </head> <body> <% int a = 1; int b = 0; out.println(a/b);//除0,产生错误。 %> </body> </html>

新建一个error.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 15:43 To change this template use File | Settings | File Templates. --%> <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isErrorPage="true"%> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>error page</title> </head> <body> 这里是错误信息!OVO:<br> <!-- 显示异常信息 --> <%=exception.getMessage()%><br /> </body> </html>

image-20230620161816692

image-20230620161816692

0x54 页面转发到用户界面

0x541 我把之前的文件扔到了jsp-examles文件夹

image-20230620162320919

image-20230620162320919

0x542 实现

本任务要求使用<jsp:forward>请求转发动作元素将页面转发到用户登录页面。

超级简单啦,先上效果图

http://localhost:8082/java1_war_exploded/user_forward/forward.jsp

image-20230620230123503

image-20230620230123503

两个文件代码如下:

forward.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 22:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>跳转页</title> </head> <body> <jsp:forward page="login.jsp"></jsp:forward> </body> </html>

login.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 22:43 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Login</title> </head> <body> <h1>你好呀,这里是登录界面。</h1> <form name="form1" method="post" action=""> <label for="name">用户名:</label> <input name="name" type="text" id="name" style="width: 200px"><br><br> <label for="pwd">密码:</label> <input name="pwd" type="password" id="pwd" style="width: 200px"><br><br> <input type="submit" name="Submit" value="提交"> </form> </body> </html>

到目前为止,文件可以在文章末尾下载

0x55 实现蛋糕商城

0x551 复制文件

记得留备份哦

image-20230620230809041

image-20230620230809041

我把之前咱们的文件复制到项目这里了。

0x552 新建页眉页脚JSP

其实只要复制过来就可以啦

image-20230620231106387

image-20230620231106387

header.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 23:09 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <div class="header"> <!-- 在定义个容器块 --> <!-- 这里的块你就可以理解为c语言的花括号,可以无限叠,可以让代码更清晰 --> <!-- 但是div的实际上是可以被css样式定义的。 --> <div class="container"> <nav class="navbar navbar-default"> <div class="collapse navbar-collapse"> <ul class="nav navbar-nav"> <li><a href="/index">主页</a></li> <li><a href="/index2">其他页面</a></li> <li><a href="#">热销</a></li> <li><a href="#">新品</a></li> <li><a href="#" class="active">注册</a></li> <li><a href="#">登录</a></li> </ul> </div> </nav> <!-- 新的内容 --> <div class="header-info"> <div class="header-right search-box"> <a href="javascript:;"><span class="glyphicon glyphicon-search" aria-hidden="true"></span></a> <div class="search"> <form class="navbar-form" action="/goods_search"> <input type="text" class="form-control" name="keyword"> <button type="submit" class="btn btn-default" aria-label="Left Align">搜索</button> </form> </div> </div> <div class="header-right cart"> <a href="goods_cart.jsp"> <span class="glyphicon glyphicon-shopping-cart " aria-hidden="true"> <span class="card_num"></span> </span> </a> </div> <div class="clearfix"> </div> </div> </div> <!-- 新的内容 --> </div> </div>

footer.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 23:10 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!-- 这个东西叫做footer,也就是你平时看到页面最下面的东西 --> <!--footer--> <div class="footer"> <div class="container"> <div class="text-center"> <p>这里是底哦,你可以写你想要的内容,比如(C)dayi</p> <!-- br是换行的意思,不需要加</br> --> <br> <h3>你也可以让字体大一点</h3> </div> </div> </div> <!--//footer-->

0x553 新建文件user_register.jsp

image-20230620232158846

image-20230620232158846

全部的代码如下:

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 23:18 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <!DOCTYPE html> <html> <!-- ver1.0 --> <!-- 头标签 --> <head> <title>注册用户</title> <!-- 标准缩放 --> <meta name="viewport" content="width=device-width, initial-scale=1"> <!-- 编码格式 --> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <!-- 引用两个文件的css --> <link type="text/css" rel="stylesheet" href="css/bootstrap.css"> <link type="text/css" rel="stylesheet" href="css/style.css"> </head> <!-- 这里是html的内容 --> <body> <!-- 如果你有实时插件,ctrl+s可以实时预览 --> <!-- 先写个头 --> <!-- 因为头不是重点,所以你可以不写 --> <!-- 定义header块 --> <div> <jsp:include page="header.jsp"></jsp:include> </div> <!-- 这种/div是结束,类似于{}中的'}'--> <!-- 然后写一个注册填充表 --> <!-- 如果你有实时插件,ctrl+s可以实时预览 --> <!-- 实际上这些div会导致css样式的套娃顺序 --> <div class="container"> <div class="register"> <!-- 写一个表单,因为我们注册实际上是发送表单到服务器 --> <div class="form"> <!-- 开始写表单 --> <!-- 这个表单会通过POST的方式直接发送给服务器路径为:user_register的文件 --> <form action="/user_register" method="post"> <!-- --> <!-- 这个div的作用实际上是将这个框居中,引用了class="register-top-grid"的css样式,具体的样式你可以去看看源文件 --> <!-- 这样,我们的表单就可以居中了 --> <div class="register-top-grid"> <h2> 新用户!</h2> <!-- 然后就是造表单了 --> <!-- 这里为了好看引用了css为input的样式 --> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>用户名 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <input type="text" name="username" placeholder="你要输入你想要的用户名!" required="required"> </div> <!-- OK,这就是第一个框 --> <!-- 然后就可以复制粘贴了 --> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>邮箱 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <input type="text" name="email" placeholder="你要输入你想要的邮箱!" required="required"> </div> <div class="input"> <!-- span的意思是提示和注释的意思 --> <!-- <font color="red">*</font>,变成红色的* --> <span>密码 <font color="red">*</font> </span> <!-- 输入框 --> <!-- 这个name很重要,会传递到后端 --> <!-- 密码是password会自动隐藏 --> <input type="password" name="password" placeholder="你要输入你想要的密码!" required="required"> </div> <!-- 后面的框为了排版,我省一点注释 --> <div class="input"> <span>收货人 </span> <!-- 收货人不是必须的,所以可以不用required --> <input type="text" name="name" placeholder="你要输入你想要的收货人!"> </div> <div class="input"> <span>收货人电话</span> <input type="text" name="phone" placeholder="你要输入你想要的收货人电话!"> </div> <div class="input"> <span>收货人地址</span> <input type="text" name="address" placeholder="你要输入你想要的收货人地址!"> </div> <!-- clearfix 是一种CSS 技巧,可以在不添加新的html 标签的前提下,解决让父元素包含浮动的子元素的问题。 --> <!-- 清除之前的浮动关系,修复在firefox、chrome等标准浏览器中子元素全部浮动时,父元素不自动增高的问题。 --> <!-- 我也是第一次用 --> <div class="clearfix"> </div> <!-- 然后我们加个按钮 --> <!-- class就用他的啦 --> <div class="register-but text-center"> <input type="submit" value="提交"> <div class="clearfix"> </div> </div> </div> </form> </div> </div> </div> <!-- OK,这样表单就写完了 --> <!-- 这个东西叫做footer,也就是你平时看到页面最下面的东西 --> <!--footer--> <div> <jsp:include page="footer.jsp"></jsp:include> </div> <!--//footer--> </body> </html>

0x554 有头有尾就算成功啦

image-20230620232240062

image-20230620232240062

0x60 根据参数请求显示不同页面

### 0x61 EL 表达式

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/20 Time: 23:51 To change this template use File | Settings | File Templates. --%> <%@ page language="java" contentType="text/html; charset=utf-8" %> <%--如果没这行,可能不会解析EL哦--%> <%@ page isELIgnored="false" %> <%--如果没这行,可能不会解析EL哦--%> <html> <head></head> <body> 1+1 = ${1+1} <br/> 请求URI为:${pageContext.request.requestURI} <br/> Content-Type响应头:${pageContext.response.contentType} <br/> 服务器信息为:${pageContext.servletContext.serverInfo} <br/> Servlet注册名为:${pageContext.servletConfig.servletName} <br/> </body> </html>

image-20230621001603371

image-20230621001603371

0x62 JSTL

0x621 加依赖

在pom.xml里添加

<dependencies> ==开始 <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> ==结束 </dependencies>

image-20230621002359526

image-20230621002359526

0x622 JSTL jsp文件

jstl.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 0:19 To change this template use File | Settings | File Templates. --%> <%@ page language="java" contentType="text/html; charset=utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head></head> <body> <c:out value="Hello World!"></c:out> </body> </html>

URL:http://localhost:8082/java1_war_exploded/el/jstl.jsp

你的不一定是哦。

image-20230621002609427

image-20230621002609427

0x623 JSTL escapexml

escapeXml 设置为true可以不解析xml

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 0:28 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> </head> <body> <%--页面跳转--%> <c:out value="${null}" escapeXml="false"> <meta http-equiv="refresh" content="0;url=http://www.dayi.ink" /> </c:out> </body> </html> <%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 9:23 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> </head> <body> <c:out value="${null}" escapeXml="false"> 使用的表达式结果为null,则输出该默认值 <meta http-equiv="refresh" content="0;url=http://www.dayi.ink /> </c:out> <br/> </body> </html>

设置为

escapeXml="true"> 这样就不会自动跳转了,而是直接输出。

比如这样

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 9:23 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> </head> <body> <c:out value="${null}" escapeXml="true"> 使用的表达式结果为null,则输出该默认值 <meta http-equiv="refresh" content="0;url=http://www.dayi.ink /> </c:out> <br/> </body> </html>

image-20230621093031725

image-20230621093031725

0x624 JSTL foreach

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 0:36 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ page import="java.util.List" %> <%@ page import="java.util.ArrayList" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> <html> <head> <title>Title</title> </head> <body> <% List colorsList=new ArrayList(); colorsList.add("red"); colorsList.add("yellow"); colorsList.add("blue"); %> <c:forEach var="color" items="<%=colorsList%>" begin="0" end="3" step="1"> ${color}<br> </c:forEach> </body> </html>

image-20230621004024727

image-20230621004024727

0x63 根据参数请求显示不同的页面

​ 通过JSTL标签库中的<c:if>标签可以根据不同的条件去处理不同的业务。本任务要求应用<c:if>标签实现根据参数请求显示不同页面的功能。具体要求如下。

​ 当请求参数为“mon”时,页面显示“周一了,工作的第一天”;当请求参数为“tues”时,页面显示“周二了,工作的第二天”;当请求参数为“wed”时,页面显示“周三了,工作的第三天”;当请求参数为“thu”时,页面显示“周四了,工作的第四天”;当请求参数为“fri”时,页面显示“周五了,工作的第五天”;当请求参数为“sat”时,页面显示“周六了,休息的第一天”;当请求参数为“sun”时,页面显示“周日了,休息的第二天”。

2023年6月21日00:45:27

睡觉啦。

如果之前的你有看,这里就超简单啦。

效果如下:

image-20230621092141265

image-20230621092141265

image-20230621092158016

image-20230621092158016

代码如下index.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 8:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <title>每周计划</title> </head> <body> <% String dayOfWeek = request.getParameter("day"); if (dayOfWeek == null) { dayOfWeek = ""; } request.setAttribute("dayOfWeek", dayOfWeek); // Store the value as a request attribute %> 传入的参数为:<c:out value="${dayOfWeek}"></c:out><br> <c:if test="${dayOfWeek == 'mon'}">周一了,工作的第1天</c:if> <c:if test="${dayOfWeek == 'tues'}">周二了,工作的2天</c:if> <c:if test="${dayOfWeek == 'wed'}">周三了,工作的3天</c:if> <c:if test="${dayOfWeek == 'thu'}">周四了,工作的第4天</c:if> <c:if test="${dayOfWeek == 'fri'}">周五了,工作的第5天</c:if> <c:if test="${dayOfWeek == 'sat'}">周六了,休息的第1天</c:if> <c:if test="${dayOfWeek == 'sun'}">周日了,休息的第2天</c:if> <c:if test="${dayOfWeek == ''}">请求参数不存在,请输入参数。</c:if> <c:if test="${!dayOfWeek.matches('mon|tues|wed|thu|fri|sat|sun')}">OPPOS, 你输入的不对哦</c:if> </body> </html> </body> </html>

0x70 按照model2实现注册功能

0x701 JAVA Bean

JavaBean通常具有如下特点:

  • 提供一个默认的无参构造函数。
  • 需要被序列化并且实现了 Serializable 接口。
  • 可能有一系列可读写属性,并且一般是 private 的。
  • 可能有一系列的 getter 或 setter 方法。

0x702 还记的这个CAKE吗

文件位置:\java3_jsp\src\main\java\net\dabbit\entity\Cake.java

package net.dabbit.entity; public class Cake { //这个是我们的实体,中的蛋糕。 //不是后室的实体。 private static final long serialVersionUID = 1L; private String id; private String name; public Cake() { } public Cake(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public String getName() { return name; } }

把它变成 JAVA Bean

大概就会是这个样子

package net.dabbit.beans; import java.io.Serializable; public class CakeBean implements Serializable { private static final long serialVersionUID = 1L; //new private String id; private String name; public CakeBean() {//构造函数 } public CakeBean(String id, String name) { this.id = id; this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }

因为原先就差不多啦,所以看起来差距不大。

但是这里引用了序列化的接口,注意下哦。

image-20230621101552175

image-20230621101552175

0x71 新建User的Bean

package net.dabbit.beans.User

package net.dabbit.beans; import java.io.Serializable; public class User implements Serializable { private static final long serialVersionUID = 1L; //序列化UID private String username; // 用户名 private String password; // 密码 public User() { } public User(String username, String password) { this.username = username; this.password = password; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }

image-20230621102300524

image-20230621102300524

0x72 登录两个界面-初

index.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 10:23 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Login</title> </head> <body> <form action="result.jsp" method="post"> <table align="center" width="300" border="1" height="150"> <tr> <td colspan="2" align="center"><b>登录页面</b></td> </tr> <tr> <td align="right">用户名:<input type="text" name="username"></input></td> </tr> <tr> <td align="right">密码:<input type="text" name="password"></input></td> </tr> <tr> <td colspan="2" align="center"><input type="submit"/></td> </tr> </table> </form> </body> </html>

result.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 10:25 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="net.dabbit.beans.User" %> <html> <head> <title>Result</title> </head> <body> <% String username = request.getParameter("username");//获得用户名 String password = request.getParameter("password");//获得密码 if (username != null && password != null) { //如果直接GET可能会导致报错哦 //核心开始 User user = new User(username, password);//新建用户 if (user.getUsername().equals("dayi") && user.getPassword().equals("123456")) {//判断用户名密码 out.print("恭喜您,登录成功!"); } else { out.print("请输入正确的用户名和密码!"); } //核心结束 } else { out.print("请通过正确的方式访问该页面!"); } %> <br/><br/> <a href="index.jsp">返回</a> </body> </html>

效果:

image-20230621103453203

image-20230621103453203

0x73 Student 信息页面

0x731 Student Bean类

package net.dabbit.beans; import java.io.Serializable; public class Student implements Serializable { private String name; private int age; private String sex; 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 getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } }

0x732 孙橙子的个人信息

StudentInfo.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="net.dabbit.beans.Student" %> <html> <head> <title>孙橙子</title> </head> <body> <jsp:useBean id="student" class="net.dabbit.beans.Student" /> <jsp:setProperty name="student" property="name" value="孙橙子" /> <jsp:setProperty name="student" property="age" value="1024" /> <jsp:setProperty name="student" property="sex" value="橙子" /> <div> <ul> <li>姓名:<jsp:getProperty name="student" property="name" /></li> <li>年龄:<jsp:getProperty name="student" property="age" /></li> <li>性别:<jsp:getProperty name="student" property="sex" /></li> </ul> </div> </body> </html>

image-20230621104945356

image-20230621104945356

0x74 BOOK信息填写

net.dabbit.beans.Book

package net.dabbit.beans; import java.io.Serializable; public class Book implements Serializable { private String bookName; private double price; private String author; public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } }

index.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 11:31 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> </head> <body> <form action="info.jsp" method="post"> <table align="center" width="400" height="200" border="1"> <tr> <td align="center" colspan="2" height="40"><b>添加图书信息</b></td> </tr> <tr> <td align="center">名称:<input type="text" name="bookName"></td> </tr> <tr> <td align="center">价格:<input type="text" name="price"></td> </tr> <tr> <td align="center">作者:<input type="text" name="author"></td> </tr> <tr> <td align="center" colspan="2"><input type="submit" value="添加"></td> </tr> </table> </form> </body> </html>

info.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 11:31 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page import="net.dabbit.beans.Book" %> <html> <head> <title>Title</title> </head> <body> <% request.setCharacterEncoding("UTF-8"); %> <jsp:useBean id="book" class="net.dabbit.beans.Book" scope="page" /> <jsp:setProperty name="book" property="*" /> <table align="center" width="400"> <tr> <td align="center">名称:<jsp:getProperty property="bookName" name="book" /></td> </tr> <tr> <td align="center">价格:<jsp:getProperty property="price" name="book" /></td> </tr> <tr> <td align="center">作者:<jsp:getProperty property="author" name="book" /></td> </tr> </table> </body> </html>

0x75 Model1 和 Model2

0x751 Model1

image-20230621144003969

image-20230621144003969

0x752 Model2

image-20230621144454723

image-20230621144454723

MVC = 模型(Model) 视图(VIEW) 控制器(controller)

image-20230621145752804

image-20230621145752804

0x76 按照JSP Model2思想实现用户注册功能

0x761 任务描述

要求按照JSP Model2模型思想编写一个用户注册程序。

实现用户注册需要创建两个JSP页面,注册页面register.jsp和注册成功提示信息页面loginSuccess.jsp;一个负责处理用户注册的请求的Servlet类ControllerServlet;两个JavaBean类,封装注册表单信息的JavaBean类RegisterFormBean和封装用户信息的JavaBean类UserBean;一个访问模拟数据库的辅助类DBUtil。

(1)UserBean是封装用户信息的JavaBean,ControllerServlet根据用户注册信息创建出一个UserBean对象,并将UserBean对象添加到DBUtil对象中,loginSuccess.jsp页面从UserBean对象中提取用户信息进行显示。

(2)RegisterFormBean是封装注册表单信息的JavaBean,用于校验从ControllerServlet中获取到的注册表单信息中的各个属性(也就是注册表单内的各个字段中所填写的数据)。

(3)DBUtil是用于访问数据库的辅助类,它相当于一个DAO(数据访问对象)。DBUtil类中封装了一个HashMap对象,用于模拟数据库,HashMap对象中的每一个元素即为一个UserBean对象。

(4)ControllerServlet是控制器,它负责处理用户注册的请求,如果注册成功,就会跳到loginSuccess.jsp页面,如果注册失败,重新跳回到register.jsp页面并显示错误信息。

(5)register.jsp是显示用户注册表单的页面,它将注册请求提交给ControllerServlet处理。

(6)loginSuccess.jsp是用户登录成功后进入的页面,新注册成功的用户自动完成登录,直接进入loginSuccess.jsp页面。

相对之前的还是稍微比较复杂点。

0x762 先写Bean

0x7621 UserBean

public class UserBean { private String name; // 定义用户名 private String password; // 定义密码 private String email; // 定义邮箱 public UserBean() { } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }

0x7622 RegisterFormBean

package net.dabbit.beans; import java.util.HashMap; import java.util.Map; public class RegisterFormBean { private String name; // 定义用户名 private String password; // 定义密码 private String confirmPassword; // 定义确认密码 private String email; // 定义邮箱 private Map<String, String> errors = new HashMap<String, String>(); // 错误信息 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getConfirmPassword() { return confirmPassword; } public void setConfirmPassword(String confirmPassword) { this.confirmPassword = confirmPassword; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public Map<String, String> getErrors() { return errors; } public void setErrors(Map<String, String> errors) { this.errors = errors; } public boolean validate() { boolean isValid = true; if (name == null || name.trim().equals("")) { errors.put("name", "请输入姓名."); isValid = false; } if (password == null || password.trim().equals("")) { errors.put("password", "请输入密码."); isValid = false; } if (confirmPassword == null || confirmPassword.trim().equals("")) { errors.put("confirmPassword", "请输入确认密码."); isValid = false; } else if (!confirmPassword.equals(password)) { errors.put("confirmPassword", "确认密码与密码不一致."); isValid = false; } if (email == null || email.trim().equals("")) { errors.put("email", "请输入邮箱."); isValid = false; } else if (!email.matches("[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+")) { errors.put("email", "邮箱格式错误."); isValid = false; } return isValid; } }

0x7623 DBUtil

package net.dabbit.beans; import java.util.HashMap; public class DBUtil { private static DBUtil instance = new DBUtil(); private HashMap<String, UserBean> users = new HashMap<String, UserBean>(); private DBUtil() { // 向数据库(users)中存入两条数据 UserBean user1 = new UserBean(); user1.setName("Jack"); user1.setPassword("12345678"); user1.setEmail("jack@jack.org"); users.put("Jack", user1); UserBean user2 = new UserBean(); user2.setName("Rose"); user2.setPassword("abcdefg"); user2.setEmail("rose@rose.org"); users.put("Rose", user2); } public static DBUtil getInstance() {//其实就是把类传回去 return instance; } // 获取数据库(users)中的数据 public UserBean getUser(String userName) { return users.get(userName); } // 向数据库(users)插入数据 public boolean insertUser(UserBean user) { if (user == null) { return false; } String userName = user.getName(); if (users.containsKey(userName)) { return false; } users.put(userName, user); return true; } }

尝试编译下,通过了就行

image-20230621152225430

image-20230621152225430

0x763 Servlet

ControllerServlet

package net.dabbit.servlet2; import net.dabbit.beans.DBUtil; import net.dabbit.beans.RegisterFormBean; import net.dabbit.beans.UserBean; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.*; import javax.servlet.*; import java.io.IOException; @WebServlet(name = "ControllerServlet",urlPatterns = "/ControllerServlet") public class ControllerServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("Content-type", "text/html;charset=UTF-8"); response.setCharacterEncoding("UTF-8"); // 获取用户注册时表单提交的参数信息 String name = request.getParameter("name"); String password = request.getParameter("password"); String confirmPassword = request.getParameter("password2"); String email = request.getParameter("email"); // 将获取的参数封装到注册表单相关的RegisterFormBean类中 RegisterFormBean registerForm = new RegisterFormBean(); registerForm.setName(name); registerForm.setPassword(password); registerForm.setConfirmPassword(confirmPassword); registerForm.setEmail(email); // 验证参数填写是否符合要求 if (!registerForm.validate()) { request.setAttribute("registerForm", registerForm); request.getRequestDispatcher("register.jsp").forward(request, response); return; } // 参数填写符合要求,将数据封装到UserBean类中 UserBean userBean = new UserBean(); userBean.setName(name); userBean.setPassword(password); userBean.setEmail(email); // 向数据库插入数据 DBUtil.getInstance().insertUser(userBean); // 注册成功,将UserBean对象添加到session中 HttpSession session = request.getSession(); session.setAttribute("userBean", userBean); response.getWriter().print("恭喜你("+userBean.getName()+")注册成功,3秒钟自动跳转"); response.setHeader("refresh","3;url=loginSuccess.jsp"); // 重定向到loginSuccess.jsp页面 //response.sendRedirect("loginSuccess.jsp"); } }

0x764 JSP文件

register.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 16:04 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <title>注册</title> </head> <body> <form action="ControllerServlet" method="post"> <h3>用户注册</h3> <div id="outer"> <div> <div class="ch">姓名:</div> <div class="ip"> <input type="text" name="name" value="${registerForm.name}" /> <span>${registerForm.errors.name}</span> </div> </div> <div> <div class="ch">密码:</div> <div class="ip"> <input type="password" name="password" /> <span>${registerForm.errors.password}</span> </div> </div> <div> <div class="ch">确认密码:</div> <div class="ip"> <input type="password" name="password2" /> <span>${registerForm.errors.password2}</span> </div> </div> <div> <div class="ch">邮箱:</div> <div class="ip"> <input type="text" name="email" value="${registerForm.email}" /> <span>${registerForm.errors.email}</span> </div> </div> <div id="bt"> <input type="reset" value="重置" /> <input type="submit" value="注册" /> </div> </div> </form> </body> </html>

loginSuccess.jsp

<%-- Created by IntelliJ IDEA. User: dayi Date: 2023/6/21 Time: 16:20 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@ page isELIgnored="false" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <html> <head> <title>Title</title> </head> <body> <div id="main"> <div id="welcome">恭喜你,登录成功</div> <hr /> <div>您的信息</div> <div> <ul> <li>您的姓名:${userBean.name}</li> <li>您的邮箱:${userBean.email}</li> </ul> </div> </div> </body> </html>

0x765 中文用户名乱码

  • 这样写会导致中文乱码

  • 新建个类
  • 导入这些内容

    net.dabbit.configs.CharactorEncoding

    package net.dabbit.configs; import java.io.UnsupportedEncodingException; public class CharactorEncoding { public CharactorEncoding() { } public String toString(String str) { String text= ""; if (str!=null&&!"".equals(str)){ try{ text = new String(str.getBytes("ISO-8859-1"),"UTF-8"); }catch (UnsupportedEncodingException e){ } } return text; } }
  • 然后加入这两行就可以啦

    import net.dabbit.configs.CharactorEncoding; CharactorEncoding conv = new CharactorEncoding(); name = conv.toString(name);

    image-20230621172626263

    image-20230621172626263

  • 效果如下

0x77 乌拉

估计这样就算是完成了,其实也没有那么难啦。

写的也比较仓促,有很多地方写的不是很完善,需要补充,不管你在哪里卡住了,请直接叫咱。

如果你真的明白了这些内容,期末作业也超级好写啦。

0xFF 文件下载

吐了,过程文件丢失了一些

JAVA这个目录管理真的有毒

这些文件是过程中保存的,做到哪个章节保存到哪。

如果你发现文件下载失败,请直接重新下载即可。

这里是虚假的文件,(压缩错目录位置了,我就说文件hash怎么都一样)(要命,快哭了

都是一样的)

为啥不删,(舍不得删

好嘞,这样就算是完成了7个作业啦。

最后修改:2023 年 06 月 25 日
如果觉得我的文章对你有用,请随意赞赏