2023年5月

【当前进度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个作业啦。

路由交换-作业11

当前进度 1.01

更新地址: https://blog.dayi.ink/?p=42
更新地址: https://type.dayiyi.top/index.php/archives/179/

【dayi的大键盘】新的博客:https://blog.dayi.ink ,欢迎来体验新的阅读。

更新中修改的内容

本文考虑写作时间的特殊性,如有问题请直接在文章末尾留言,相互提醒下,可能不再更新(写到凌晨1点多,明天还有特别多特别多事,估计来不及改了

0x00 准备文件

分步骤文件可以从文件末尾下载

有时间一定要自己做一遍

要命呜呜呜

0x01 打开文件

image-20230527234554019

0x10 第 1部分:配置设备并 验证连通性

0x11 步骤 1:配置 PC 接口。

a. 使用地址分配 表中列出的 PC3 IPv4 和 IPv6 地址。

b. 使用地址分配 表中列出的 PC4 IPv4 和 IPv6 地址。

PC3

10.0.4.10
255.255.255.0
10.0.4.1

2001:db8:acad:4::10 /64
fe80::2:a

PC4

10.0.5.10
255.255.255.0
10.0.5.1


2001:db8:acad:5::10 /64
fe80::2:b

image-20230527234938185

0x12 步骤 2:配置路由器。

a. 在路由器R2上,打开一个终端。进入特权 EXEC 模式。

b. 进入配置模式。

c. 给路由器R2分配一个设备名。

d. 把c1sco1234配置为加密的特权 EXEC 模式 密码。

e. 把路由器的域名设置为ccna-lab.com。

f. 要防止路由器尝试将错误输入的命令视为主机名 ,则禁用 DNS 查找。

g. 加密明文的密码。

h. 把用户名配置为SSHadmin,把加密密码配置为55Hadm!n。

i. 生成一组加密密钥,把模设置为 1024 位。

j. 把控制台密码配置为cisco,让会话在 6 分钟处于不活动状态则 断开,同时启用登录功能。使用命令logging synchronous 防止 控制台消息打断命令的输入。

k. 把 vty 密码配置为cisco,对 vty 线路进行配置让它只 接受 SSH 连接,并让会话在 6 分钟处于 不活动状态则断开,同时使用本地数据库来启用登录功能。

l. 创建一个向访问设备者发出警告的标语:未经授权, 禁止访问。

m. 启用 IPv6 路由。

n. 使用上面地址分配表中的 IPv4 和 IPv6 编址信息来配置路由器上的所有四个接口。给四个 接口配置描述信息。激活所有四个接口。

o. 将运行配置保存到启动配置文件中。

R2路由器

Router>en
Router#conf t
Enter configuration commands, one per line.  End with CNTL/Z.
Router(config)#hostname R2
R2(config)#enable secret c1sco1234
R2(config)#ip domain-name ccna-lab.com
R2(config)#no ip domain lookup
R2(config)#service password-encryption
R2(config)#username SSHadmin secret 55Hadm!n
R2(config)#crypto key generate rsa
How many bits in the modulus [512]: 1024

#j
R2(config)#line console 0
R2(config-line)#password cisco
R2(config-line)#logging synchronous
R2(config-line)#exec-timeout 6 0
R2(config-line)#login
#k
R2(config-line)#line vty 0 4
R2(config-line)#password cisco
R2(config-line)#exec-timeout 6 0
R2(config-line)#transport input ssh
R2(config-line)#login local

#i 可能有问题,没过
R2(config-line)#banner motd $auth only$

# 后来发现可能必须用这个字符串才能100
banner motd $ WARNING Authorized Users Only! $

#m
R2(config)#ipv6 unicast-routing


#n
R2(config)#int g0/0/0
R2(config-if)#des to S3
R2(config-if)#ip addr 10.0.4.1 255.255.255.0
R2(config-if)#ipv6 addr 2001:db8:acad:4::1/64
R2(config-if)#ipv6 addr fe80::2:a link-local
R2(config-if)#no shut


R2(config-if)#int g0/0/1
R2(config-if)#des to S4
R2(config-if)#ip addr 10.0.5.1 255.255.255.0
R2(config-if)#ipv6 addr fe80::2:b link-local
R2(config-if)#ipv6 addr 2001:db8:acad:5::1/64
R2(config-if)#no shut

R2(config-if)#int s0/1/0
R2(config-if)#des to R1
R2(config-if)#ip addr 10.0.3.2 255.255.255.0
R2(config-if)#ipv6 addr fe80::1:c link-local
R2(config-if)#ipv6 addr 2001:db8:acad:3::2/64
R2(config-if)#no shut

R2(config-if)#int s0/1/1
R2(config-if)#des to internet
R2(config-if)#ip addr 209.165.200.225 255.255.255.252
R2(config-if)#ipv6 addr fe80::1:d link-local
R2(config-if)#ipv6 addr 2001:db8:feed:224::1/64
R2(config-if)#no shut

R2(config-if)#end

#o
R2#copy running-config startup-config
Destination filename [startup-config]? 

0x13 步骤 3:验证网络连接。

a. 在PC3上使用命令行,pingPC4的 IPv4 和 IPv6 地址 。

PC3在【desktop】->【command prompt】执行命令

ping 10.0.5.10
ping 2001:db8:acad:5::10

image-20230528000243310


Q.0x13.a 问题:ping 操作是否成功?

答案:通了,成功了


b. 从R2的 CLI,去 ping R1 S0/1/1 的 IPv4 和 IPv6 地址。分配给 R1 S0/1/1 接口的地址为:IPv4 地址 = 10.0.3.1 IPv6 地址 = 2001:db8:acad:3::1

R2执行

R2(config)#end
R2#ping 10.0.3.1

输出结果:

R2#ping 10.0.3.1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 10.0.3.1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 4/7/10 ms

R2#ping 2001:db8:acad:3::1

Type escape sequence to abort.
Sending 5, 100-byte ICMP Echos to 2001:db8:acad:3::1, timeout is 2 seconds:
!!!!!
Success rate is 100 percent (5/5), round-trip min/avg/max = 8/8/11 ms

R2#

image-20230528000605371

问题:

Q.0x13.b.1 问题:ping 操作是否成功?

答案:如上图所示,成功了


从PC3 的命令行去 ping ISP 的地址 209.165.200.226。

PC3执行:

C:\>ping 209.165.200.226


结果:
Pinging 209.165.200.226 with 32 bytes of data:

Reply from 209.165.200.226: bytes=32 time=12ms TTL=254
Reply from 209.165.200.226: bytes=32 time=10ms TTL=254
Reply from 209.165.200.226: bytes=32 time=7ms TTL=254
Reply from 209.165.200.226: bytes=32 time=10ms TTL=254

Ping statistics for 209.165.200.226:
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 7ms, Maximum = 12ms, Average = 9ms

image-20230528000729161

Q.0x13.b.2 问题:ping 操作是否成功?

答案:如图所示,成功了。

从 PC3 尝试 ping ISP 上的地址 64.100.1.1 来进行测试。

在PC3上执行:

ping 64.100.1.1


#输出内容
C:\>ping 64.100.1.1

Pinging 64.100.1.1 with 32 bytes of data:

Reply from 10.0.4.1: Destination host unreachable.
Request timed out.
Reply from 10.0.4.1: Destination host unreachable.
Reply from 10.0.4.1: Destination host unreachable.

Ping statistics for 64.100.1.1:
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),

