【当前进度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

注意目录和文件最好不要涉及到中文,尽可能只有英文、数字、下划线,其他的字符尽可能不要出现,容易出现问题,但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

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

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

无关章节啦

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

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

下载zip版本

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

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

0x122 更换主题

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

CTRL+K+T(依次按)

image-20230526192040484

0x123 实时预览

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

image-20230526194505104

0x13 开始写代码

0x131 user_register.html

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

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

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

    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

  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

  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

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

    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

    <!-- 这个东西叫做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-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

0x222 报错分析

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

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

0x223尝试打开网页

打开: http://localhost:8080

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-20230526213040311

  • 端口被占用

    修改文件:

    apache-tomcat-8.5.50\conf\server.xml

    修改为其他的端口

    image-20230526213259596

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

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

    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

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

    image-20230530090327809

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

    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

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

      修改这里就可以啦

      image-20230530093611653

    image-20230530090711842

    image-20230530090756683

    image-20230530090840708

image-20230530091149182

image-20230530092849740

image-20230530093507074

0x25 Tomcat 日志乱码

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

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

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

    修改为GBK编码

image-20230530094425568

  • 重启Tomcat,日志就是正常的啦

    image-20230530094517845

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

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

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

    @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
  • 选择【webapp】->选择【1.4】->填写包名【com.example.testdayi】-> 选择你要存放的文件夹(最好路径全英文)

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

    image-20230530104659041

image-20230530104627519

  • 然后会自动进行创建项目,这个过程可能比较慢,你可以通过一些方法来加速,比如哈利波特

    image-20230530105020289

  • 记得回车两次,你如果能看懂就可以自己看一下

    image-20230530105414154

  • 出现BUILD SUCCESS 就可以了

    image-20230530105455899

0x263 项目修改

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

    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

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

    image-20230530111245287

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

0x264 部署项目

  • 右键tomcat 8.5 ->【 Add Deployment】->【Exploded】

    image-20230530104316092

  • 选择文件夹,如果你改为其他名字的话就是其他名字。

    我这里的目录是:D:\_project\javaweb_\config_tomcat\demo\target\demo

  • 提示是否需要修改配置文件,选择No即可。
  • 然后PUSH server或者直接启动tomcat即可

    image-20230530110614892

  • 右键TOMCAT 8.5 选择,Server Actions,选择show in browser,然后选这个localhost:8080/demo

    image-20230530110653012

    image-20230530113418737

  • 出现项目文件的内容即没问题啦

    image-20230530113454049

0x265 如果需要修改

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

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

image-20230530113708196

  • 打包完进行刷新网页(之后如果出现刷新网页内容不变,则重启下tomcat即可)

    image-20230530113857216

  • 修改的内容出来啦(修改的内容是加了个“Hello”)

    image-20230530113927877

0x30 解决中文乱码

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

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

0x31 使用VSC

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

请跳转到0x32

0x311 添加依赖包

搜索:

Servlet api

image-20230606082002045

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

选择

org.apache.tomcat

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

image-20230606082247591

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

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

image-20230606082353372

0x32 下载IDEA

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

image-20230619235742314

  • 如果你需要白色主题(我喜欢亮滴):
    image-20230619235814348

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-20230620002921394

  • 右上角编辑配置:

    image-20230620002956653

  • 这个昂子:image-20230620003054277

0x332 测试编译

点一下

image-20230620003233932

如果出现success就可以啦

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-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 添加包

  • 新建java目录

    image-20230620003837376

  • 新建包net.dabbit.javaweb.servlet

    image-20230620003848791

  • 然后随便建个类

    image-20230620004005245

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

  • 右上角重新构建,(开始按钮),如果build success就可以了。

    image-20230620005022480

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

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

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

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

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

image-20230620004820389

image-20230624213716435

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

image-20230620004606458

image-20230620004650761

0x337 配置TOMCAT

  • 编辑配置。

image-20230620004927330

  • 选择本地tomcat

    image-20230620005114111

  • 修改参数

    image-20230620005222410

  • 为了防止端口可能冲突,我改了个8081,可以不改

    image-20230620005305117

  • 点击修复。

    image-20230620005333812

  • 然后保存即可。

0x338 启动Tomcat

  • 点击绿色的

image-20230620005414289

  • 这样就是对的了

image-20230620005454094

0x339 访问页面

我这里写的是

http://localhost:8081/our_homework2_war_exploded/Hello

就是自动打开的网页,再加个/Hello

image-20230620005527136

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

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

0x34 解决中文乱码

0x341 尝试直接用中文

  • 修改
  • 重新部署

image-20230620005725629

0x342 发现乱码

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

  • 重新编译(重新部署)

0x345 解决锟斤拷

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

你可以也参考这个:

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

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-20230620233832349

  • 返回之后再购买多次之后

    image-20230620233911286

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>
  • 启动起来访问hello.jsp

    image-20230620094529358

  • 尝试点击销毁(停止Tomcat服务器)

    image-20230620104601530

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

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

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

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

0x534 买个大点的硬盘

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

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

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

0x54 页面转发到用户界面

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

image-20230620162320919

0x542 实现

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

超级简单啦,先上效果图

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

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

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

0x552 新建页眉页脚JSP

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

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

  • header
  • footer
  • 这两个就可以直接去引用jsp啦

    image-20230620232045866

  • 记得重新部署一下

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

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

0x62 JSTL

0x621 加依赖

在pom.xml里添加

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

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

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

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

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

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

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

2023年6月21日00:45:27

睡觉啦。

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

效果如下:

image-20230621092141265

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

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

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

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

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

0x752 Model2

image-20230621144454723

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

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

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

  • 效果如下

0x77 乌拉

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

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

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

0xFF 文件下载

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

JAVA这个目录管理真的有毒

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

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

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

都是一样的)

为啥不删,(舍不得删

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

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