【当前进度1.102】JAVA Web 作业当前进度1.102 不骗你，第一个任务估计也就0.01，乐观点也最多百分之6https://type.dayiyi.top/index.php/archives/181/1.00了，测试版当前共计：13997字2023年6月20日01:10:162023年6月21日00:45:472023年6月21日11:40:242023年6月21日15:32:392023年6月22日09:35:432023年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:020x01 文件下载由于涉及的文件真的非常的多，我也临时没想好应该如何共享这些文件。使用之前的下载方式使用阿里云盘使用阿里云盘开网页直接下载，无需登录后来看，文件也没那么多，于是，直接在文章末尾可以进行文件下载。0x02 目录说明大致如下0x01 章节1 - 0x011 章节1.1 - 0x012 章节1.2 0x02 章节2 - 0x021 章节2.1 - 0x022 章节2.20x03 开发工具因为整个课程涉及了WEB几乎全栈的开发，因此，这里使用了以下的工具VSCODEChrome 浏览器IDEA（关键）Tomcat（8.5）maven（进行包管理，非常的方便）0x10 蛋糕商场的注册界面该部分对应实验报告内容如下序号实验项目完成时间1蛋糕商城注册页面2.280x11 准备文件需要准备这些文件，这些文件的压缩包在群文件中有。群文件名：23.2.28_java_web.rar链接下载：https://p.dabbit.net/blog/pic_bed/2023/05/a77f2e125a83aee1_202305261907278.7z这里准备好这8个文件，4个css样式文件，4个字体文件这两个红色的圈，是两个文件夹，您下下文件7z来就可以了。解压后用VSC打开这个文件夹。就会有类似这样的样子。可能有所差距， 是因为主题包的问题。注意目录和文件最好不要涉及到中文，尽可能只有英文、数字、下划线，其他的字符尽可能不要出现，容易出现问题，但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）的插件包这里是报告结束的dayi（2023年6月24日21:05:22）这篇报告写了一个月诶，其实也没必要装太多插件，装个HTML高亮和补全就可以。这么多插件也就用到一两个诶。0x121 如果你想要修改vscode为绿色版，也就是携带版无关章节啦携带版就是所有的插件、数据文件存在当前的目录，可以塞优盘里等。从官网：Download Visual Studio Code - Mac, Linux, Windows下载zip版本解压之后，在跟VSCODE.EXE同样目录下，新建文件夹data即可。数据就会一直保存在这里啦。0x122 更换主题无关章节，换个主题多好看呀。CTRL+K+T（依次按）0x123 实时预览无关章节，可选章节，因为咱们写的页面并不多，一开始我觉得要写很多页面所以写了这个地方。0x13 开始写代码0x131 user_register.html如果你打不开下图的界面，VSCODE:左上角文件->打开文件夹（你可以新建一个，然后把css和fonts两个文件夹放进去）->然后打开这个文件夹就可以了（注意不是打开文件）准备好文件之后，开始写代码新建文件./project/user_register.html（别在意这个图,图错啦，是user_register.html，不是header.html;2023年6月24日21:08:37 补上图：简单点的代码（不过建议直接看下一点（3.简单写一下代码如下 ） 的内容，注释更多）这里进行了一定的简单注释，如果你想要了解更多，可以自己去菜鸟教程之类的网站、书、课等去看看哦。 注册用户 新用户！ 用户名 * 邮箱 * 密码 * 收货人 收货人电话 收货人地址 效果如下，其实也能看简单写一下代码如下（好吧好吧，如果第一次看这个东东，估计也不是很简单）这个代码的话，我尽可能解释一点，更多的内容还是自己去学一学。 注册用户 这里是头 这里也是头 热销 新品 注册 登录 新用户！ 用户名 * 邮箱 * 密码 * 收货人 收货人电话 收货人地址 这里是底哦，你可以写你想要的内容，比如（C）dayi 你也可以让字体大一点 效果图如下：稍微把头修改一下也就是 的部分 主页 其他页面 热销 新品 注册 登录 搜索 把header和footer分出来，新建为两个文件，方便后序其他文件的使用header.html 主页 其他页面 热销 新品 注册 登录 搜索 footer.html 这里是底哦，你可以写你想要的内容，比如（C）dayi 你也可以让字体大一点 到此，任务一完成，然而，这之前暴雨前的黎明（0x14 点击提交会发生什么？科普章节，你不需要写。点击之后会发生这样的事情：浏览器会发送这些数据到后端也就是这些内容会POST到服务器username=123&email=213&password=213123123&name=123124&phone=123658&address=231900x20 配置tomcat唔写不动了0x21 准备文件【java-web-tomcat服务器】apache-tomcat-8.5.50-windows.ziphttps://p.dabbit.net/blog/pic_bed/2023/05/2382cd17a1cf1632_202305262111014.zip这个地方比较麻烦java环境，最好是1.8版本你必须有JDK，17也可以，1.8（推荐）也可以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如果你的是小黑窗口一闪而过，那就需要配置环境变量啦。0x222 报错分析如果跟上面的图片一样，恭喜你，你没有报错。1. shift+右键，选择在此打开cmd/powershell/终端 2. 输入cmd 3. 输入startup.bat一般会提示JAVA_HOME找不到，这个时候，你只需要去0x23去修改下JAVA_HOME即可。0x223尝试打开网页打开: http://localhost:8080出现了，恭喜你，你省去了很多事情，并且简单的成功了0x23 报错上一步成功了，本章节可以忽略我没有JAVA，那就下载JAVAhttp://java.comJava 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？https://p.dabbit.net/blog/pic_bed/jdk1.8.0_361_ad874039-ce6d-497a-95d6-d3b0803.7z端口被占用修改文件：apache-tomcat-8.5.50\conf\server.xml修改为其他的端口但我建议你搜索端口号占用进程，并且杀掉他netstat -aon | findstr 8080 tasklist | findstr + 进程号 taskkill /f /im 进程名.exe0x241 在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：这里还保留这个章节的原因是，因为，如果你这样配置之后，你会对整个过程更加了解哦。下载插件Community Server Connectors右下角可能会报错，如果提示当前JAVA版本不够，需要更高版本：添加rsp-ui.rsp.java.home，到你的高版本JDK目录，注意\\和\的区别右键，Create Server，提示是否需要下载，你可以用本地的，也可以下载一个，差不多。我这里选择用本地的。如果你选下载，是否同意都同意即可。导入本地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" %> index hello world <% out.println(1024 * 1024); %> 访问http://127.0.0.1:8080/rabbit/，可以看到网页，表示成功了。如果需要修改JSP的运行目录：修改这里就可以啦0x25 Tomcat 日志乱码看到一堆锟斤拷了吗进行修一修。0x251 方法1，修改为GBK编码输出（推荐）修改文件：apache-tomcat-8.5.50\conf\logging.properties修改为GBK编码重启Tomcat，日志就是正常的啦0x252 方法2，修改启动参数（没有成功）好像不生效。我觉得这样改也不对。就不要这样改了。这个方法就参考一下，图个乐。可能是在Linux下，不过我觉得这样改也怪怪的 ，本来好像就是UTF-8，但是cmd编码是GBK。因此会出现锟斤拷。在Tomcat文件夹目录中，/bin/catalina.bat里面修改，添加set JAVA_OPTS= -Dfile.encoding=UTF-8111 |setlocal 112 |set JAVA_OPTS= -Dfile.encoding=UTF-8 113 |rem Suppress Terminate batch job on CTRL+C 添加112行0x26 VSC-Tomcat部署项目参考过程，用IDEA会快一点，但如果你这样配置之后，你会对MVN（maven）有更深的了解。很麻烦对吧，这就是学计算机0x261 插件安装Extension Pack for Java Maven for Java Debugger for Java0x2611 安装maven我之前好像编译过java项目，所以我没这个步骤，但是如果你没配过，还是要配一次。下载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进入到设置里，修改配置参数：这里可能需要复制的内容：@ext:vscjava.vscode-maven然后在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.cmd0x262 新建项目右键文件列表目录，新建项目选择【webapp】->选择【1.4】->填写包名【com.example.testdayi】-> 选择你要存放的文件夹（最好路径全英文）什么是包名，一般就是网址域名的反过来写就可以。然后会自动进行创建项目，这个过程可能比较慢，你可以通过一些方法来加速，比如哈利波特记得回车两次，你如果能看懂就可以自己看一下出现BUILD SUCCESS 就可以了0x263 项目修改修改下文件，以便后面的测试文件：demo\src\main\webapp\index.jsp内容如下：<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %> index hello world <% out.println(1024 * 1024); out.println("你好"); %> 进行编译和部署点击这里的package如果出现SUCCESS ，并且demo里面出现文件，则构建（BUILD）成功。这个目录有demo，index.jsp，WEB-INF META-INF几个文件即可。0x264 部署项目右键tomcat 8.5 ->【 Add Deployment】->【Exploded】选择文件夹，如果你改为其他名字的话就是其他名字。我这里的目录是：D:\_project\javaweb_\config_tomcat\demo\target\demo提示是否需要修改配置文件，选择No即可。然后PUSH server或者直接启动tomcat即可右键TOMCAT 8.5 选择，Server Actions，选择show in browser，然后选这个localhost:8080/demo出现项目文件的内容即没问题啦0x265 如果需要修改要在src文件夹里修改哦，虽然你该target目录下的也可以生效，但是这样不对。文件:demo\src\main\webapp\index.jsp修改完之后进行再打包。package即可。打包完进行刷新网页（之后如果出现刷新网页内容不变，则重启下tomcat即可）修改的内容出来啦（修改的内容是加了个“Hello”）0x30 解决中文乱码看似简单，实际是写一个servlet【本章节弃用】，但是舍不得删掉）0x31 使用VSC本章节弃用，但是建议手动试试装包过程，和包编译和maven进行维护。请跳转到0x320x311 添加依赖包搜索：Servlet api选择Tomcat的也就是，搜索完之后：选择org.apache.tomcat这样的包，然后会自动提示在pom.xml里更新文件，保存即可。CTRL+S保存文件就可以啦。然后会提示是否同步依赖，同步就可以。0x32 下载IDEA这个可以省时间，就用这个了。有人连bing都懒得用，这里下载：https://www.jetbrains.com/zh-cn/idea/，点击Download。我下的是 Ultimate，激活用数据库群里的一个我传的压缩包，或者用学校邮箱认证正版，这里链接就不放了。下载之后安装，一直下一步就可以。然后 随便打开一个不带中文目录的空文件夹左上角，File->Setting->Plugins搜索 chinese选择第二个插件，点击Install等一会就是中文了，可能需要重启。如果你需要白色主题（我喜欢亮滴）：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来帮我们简化过程。为什么这里改用IDEADEA确实方便一点，而且能加快开发。这里是写完初稿的dayi：2023年6月24日21:31:04，IDEA，不是很想承认，但是确实挺好用。0x331 建立项目文件，新建项目，如图所示名称随意，但是建议不要出现任何中文位置，不建议出现中文JDK建议选择1.8，可以自动下载选择webapp框架高级设置填默认，但这里可以填一下包名，具体的可以参考0x241的视频。这个过程在0x241下有参考视频然后大概这个样子：右上角编辑配置：这个昂子：0x332 测试编译点一下如果出现success就可以啦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>加完之后点这里哦如果你需要全部的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目录新建包net.dabbit.javaweb.servlet然后随便建个类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); } } 右上角重新构建，（开始按钮），如果build success就可以了。0x336 如果你发现一堆红色的提示，记得更新MVN别尝试下，1.9G的仓库，下半辈子。如果你跟我一样一堆红色的，记得更新下包，别别别，别更新包，1.9G的包索引，够你的。这里点击加载更改就行（蓝色的图标）如果还是不行，重启下IDEA应该就行了。。感觉这些文字在打架，dayi1:确实，dayi2：确实下面这段别管了。dayi:2 这是dayi1干的蠢事。0x337 配置TOMCAT编辑配置。选择本地tomcat修改参数为了防止端口可能冲突，我改了个8081，可以不改点击修复。然后保存即可。0x338 启动Tomcat点击绿色的这样就是对的了0x339 访问页面我这里写的是http://localhost:8081/our_homework2_war_exploded/Hello 就是自动打开的网页，再加个/Hello打开的文件如图，正确的。如果，你这里失败了，那样可能需要做一些不少的工作来成功，下面的步骤都是基于TOMCAT的，得把TOMCAT配置好。0x34 解决中文乱码0x341 尝试直接用中文修改重新部署0x342 发现乱码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); } } 重新编译（重新部署）0x345 解决锟斤拷0x35 问题解决，文件下载睡觉啦。2023年6月20日01:02:510x35_our_homework2.ziphttps://p.dabbit.net/blog/pic_bed/2023/06/9c76394a5a75ad2b_202306200107974.zip0x40 实现购物车代码注释有点少，应该自己仔细看看就看得懂，大篇其实都是JAVA的类的相关。有时间的话就补充注释。0x41 新建包小提示：ALT+左键 、ALT + 左键 可以一次多点好几行哦，然后一起修改内容。小提示2：ALT+ENTER可以修复代码的很多错误哦。总共三个包，这里是我的命名，你完全可以不按照这个命名。net.dabbit.configs 这个是配置文件，记录URL的对应关系net.dabbit.entity 实体类，你感觉像实体的都是实体net.dabbit.servlet2 这个包是servlet为什么这样做，因为dabbit.net是咱的域名。你完全可以修改成你自己的，或者你自定义点。你可以也参考这个：那些CAKE什么的都是java的类哦。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.Cakepackage 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.CakeCartpackage 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.CakeDBpackage 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.Configpackage 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 servlet0x441 列出蛋糕ListCakeServletpackage 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("给您提供的蛋糕有： "); 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() + "点击购买 "); } String url = cfg.CART_OF_CAKE; out.write(" 查看我的购物车:" + "查看我的购物车 "); } } 0x442 购买请求PurchaseServletpackage 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 购物车CartServletpackage 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信息，您可能没有访问过网站，也没有购买过蛋糕，是不是呀大黑阔 "); return; } cart = (CakeCart) session.getAttribute("shopping_cart");//获得cart属性 if(cart==null){ out.println("您购物车好像是空哒嘎嘎嘎 "); return; } out.println("OK,这是您购物车里的吃的: "); //枚举购物车里的吃的 for (Cake c:cart.get_cart()) out.println(c.getName() + " "); //打印购买列表的表。 Config cfg = new Config(); String url = cfg.getId("LIST_CAKE_URL"); out.write(" 返回购买列表:" + "返回购买列表 "); } } 0x445 实现效果访问:你要访问你自己的界面呀，ListCakeServlet是你自己的相对呀。比如你默认的在：http://localhost:8082/java1_war_exploded/那就这样打开http://localhost:8082/java1_war_exploded/ListCakeServlet点击购买孙橙子味道返回之后再购买多次之后0x4F 文件下载请跳转到0xFF中的0x554dayi2：很遗憾，做的时候压缩错文件夹了，过程文件丢失了一点。但是最后的文件是有哒。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"%> life.jsp <%! 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; %> JSP <%=content1 %> <%=content2 %> <%=content3 %> <%--来自菜鸟教程--%> 启动起来访问hello.jsp尝试点击销毁（停止Tomcat服务器）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" %> Time <% Date dt = new Date(); SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String today =df.format(dt); %> 当前时间：<%=today%> 0x532 显示1+1和动态注释时间显示1+1和动态注释时间<%-- 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" %> Title <% int a = 5; int b = 10; out.println(a + b); %> <%--动态注释--%> <!-- 这是一跳注释，但是注释的时间是：<%=new Date()%> --> 0x533 引用其他文件引用其他文件<%@ include file="time.jsp"%>0x534 买个大点的硬盘618有活动，980PRO 479，跟送一样（我1700买的，哭死）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" %> Title forward: <jsp:forward page="hello.jsp" /> 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，如果报错了就去那个地方--%> Title <% int a = 1; int b = 0; out.println(a/b);//除0，产生错误。 %> 新建一个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"%> error page 这里是错误信息！OVO: <%=exception.getMessage()%> 0x54 页面转发到用户界面0x541 我把之前的文件扔到了jsp-examles文件夹0x542 实现本任务要求使用<jsp:forward>请求转发动作元素将页面转发到用户登录页面。超级简单啦，先上效果图http://localhost:8082/java1_war_exploded/user_forward/forward.jsp两个文件代码如下：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" %> 跳转页 <jsp:forward page="login.jsp"></jsp:forward> 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" %> Login 你好呀，这里是登录界面。 用户名： 密码： 到目前为止，文件可以在文章末尾下载0x55 实现蛋糕商城0x551 复制文件记得留备份哦我把之前咱们的文件复制到项目这里了。0x552 新建页眉页脚JSP其实只要复制过来就可以啦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" %> 主页 其他页面 热销 新品 注册 登录 搜索 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" %> 这里是底哦，你可以写你想要的内容，比如（C）dayi 你也可以让字体大一点 0x553 新建文件user_register.jspheaderfooter这两个就可以直接去引用jsp啦记得重新部署一下全部的代码如下：<%-- 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" %> 注册用户 <jsp:include page="header.jsp"></jsp:include> 新用户！ 用户名 * 邮箱 * 密码 * 收货人 收货人电话 收货人地址 <jsp:include page="footer.jsp"></jsp:include> 0x554 有头有尾就算成功啦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哦--%> 1+1 = ${1+1} 请求URI为：${pageContext.request.requestURI} Content-Type响应头：${pageContext.response.contentType} 服务器信息为：${pageContext.servletContext.serverInfo} Servlet注册名为：${pageContext.servletConfig.servletName} 0x62 JSTL0x621 加依赖在pom.xml里添加<dependencies> ==开始 <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> ==结束 </dependencies> 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"%> <c:out value="Hello World!"></c:out> URL:http://localhost:8082/java1_war_exploded/el/jstl.jsp你的不一定是哦。0x623 JSTL escapexmlescapeXml 设置为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"%> Title <%--页面跳转--%> <c:out value="${null}" escapeXml="false"> </c:out> <%-- 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"%> Title <c:out value="${null}" escapeXml="false"> 使用的表达式结果为null，则输出该默认值 </c:out> 设置为 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"%> Title <c:out value="${null}" escapeXml="true"> 使用的表达式结果为null，则输出该默认值 </c:out> 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"%> Title <% 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} </c:forEach> 0x63 根据参数请求显示不同的页面​ 通过JSTL标签库中的<c:if>标签可以根据不同的条件去处理不同的业务。本任务要求应用<c:if>标签实现根据参数请求显示不同页面的功能。具体要求如下。​ 当请求参数为“mon”时，页面显示“周一了，工作的第一天”；当请求参数为“tues”时，页面显示“周二了，工作的第二天”；当请求参数为“wed”时，页面显示“周三了，工作的第三天”；当请求参数为“thu”时，页面显示“周四了，工作的第四天”；当请求参数为“fri”时，页面显示“周五了，工作的第五天”；当请求参数为“sat”时，页面显示“周六了，休息的第一天”；当请求参数为“sun”时，页面显示“周日了，休息的第二天”。2023年6月21日00:45:27睡觉啦。如果之前的你有看，这里就超简单啦。效果如下：代码如下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" %> 每周计划 <% 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> <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> 0x70 按照model2实现注册功能0x701 JAVA BeanJavaBean通常具有如下特点：提供一个默认的无参构造函数。需要被序列化并且实现了 Serializable 接口。可能有一系列可读写属性，并且一般是 private 的。可能有一系列的 getter 或 setter 方法。0x702 还记的这个CAKE吗文件位置:\java3_jsp\src\main\java\net\dabbit\entity\Cake.javapackage 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; } } 因为原先就差不多啦，所以看起来差距不大。但是这里引用了序列化的接口，注意下哦。0x71 新建User的Beanpackage net.dabbit.beans.Userpackage 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; } } 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" %> Login 登录页面 用户名： 密码： 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" %> Result <% 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("请通过正确的方式访问该页面！"); } %> 返回 效果：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" %> 孙橙子 <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="橙子" /> 姓名：<jsp:getProperty name="student" property="name" /> 年龄：<jsp:getProperty name="student" property="age" /> 性别：<jsp:getProperty name="student" property="sex" /> 0x74 BOOK信息填写net.dabbit.beans.Bookpackage 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" %> Title 添加图书信息 名称： 价格： 作者： 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" %> Title <% request.setCharacterEncoding("UTF-8"); %> <jsp:useBean id="book" class="net.dabbit.beans.Book" scope="page" /> <jsp:setProperty name="book" property="*" /> 名称：<jsp:getProperty property="bookName" name="book" /> 价格：<jsp:getProperty property="price" name="book" /> 作者：<jsp:getProperty property="author" name="book" /> 0x75 Model1 和 Model20x751 Model10x752 Model2MVC = 模型（Model) 视图（VIEW) 控制器（controller）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 先写Bean0x7621 UserBeanpublic 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 RegisterFormBeanpackage 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 DBUtilpackage 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; } }尝试编译下，通过了就行0x763 ServletControllerServletpackage 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" %> 注册 用户注册 姓名: ${registerForm.errors.name} 密码: ${registerForm.errors.password} 确认密码: ${registerForm.errors.password2} 邮箱: ${registerForm.errors.email} 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" %> Title 恭喜你，登录成功 您的信息 您的姓名：${userBean.name} 您的邮箱：${userBean.email} 0x765 中文用户名乱码这样写会导致中文乱码新建个类导入这些内容net.dabbit.configs.CharactorEncodingpackage 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);效果如下0x77 乌拉估计这样就算是完成了，其实也没有那么难啦。写的也比较仓促，有很多地方写的不是很完善，需要补充，不管你在哪里卡住了，请直接叫咱。如果你真的明白了这些内容，期末作业也超级好写啦。0xFF 文件下载吐了，过程文件丢失了一些JAVA这个目录管理真的有毒这些文件是过程中保存的，做到哪个章节保存到哪。如果你发现文件下载失败，请直接重新下载即可。0x63 https://p.dabbit.net/blog/pic_bed/2023/06/182f97a4a9686a9e_202306210959969.rar0x72 https://p.dabbit.net/blog/pic_bed/2023/06/bcdd6b8ddd3ae723_202306211039020.zip0x73 https://p.dabbit.net/blog/pic_bed/2023/06/fff8655b22489efe_202306211050782.zip0x74 https://p.dabbit.net/blog/pic_bed/2023/06/64c79acd79e952ac_202306211138924.zip0x764 https://p.dabbit.net/blog/pic_bed/0x764_java3_jsp.zip0x765https://p.dabbit.net/blog/pic_bed/0x765_java3_jsp_2f0f778d-5183-46a1-a197-89745650570d.zip0x242 从0x765进行修改的：删掉一些没用的文件即可，配置是一样哒。https://p.dabbit.net/blog/pic_bed/0x242_java3_jsp_2f0f778d-5183-46a1-a197-89745650570d.7z0x11 HTML、CSS下载：https://p.dabbit.net/blog/pic_bed/2023/05/a77f2e125a83aee1_202305261907278.7z0x21 Tomcat 下载：https://p.dabbit.net/blog/pic_bed/2023/05/2382cd17a1cf1632_202305262111014.zip0x23 JDK1.8 https://p.dabbit.net/blog/pic_bed/jdk1.8.0_361_ad874039-ce6d-497a-95d6-d3b0803.7z0x35 文件下载：https://p.dabbit.net/blog/pic_bed/2023/06/9c76394a5a75ad2b_202306200107974.zip0x11 文件下载：https://p.dabbit.net/blog/pic_bed/2023/05/a77f2e125a83aee1_202305261907278.7z这里是虚假的文件，（压缩错目录位置了，我就说文件hash怎么都一样）（要命，快哭了都是一样的）为啥不删，（舍不得删0x54 https://p.dabbit.net/blog/pic_bed/2023/06/ca30c176745d7387_202306202305059.rar0x554 https://p.dabbit.net/blog/pic_bed/2023/06/ca30c176745d7387_202306202324631.rar0x624 https://p.dabbit.net/blog/pic_bed/2023/06/ca30c176745d7387_202306210044857.rar0x63 https://p.dabbit.net/blog/pic_bed/2023/06/ca30c176745d7387_202306210950082.rar好嘞，这样就算是完成了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 打开文件0x10 第 1部分：配置设备并 验证连通性0x11 步骤 1：配置 PC 接口。a. 使用地址分配 表中列出的 PC3 IPv4 和 IPv6 地址。b. 使用地址分配 表中列出的 PC4 IPv4 和 IPv6 地址。PC310.0.4.10 255.255.255.0 10.0.4.1 2001:db8:acad:4::10 /64 fe80::2:aPC410.0.5.10 255.255.255.0 10.0.5.1 2001:db8:acad:5::10 /64 fe80::2:b0x12 步骤 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::10Q.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::1R2执行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#问题：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 = 9msQ.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:\>Q.0x13.b.3 问题：ping 操作是否成功？答案：失败了，R2没有配置网关出口。c. 从 PC3 的命令行向 R2 G0/0/0 的 IPv4 地址发起 SSH 会话，并且使用SSHadmin和密码 55Hadm!n进行登录。C:\> ssh -l SSHadmin 10.0.4.1PC3执行：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#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]0x22 步骤 2：检索重要的硬件 和软件信息。R2User 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.binQ.0x22.a.2 路由器有多大非易失性随机访问内存 (NVRAM) ？32768K bytes of non-volatile configuration memory.所以是：32768K NVRAMQ.0x22.a.3 路由器的闪存有多大？闪存不是内存，闪存可以叫硬盘。3223551K bytes of flash memory at bootflash:.所以是：3223551Kshow命令往往会提供多屏的输出信息。 用户可通过过滤输出，显示某些部分的输出。要启用过滤命令，需要在 show命令后面 输入管道 (|) 符，然后输入一个过滤参数和一个过滤 表达式。您可以使用include 关键字将输出与过滤语句匹配，以显示输出中包含过滤 表达式的所有行。过滤show version 命令，使用show version | include register 回答以下问题。执行:R2#show version | include register Configuration register is 0x2102Q.0x22.b 下一次重新加载中 路由器的启动过程是怎样的？0x2102 对应二进制： 0010 0001 0000 0010 第1位（最左侧）：控制台忽略Break键，这里为0，因此控制台不会忽略Break键。 第3位：控制台忽略Break键，这里为1，表示控制台不会忽略Break键。 第16位（最右侧）：0 表示从ROM中加载，1 表示从闪存中加载系统.路由器启动过程：自检（POST）加载系统读取NVRAM的配置文件根据配置文件进行配置接口、协议、参数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/0C 10.0.4.0/24 is directly connected, GigabitEthernet0/0/0Q.0x24 路由表中有多少个路由条目以代码 C 标识？40x25 步骤 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 shutdownQ.0x25.a.2 您可以使用什么过滤命令让设备只显示 分配了地址的接口？show ip interface brief | exclude unassignedb. 使用命令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
手写压位高精度（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 准备文件文件下载：https://p.dabbit.net/blog/pic_bed/2023/05/153c17ec66e5b5c7_202305090819041.7z分步骤文件可以从文件末尾下载有时间一定要自己做一遍0x01 打开文件看了看，感觉..有点夸张的样子做完的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 地址子网掩码默认网关PC1NICDHCPDHCPDHCPPC2NICDHCPDHCPDHCPDNS 服务器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 相关内容暂无0x10 第 1 部分： 将路由器配置为 DHCP 服务器0x11 第 1 部分：步骤 1 ： 配置排除的 IPv4 地址。配置 R2 从 R1 LAN 和 R3 LAN 中排除前 10 个地址。 DHCP 地址池中的所有其他地址都应该可用。先看下网络拓扑图：要命R1 的 LAN 192.168.10.0/24R3 的 LAN 192.168.30.0/24这样前10个就是除去192.168.10.1-10192.168.30.1-10在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.100x12 第 1 部分：步骤 2 ： 在 R2 上为 R1 LAN 创建 DHCP 池。a. 创建命名为 R1-LAN 的 DHCP 池。这个池的名称必须匹配上面的值， 这样配置才能得分。b. 配置 DHCP 池以包括 DNS 服务器的网络地址、默认网关和 IP 地址。创建名字为R1-LAN的地址池子R2(config)#ip dhcp pool R1-LAN配置网段，默认网关，DNSDNS服务器：192.168.20.254默认路由：192.168.10.1（也就是R1的地址）子网掩码前缀：24，对应255.255.255.0R2(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.2540x13 第 1 部分：步骤 3 ： 在 R2 上为 R3 LAN 创建 DHCP 池。a. 创建命名为 R3-LAN (区分大小写) 的 DHCP 池。b. 配置 DHCP 池以包括 DNS 服务器的网络地址、默认网关和 IP 地址。同理啦创建地址池R3-LANR2(config)#ip dhcp pool R3-LAN #或者↓这样直接输就行 R2(dhcp-config)#ip dhcp pool R3-LAN # ↓复制用，但是建议手打哦 ip dhcp pool R3-LAN 配置网段，默认网关，DNSDNS服务器：192.168.20.254默认路由：192.168.30.1（也就是R3的地址）子网掩码前缀：24，对应255.255.255.0R2(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目前咱35的进度0x20 第 2 部分： 配置 DHCP 中继0x21 第 2 部分：步骤 1 ： 将 R1 和 R3 配置为 DHCP 中继代理。先看下地址表：设备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不适用可以发现，R2的在两个路由器之间的IP分别是10.1.1.2 (与R1)10.2.2.2 (与R3)设置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设置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进度640x22 第 2 部分：步骤 2 ： 设置 PC1 和 PC2 从 DHCP 接收 IP 编址信息。这个就是纯手点一下就可以PC1如果正确获得了IP，说明成功啦PC2也同理啦0x30 第 3 部分： 配置 R2 作为 DHCP 客户端0x31 第 3 部分： 配置 R2 上的千兆以太网 G0/1 接口从 DHCP 接收 IP 编址。这个机翻无力吐槽了去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 dhcp0x32 第 3 部分：激活接口。我觉得这一步跟上一步一起做完比较好R2(config-if)#int g0/1 R2(config-if)#no shut # ↓复制用，但是建议手打哦 int g0/1 no shut完成0x40 文件下载作业10_分步骤文件.7z（文件大小：7Mb)下载地址1（HKserver）https://pic.icee.top/blog/pic_bed/%E4%BD%9C%E4%B8%9A10_%E5%88%86%E6%AD%A5%E9%AA%A4%E6%96%87%E4%BB%B6.7z下载地址2（CF）https://p.dabbit.net/blog/pic_bed/%E4%BD%9C%E4%B8%9A10_%E5%88%86%E6%AD%A5%E9%AA%A4%E6%96%87%E4%BB%B6.7z