C:\>

image-20230528000940689

Q.0x13.b.3 问题:ping 操作是否成功?

答案:失败了,R2没有配置网关出口。


c. 从 PC3 的命令行向 R2 G0/0/0 的 IPv4 地址发起 SSH 会话,并且使用SSHadmin和密码 55Hadm!n进行登录。C:\> ssh -l SSHadmin 10.0.4.1

PC3执行:

C:\> ssh -l SSHadmin 10.0.4.1

#输出内容:
C:\>ssh -l SSHadmin 10.0.4.1

Password: [输入:55Hadm!n]

auth only

R2>enable
Password: [输入:c1sco1234]
R2#

image-20230528001158136

Q.0x13.c 问题:远程访问 成功了吗?

如图所示,成功了。

0x20 第 2 部分:显示路由器信息

在第 2 部分中,您需要在 SSH 会话中使用show命令来从路由器那里检索信息

0x21 步骤 1:向 R2 发起 SSH 会话。

从 PC3 的命令行向R2 G0/0/0 的 IPv6 地址发起 SSH 会话,并且使用SSHadmin和密码55Hadm!n进行登录。

PC3 CMD内

C:\>ssh -l SSHadmin ssh -l SSHadmin 2001:db8:acad:4::1
Password: [输入:55Hadm!n]

image-20230528001959449

0x22 步骤 2:检索重要的硬件 和软件信息。

R2

User Access Verification

Password: [cisco]

R2>enable
Password: [c1sco1234]
R2#show version

输出内容:

R2#show version
Cisco IOS XE Software, Version 03.16.05.S - Extended Support Release
Cisco IOS Software, ISR Software (X86_64_LINUX_IOSD-UNIVERSALK9-M), Version Version 15.5 (3)S5, RELEASE SOFTWARE (fc2)
Technical Support: http://www.cisco.com/techsupport
Copyright (c) 1986-2017 by Cisco Systems, Inc.
Compiled Thu 19-Jan-17 11:24 by mcpre

Cisco IOS-XE software, Copyright (c) 2005-2017 by cisco Systems, Inc.
All rights reserved.  Certain components of Cisco IOS-XE software are
licensed under the GNU General Public License ("GPL") Version 2.0.  The
software code licensed under GPL Version 2.0 is free software that comes
with ABSOLUTELY NO WARRANTY.  You can redistribute and/or modify such
GPL code under the terms of GPL Version 2.0.  For more details, see the
documentation or "License Notice" file accompanying the IOS-XE software,
or the applicable URL provided on the flyer accompanying the IOS-XE
software.


ROM: IOS-XE ROMMON

Router uptime is 4 minutes, 58 seconds
Uptime for this control processor is 4 minutes, 58 seconds
System returned to ROM by power-on
System image file is "bootflash:/isr4300-universalk9.03.16.05.S.155-3.S5-ext.SPA.bin"
Last reload reason: PowerOn


This product contains cryptographic features and is subject to United
States and local country laws governing import, export, transfer and
use. Delivery of Cisco cryptographic products does not imply
third-party authority to import, export, distribute or use encryption.
Importers, exporters, distributors and users are responsible for
compliance with U.S. and local country laws. By using this product you
agree to comply with applicable laws and regulations. If you are unable
to comply with U.S. and local laws, return this product immediately.

A summary of U.S. laws governing Cisco cryptographic products may be found at:
http://www.cisco.com/wwl/export/crypto/tool/stqrg.html

If you require further assistance please contact us by sending email to
export@cisco.com.



Suite License Information for Module:'esg'

--------------------------------------------------------------------------------
Suite                 Suite Current         Type           Suite Next reboot

--------------------------------------------------------------------------------
FoundationSuiteK9     None                  None           None

securityk9
appxk9
    
AdvUCSuiteK9          None                  None           None

uck9
cme - srst
cube


Technology Package License Information:

------------------------------------------------------------------------
Technology    Technology-package                  Technology-package
              Current              Type           Next reboot
------------------------------------------------------------------------
appxk9           None             None             None
uck9             None             None             None
securityk9       securityk9       Permanent        securityk9
ipbase           ipbasek9         Permanent        ipbasek9
security         securityk9       Permanent        securityk9
ipbase           ipbasek9         Permanent        ipbasek9

cisco ISR4321/K9 (1RU) processor with 1687137K/6147K bytes of memory.
Processor board ID FLM2041W2HD
2 Gigabit Ethernet interfaces
2 Serial interfaces
32768K bytes of non-volatile configuration memory.
4194304K bytes of physical memory.
3223551K bytes of flash memory at bootflash:.


Configuration register is 0x2102


R2#

Q.0x22.a.1 路由器运行的 IOS 镜像 的名称是什么?

System image file is "bootflash:/isr4300-universalk9.03.16.05.S.155-3.S5-ext.SPA.bin"

所以是:isr4300-universalk9.03.16.05.S.155-3.S5-ext.SPA.bin

Q.0x22.a.2 路由器有多大非易失性随机访问内存 (NVRAM) ?

32768K bytes of non-volatile configuration memory.

所以是:32768K NVRAM

Q.0x22.a.3 路由器的闪存有多大?

闪存不是内存,闪存可以叫硬盘。

3223551K bytes of flash memory at bootflash:.

所以是:3223551K

show命令往往会提供多屏的输出信息。 用户可通过过滤输出,显示某些部分的输出。要启用过滤命令,需要在 show命令后面 输入管道 (|) 符,然后输入一个过滤参数和一个过滤 表达式。您可以使用include 关键字将输出与过滤语句匹配,以显示输出中包含过滤 表达式的所有行。过滤show version 命令,使用show version | include register 回答以下问题。

执行:

R2#show version | include register 
Configuration register is 0x2102

Q.0x22.b 下一次重新加载中 路由器的启动过程是怎样的?

0x2102 对应二进制:
0010 0001 0000 0010

第1位(最左侧):控制台忽略Break键,这里为0,因此控制台不会忽略Break键。
第3位:控制台忽略Break键,这里为1,表示控制台不会忽略Break键。
第16位(最右侧):0 表示从ROM中加载,1 表示从闪存中加载系统.

路由器启动过程:

  1. 自检(POST)
  2. 加载系统
  3. 读取NVRAM的配置文件
  4. 根据配置文件进行配置接口、协议、参数

0x23步骤 3:显示运行 配置

a. 在路由器上使用命令show running-config来回答 下列问题,但是让输出信息仅显示包含“password”这个词的行。
R2#show running-config 
....
service password-encryption
...
 password 7 0822455D0A16
...
 password 7 0822455D0A16


R2#show running-config | include password
service password-encryption
 password 7 0822455D0A16
 password 7 0822455D0A16
R2#

Q.0x23.a 问题:密码在 输出信息中以什么方式显示?

密码被加密了,通过了一定的算法。

R2# show running-config | begin vty


#输出
R2#show running-config | begin vty
line vty 0 4
 exec-timeout 6 0
 password 7 0822455D0A16
 login local
 transport input ssh
!
!
!
end

使用show running-config | begin vty 命令。注意:更具体的命令是show running-config | section vty; 但是,当前版本的 Packet Tracer 不支持 section这个过滤命令。

Q.0x23.b 问题:使用这条 命令的结果是什么?

R2# show running-config | begin vty


#输出
R2#show running-config | begin vty
line vty 0 4
 exec-timeout 6 0
 password 7 0822455D0A16
 login local
 transport input ssh
!
!
!
end

0x24 步骤 4:在路由器上显示路由表 。

在路由器上使用show ip route 命令来 回答下列问题:
R2#show ip route
Codes: L - local, C - connected, S - static, R - RIP, M - mobile, B - BGP
       D - EIGRP, EX - EIGRP external, O - OSPF, IA - OSPF inter area
       N1 - OSPF NSSA external type 1, N2 - OSPF NSSA external type 2
       E1 - OSPF external type 1, E2 - OSPF external type 2, E - EGP
       i - IS-IS, L1 - IS-IS level-1, L2 - IS-IS level-2, ia - IS-IS inter area
       * - candidate default, U - per-user static route, o - ODR
       P - periodic downloaded static route

Gateway of last resort is not set

     10.0.0.0/8 is variably subnetted, 6 subnets, 2 masks
C       10.0.3.0/24 is directly connected, Serial0/1/0
L       10.0.3.2/32 is directly connected, Serial0/1/0
C       10.0.4.0/24 is directly connected, GigabitEthernet0/0/0
L       10.0.4.1/32 is directly connected, GigabitEthernet0/0/0
C       10.0.5.0/24 is directly connected, GigabitEthernet0/0/1
L       10.0.5.1/32 is directly connected, GigabitEthernet0/0/1
     209.165.200.0/24 is variably subnetted, 2 subnets, 2 masks
C       209.165.200.224/30 is directly connected, Serial0/1/1
L       209.165.200.225/32 is directly connected, Serial0/1/1

R2#

Q.0x24 在路由 表中使用什么代码来标识直连网络?

直连网络使用代码"C"、“L”来标识。
在"C"代码后面是网络地址和子网掩码,表示该网络是直接连接的。
在“L”代码后面的是本地连接。

C 10.0.3.0/24 is directly connected, Serial0/1/0
C 10.0.4.0/24 is directly connected, GigabitEthernet0/0/0

Q.0x24 路由表中有多少个路由条目以代码 C 标识?

4

0x25 步骤 5:显示路由器接口上的汇总列表 。

a. 在路由器上使用show ip interface brief命令,回答 以下问题。
R2#show ip interface brief
Interface              IP-Address      OK? Method Status                Protocol 
GigabitEthernet0/0/0   10.0.4.1        YES manual up                    up 
GigabitEthernet0/0/1   10.0.5.1        YES manual up                    up 
Serial0/1/0            10.0.3.2        YES manual up                    up 
Serial0/1/1            209.165.200.225 YES manual up                    up 
Vlan1                  unassigned      YES unset  administratively down down
R2#

Q.0x25.a.1 哪个命令能够将千兆以太网端口的 状态从管理性关闭更改为管理性开启?

no shutdown

Q.0x25.a.2 您可以使用什么过滤命令让设备只显示 分配了地址的接口?

show ip interface brief | exclude unassigned
b. 使用命令show ipv6 int brief查看 R2 上的 IPv6 设置。
R2#show ipv6 int brief
GigabitEthernet0/0/0       [up/up]
    FE80::2:A
    2001:DB8:ACAD:4::1
GigabitEthernet0/0/1       [up/up]
    FE80::2:B
    2001:DB8:ACAD:5::1
Serial0/1/0                [up/up]
    FE80::1:C
    2001:DB8:ACAD:3::2
Serial0/1/1                [up/up]
    FE80::1:D
    2001:DB8:FEED:224::1
Vlan1                      [administratively down/down]
    unassigned
R2#

Q.0x25.b 输出信息中的 [up/up] ,表示的是什么意思?

[up/up]表示接口的状态。
第一个"up"表示接口的输入方向(inbound)是up状态,即接口能够接收和处理数据包。
第二个"up"表示接口的输出方向(outbound)是up状态,即接口能够发送数据包。

0x30 文件下载

做到凌晨1点。

https://pic.icee.top/blog/pic_bed/%E5%88%86%E6%AD%A5%E9%AA%A4%E6%96%87%E4%BB%B6.rar

image-20230528005832224

手写压位高精度(N^2)乘法

O(N)加法
没什么出众的地方,只是一次作业,也当练习一下。


#include<bits/stdc++.h>

// by.dayi 23.5.10
// 第一次尝试写压位高精度
// 其实python可太容易了,但是想趁着机会练一下手写

const int maxn = 10086; // 数组长度,高精度最大可以存4*maxn位,可以无限增加,但是乘法是n^2实现的
const int power = 4; //10^4次方,高精度压位,每个位存4位,因为10^8<2^31,但是10^10>2^31
const int base  = 1e4; // 基数

//最大值 最小值
template <typename T> T max(T a,T b){return a>b?a:b;} 
template <typename T> T min(T a,T b){return a<b?a:b;} 

struct big_dec{//高精度
  int a[maxn];//数组长度
  int _len_big_dec;//当前长度
  int f;

  big_dec(){//结构体构造函数,初始化
    memset(a,0,sizeof(a));
    _len_big_dec = 0;
    f = 0;//f=1为负数
  }

  //从字符串读取
  inline void read_from_str(const char *str){
    int len = strlen(str);//数组长度
    int k = 1;//当前的位置
    int w = 1;//当前位的权值
    int end = 0;//结束位置

    //负数
    if(str[0]=='-'){f=1;end=1;}

    for(int i=len-1;i>=end;i--){
      // 12   345678
      // a[2] a[1]
      a[k] += (str[i]-'0')*w;//加位
      w*=10;//权值增加
      if(w==base){//权值到达基数
        w = 1;//权值归1
        k++;//位置增加
      }
    }
    _len_big_dec = k;
  }
  
  bool is_zero() const { //是否是0
    return _len_big_dec == 1 && a[1] == 0;
  }

  big_dec abs() const { //绝对值
    big_dec ans = *this;
    ans.f = 0;
    return ans;
  }

  //stdout标准输出
  inline void print_stdout(){
    if(this->f)printf("-");//负数
    for(int i=_len_big_dec;i>=1;i--){
      if(i==_len_big_dec && a[i]!=0) printf("%d",a[i]);
      else printf("%04d",a[i]);
    }
  }

  //赋值,也是复制
  big_dec operator = (const big_dec &b){
    _len_big_dec = b._len_big_dec;
    f = b.f;
    for(int i=1;i<=_len_big_dec;i++){
      a[i] = b.a[i];
    }
    return *this;
  }

  // 小于号
  bool operator<(const big_dec &b) const {
    if (f != b.f) {return f > b.f;} //0为正数,1为负数,0>1 
    if (_len_big_dec != b._len_big_dec) {//长度
      return f?(_len_big_dec > b._len_big_dec):(_len_big_dec < b._len_big_dec);
    }

    //长度相同,判断每一位
    for (int i=_len_big_dec;i>=1;i--){
      if (a[i]!=b.a[i]) {
        return f?(a[i]>b.a[i]):(a[i]<b.a[i]);
      }
    }
    return false; // 相等
  }

  // 大于号
  bool operator>(const big_dec &b) const {
    return b<*this; // 反向比较即可
  }


  //加法,要命
  big_dec operator + (const big_dec &b){
    big_dec ans;//结果
    if(f==b.f){//同号相加
      ans.f=b.f;
      int len=max(_len_big_dec,b._len_big_dec);
      for(int i=1;i<=len;++i){
        ans.a[i] += a[i]+b.a[i]; //加位
        if(ans.a[i]>=base){//需要进位
          ans.a[i+1]++;//进位
          ans.a[i]-=base;
        }
      }
      ans._len_big_dec=ans.a[len+1]?len+1:len+0; //判断最高位是否需要进位
    }else{//异号的情况
      big_dec c,d; // c的绝对值小于d
      c = min(this->abs(),b.abs());
      d = max(this->abs(),b.abs());
      ans.f = d.f;//结果与绝对值大的相同
      int len = max(c._len_big_dec,d._len_big_dec);
      for(int i=1;i<=len;++i){
        //如果当前位小于等于c的长度,就减去c的当前位,否则减去0
        ans.a[i] += d.a[i]-(i<=c._len_big_dec?c.a[i]:0);
        if(ans.a[i] < 0){// 需要借位
          ans.a[i] += base; // 加上基数
          ans.a[i+1]--; // 借位
        }
      }
      while(len>1 &&(ans.a[len] == 0)) len--;//去除前导0
      ans._len_big_dec = len;//更新
    }
    return ans;
  }

  //乘法(On^2)
  big_dec operator * (const big_dec &b){
    big_dec ans;
    ans.f = f^b.f;//异或就可以,一样的是正也就是0,不一样的是负也就是1
    for(int i=1;i<=_len_big_dec;++i){
      for(int j=1;j<=b._len_big_dec;++j){
        ans.a[i+j-1] += a[i]*b.a[j];//乘
        if(ans.a[i+j-1]>=base){//需要进位
          ans.a[i+j] += ans.a[i+j-1]/base;//要除基本的倍数
          ans.a[i+j-1] %= base;//mod一下
        }
      }
    }
    int max_len = _len_big_dec+b._len_big_dec;//最大的可能位数
    while(max_len>1 && ans.a[max_len]==0) max_len--;//同样的去除前导0
    ans._len_big_dec = max_len;//赋值
    return ans;
  }

  //相反数
  big_dec operator-() const {
    big_dec ret = *this;
    ret.f = !f; // 符号取反
    return ret;
  }

  //减法,直接加相反数
  big_dec operator - (const big_dec &b){
    big_dec ans ; 
    ans = *this + -b;
    if(*this<b){
      ans.f = !ans.f;
    }
    return ans;
  }

  // to_int
  int to_int() const {
    int ans = 0;
    for (int i=_len_big_dec;i>=1;--i) {
      ans = ans*base+a[i];
    }
    return f ? -ans : ans;
  }
  // to_long_long
  long long to_long_long() const {
    long long ans = 0;
    for (int i=_len_big_dec;i>=1;--i) {
      ans = ans*base+a[i];
    }
    return f ? -ans : ans;
  }
} ;

int main(){
  big_dec a, b, ans;
  char str[10086];

  printf("a:");
  scanf("%s", str);
  a.read_from_str(str);

  printf("b:");
  scanf("%s", str);
  b.read_from_str(str);

  printf("Big Decimal value:\n"); //高精度十进制数值
  printf("a:");a.print_stdout();printf("\n");//输出
  printf("b:");b.print_stdout();printf("\n");//输出

  printf("To int and long long,maybe overflow:\n");//转换为int和long long,可能会溢出
  printf("a_to_int: %d\n", a.to_int());//转换为int
  printf("a_to_long_long: %lld\n", a.to_long_long());//转换为long long
  printf("\n");
  printf("b_to_int: %d\n", b.to_int());//转换为int
  printf("b_to_long_long: %lld\n", b.to_long_long());//转换为long long
  printf("\n");

  ans = a + b;
  printf("a + b = ");//加法
  ans.print_stdout(); printf("\n");

  ans = a - b;
  printf("a - b = ");//减法
  ans.print_stdout(); printf("\n");

  ans = a * b;
  printf("a * b = ");//乘法
  ans.print_stdout(); printf("\n");
 

  return 0;
}

//测试样例1:
//114514
//1919810

//a:114514
//b:1919810
//Big Decimal value:
//a:114514
//b:1919810

//To int and long long,maybe overflow:
//a_to_int: 114514
//a_to_long_long: 114514
//
//b_to_int: 1919810
//b_to_long_long: 1919810
//
//a + b = 2034324
//a - b = -1805296
//a * b = 219845122340


//=========================================
//测试样例2:
//1145140000114514000
//-191981000019198100019198101919810

//输出:
// a:1145140000114514000
// b:-191981000019198100019198101919810
// Big Decimal value:
// a:1145140000114514000
// b:-191981000019198100019198101919810

// To int and long long,maybe overflow:
// a_to_int: 1290442832
// a_to_long_long: 1145140000114514000 (这里正确转换了,还没有溢出longlong)
// 
// b_to_int: -181246018
// b_to_long_long: 5304828336058558398
// 
// a + b = 191981000019196954879197987405810
// a - b = 191981000019199245159198216433810
// a * b = -219845122383969024492182965658049674843245122340000

//py3.11输出结果:-219845122383969024492182965658049674843245122340000

路由交换-作业10-7.4.1 CCNA7 实施DHCPv4

当前进度 1.0

更新地址: https://blog.dayi.ink/?p=35
更新地址: https://type.dayiyi.top/index.php/archives/173/

【dayi的大键盘】新的博客:https://blog.dayi.ink ,欢迎来体验新的阅读。

更新中修改的内容

在试错过程中发现并修改的内容:

目前没有

0x00 准备文件

文件下载:

分步骤文件可以从文件末尾下载

有时间一定要自己做一遍

0x01 打开文件

image-20230509082146607

看了看,感觉..有点夸张的样子

做完的dayi:没有那么夸张,而且挺快的

0x02 引言

地址分配表

设备R1

接口IPv4 地址子网掩码默认网关
G0/0192.168.10.1255.255.255.0不适用
S0/0/010.1.1.1255.255.255.252不适用

设备R2

接口IPv4 地址子网掩码默认网关
G0/0192.168.20.1255.255.255.0不适用
G0/1DHCPDHCP不适用
S0/0/010.1.1.2255.255.255.252不适用
S0/0/110.2.2.2255.255.255.252不适用

设备R3

接口IPv4 地址子网掩码默认网关
G0/0192.168.30.1255.255.255.0不适用
S0/0/110.2.2.1255.255.255.0不适用

非交换设备

设备接口IPv4 地址子网掩码默认网关
PC1NICDHCPDHCPDHCP
PC2NICDHCPDHCPDHCP
DNS 服务器NIC192.168.20.254255.255.255.0192.168.20.1

目标

1 部分:将路由器配置为 DHCP 服务器

2 部分:配置 DHCP 中继

3 部分:将路由器配置为 DHCP 客户端

场景

作为公司的网络技术人员, 您的任务就是将思科路由器配置为 DHCP 服务器,为网络上的客户端提供动态地址 分配。您还需要将边缘路由器配置为 DHCP 客户端, 使它能够从 ISP 网络接收 IP 地址。由于服务器是集中式部署的, 因此您需要配置两个 LAN 路由器,以便在 LAN 和充当 DHCP 服务器的那台路由器之间中继 DHCP 流量。

0x03 相关内容

  1. 暂无

0x10 第 1 部分: 将路由器配置为 DHCP 服务器

0x11 第 1 部分:步骤 1 : 配置排除的 IPv4 地址。

配置 R2 从 R1 LAN 和 R3 LAN 中排除前 10 个地址。 DHCP 地址池中的所有其他地址都应该可用。
  1. 先看下网络拓扑图:

    image-20230509083739217

    要命

    • R1 的 LAN 192.168.10.0/24
    • R3 的 LAN 192.168.30.0/24

    这样前10个就是除去

    • 192.168.10.1-10
    • 192.168.30.1-10
  2. 在R2的CLI里输入命令

    R2>en
    R2#conf t
    R2(config)#ip dhcp excluded-address 192.168.10.1 192.168.10.10
    R2(config)#ip dhcp excluded-address 192.168.30.1 192.168.30.10

0x12 第 1 部分:步骤 2 : 在 R2 上为 R1 LAN 创建 DHCP 池。

a. 创建命名为 R1-LAN 的 DHCP 池。这个池的名称必须匹配上面的值, 这样配置才能得分。

b. 配置 DHCP 池以包括 DNS 服务器的网络地址、默认网关和 IP 地址。

  1. 创建名字为R1-LAN的地址池子

    R2(config)#ip dhcp pool R1-LAN
  2. 配置网段,默认网关,DNS

    • DNS服务器:192.168.20.254
    • 默认路由:192.168.10.1(也就是R1的地址)
    • 子网掩码前缀:24,对应255.255.255.0
    R2(dhcp-config)#network 192.168.10.0 255.255.255.0
    R2(dhcp-config)#default-router 192.168.10.1
    R2(dhcp-config)#dns-server 192.168.20.254

image-20230509084713227

0x13 第 1 部分:步骤 3 : 在 R2 上为 R3 LAN 创建 DHCP 池。

a. 创建命名为 R3-LAN (区分大小写) 的 DHCP 池。

b. 配置 DHCP 池以包括 DNS 服务器的网络地址、默认网关和 IP 地址。

  1. 同理啦
  2. 创建地址池R3-LAN

    R2(config)#ip dhcp pool R3-LAN
    
    #或者↓这样直接输就行
    R2(dhcp-config)#ip dhcp pool R3-LAN 
    
    # ↓复制用,但是建议手打哦
    ip dhcp pool R3-LAN 
  3. 配置网段,默认网关,DNS

    • DNS服务器:192.168.20.254
    • 默认路由:192.168.30.1(也就是R3的地址)
    • 子网掩码前缀:24,对应255.255.255.0
    R2(dhcp-config)#network 192.168.30.0 255.255.255.0
    R2(dhcp-config)#default-router 192.168.30.1
    R2(dhcp-config)#dns-server 192.168.20.254
    
    # ↓复制用,但是建议手打哦
    network 192.168.30.0 255.255.255.0
    default-router 192.168.30.1
    dns-server 192.168.20.254

image-20230509085604431

目前咱35的进度

image-20230509085705116

0x20 第 2 部分: 配置 DHCP 中继

0x21 第 2 部分:步骤 1 : 将 R1 和 R3 配置为 DHCP 中继代理。

  1. 先看下地址表:

    设备R2

    接口IPv4 地址子网掩码默认网关
    G0/0192.168.20.1255.255.255.0不适用
    G0/1DHCPDHCP不适用
    S0/0/010.1.1.2255.255.255.252不适用
    S0/0/110.2.2.2255.255.255.252不适用
  2. 可以发现,R2的在两个路由器之间的IP分别是

    • 10.1.1.2 (与R1)
    • 10.2.2.2 (与R3)
  3. 设置R1作为中继代理

    R1>en
    R1#conf t
        Enter configuration commands, one per line.  End with CNTL/Z.
    
    #↓主要命令
    R1(config)#int g0/0
    R1(config-if)#ip helper-address 10.1.1.2
    
    # ↓复制用,但是建议手打哦
    en
    conf t
    int g0/0
    ip helper-address 10.1.1.2
  4. 设置R3作为中继代理

    R3>en
    R3#conf t
        Enter configuration commands, one per line.  End with CNTL/Z.
    
    #↓主要命令
    R3(config)#int g0/0
    R3(config-if)#ip helper-address 10.2.2.2
    
    # ↓复制用,但是建议手打哦
    en
    conf t
    int g0/0
    ip helper-address 10.2.2.2

进度64

image-20230509090518335

0x22 第 2 部分:步骤 2 : 设置 PC1 和 PC2 从 DHCP 接收 IP 编址信息。

这个就是纯手点一下就可以

  1. PC1如果正确获得了IP,说明成功啦

    image-20230509090740725

  2. PC2也同理啦

    image-20230509090855267

0x30 第 3 部分: 配置 R2 作为 DHCP 客户端

0x31 第 3 部分: 配置 R2 上的千兆以太网 G0/1 接口从 DHCP 接收 IP 编址。

  1. 这个机翻无力吐槽了
  2. 去R2上去配置一下就可以,这里是为了访问外网,类似ISP分配下地址

    R2>en
    R2#conf t
        Enter configuration commands, one per line.  End with CNTL/Z.
    R2(config)#int g0/1
    R2(config-if)#ip addr dhcp
    
    # ↓复制用,但是建议手打哦
    en
    conf t
    int g0/1
    ip addr dhcp

0x32 第 3 部分:激活接口。

  1. 我觉得这一步跟上一步一起做完比较好

    R2(config-if)#int g0/1
    R2(config-if)#no shut
    
    # ↓复制用,但是建议手打哦
    int g0/1
    no shut
  2. 完成

image-20230509092325092

0x40 文件下载

image-20230509092458277