一、实验目的
(1)掌握java web开发环境的搭建
(2)掌握java web项目的创建、发布和运行
(3)理解MVC的开发模式
(4)掌握基础的多角色系统设计与实现
二、实验要求
(1)实现不同类型用户的注册与登陆(在实验四的基础上将医生与病人作为系统用户),使用Servlet+JSP+JDBC或者其他框架技术,并设计相应的mysql数据库。
(2)用户登录成功之后进入主页,把用户的用户名存入session并显示在页面上。
(3)提前设置好一些科室,医生可以维护自己所属科室信息。
(4)病人登陆跳转至挂号页显示自己的挂号记录,并可以选择科室进行挂号。
(5)当病人提交挂号信息,按不同时间段计算并记录挂号费。
(6)医生登陆跳转至记录页显示自己所在科室的挂号记录,并可以根据不同维度对挂号记录进行筛选。
三、具体实验操作
首先请下载本次实验六所需的文件
通过网盘分享的文件:实验六所需.zip
(内含Tomcat10,一个jar文件,和一个txt文本)
链接: https://pan.baidu.com/s/1ccfOHSxPC212cjGiEliMnQ?pwd=knag 提取码: knag
让我们来从头来看本次实验到底需要哪些步骤才能精准完成
1.Java本身实验环境
Idea这玩意你该有吧 Navicat数据库很关键 服务器是tomcat的
我建议先把java升级了,我中间反正被1.8绊了一跤,换了22.0
并且Tomcat也需要升级,代码这玩意真是稍微过一年就会有新的更简洁的出现
Tomcat需要在10版本以上才能让servlet脱离web.xml文件实现action映射
2.第一步,新建项目
你真的知道你要建的是什么项目吗??????
还在傻傻的建java项目吗孩子
这样你就会失去
这两个一个是配置基础,一个是servlet亲爹和jstl亲妈(虽然高版本不再需要改web.xml文件了)
甚至在我的文件里其实已经抛弃jstl(因为版本过高,jstl跟不上了)sd
(1)建立Jakarta EE项目
第二个界面先把版本改为最高的Jakarata EE 10 ,然后单击创建
创建后注意右下角
记得加载Maven项目!!!!!
加载后你就不用再自己去导入servlet包
注意,mysql-connector-java 包并不包含在maven依赖项里,需要添加代码用来协助构建
创建中。。。。。。。。。。。。。。。。创建完毕!
这里是你的文件结构
(2)初始化文件内容
java下面是你的java代码,里面存放的是Model(对象),Dao(对象与数据库交互操作)和Servlet(处理请求和产生反馈)
WEB-INF里面需要新建一个文件夹lib存放jstl.jar和standard.jar(需要下载)(同样在开头的网盘文件夹里面可以找到)
Webapp里面存放css和html文件
(如今html比jsp使用的更多更广了,所以建议使用html文件构建网站)
//css等文件夹是后期自己创建的
(3)配置你的服务器
先点修复,部署工件
这个上下文是你的url中很重要的一部分,不要随便修改!
(或者你想直接搬运哥们的代码,那你就需要改上下文为—— /demo)
到时候你的网址大概是
http://(固定)localhost:8080/(同样固定)demo1_war/(上下文)+servlet或者html
http://localhost:8080/test6_war/http://localhost:8080/test6_war/如这样。
同样应用+确定
我可以这么说,这一步之后你基本就不用再配置什么东西了,只剩下难题就是编程了
#整个流程如视频所示
创建
(4)完善依赖文件
在pom.xml文件中,插入如下代码
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.23</version>
</dependency>
每次修改pom.xml文件后,右上角会出现如下图标
一定要点击,这样idea就会更新maven依赖,这样才不会缺失驱动文件
3.编写整个前后端程序
首先让我们了解整个实验的流程
(1)将后端基础编好——数据库配置和Model以及Dao等
首先编辑数据库信息
然后根据数据库的列名来编写类的属性
最后编写Dao
注意!Dao的编写一定是与具体实验操作挂钩,所以建议边走边编,这样能减少修改
Dept(科室类)
package Model;
public class Dept {
public Integer id;
public String name;
public String des;
public Dept(Integer id, String name, String des) {
this.id = id;
this.name = name;
this.des = des;
}
public Integer getId() {
return id;
}
public Dept(Integer id) {
this.id = id;
}
public Dept() {
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
}
Doc(医生类)
package Model;
public class Doc {
public Integer id;
public String name;
public String password;
public Integer roomId;
public String sex;
public String phone;
public String email;
public String detail;
public Doc(Integer id, String name, String password, Integer roomId, String sex, String phone, String email, String detail) {
this.id = id;
this.name = name;
this.password = password;
this.roomId = roomId;
this.sex = sex;
this.phone = phone;
this.email = email;
this.detail = detail;
}
public Doc() {
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public Doc(Integer id, String name, String password, Integer roomId) {
this.id = id;
this.name = name;
this.password = password;
this.roomId = roomId;
}
public Doc(Integer id, String name, String password, Integer roomId, String sex) {
this.id = id;
this.name = name;
this.password = password;
this.roomId = roomId;
this.sex = sex;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Doc(Integer id, String password) {
this.id = id;
this.password = password;
}
public Doc(Integer id, Integer roomId) {
this.id = id;
this.roomId = roomId;
}
public Doc(Integer id, String name, Integer roomId) {
this.id = id;
this.name = name;
this.roomId = roomId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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 Integer getRoomId() {
return roomId;
}
public void setRoomId(Integer roomId) {
this.roomId = roomId;
}
}
Pat(病人类)
package Model;
public class Pat {
public Integer id;
public String name;
public String password;
public String sex;
public Integer roomId;
public String feel;
public String phone;
public String email;
public Pat(Integer id, String name, String password, String sex, Integer roomId, String feel) {
this.id = id;
this.name = name;
this.password = password;
this.sex = sex;
this.roomId = roomId;
this.feel = feel;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Pat(Integer id, String name, String password, String sex, String phone, String email) {
this.id = id;
this.name = name;
this.password = password;
this.sex = sex;
this.phone = phone;
this.email = email;
}
public Pat(Integer id, String password) {
this.id = id;
this.password = password;
}
public String getFeel() {
return feel;
}
public void setFeel(String feel) {
this.feel = feel;
}
public Pat(Integer id, String name, String password, Integer roomId, String sex) {
this.id = id;
this.name = name;
this.password = password;
this.roomId = roomId;
this.sex = sex;
}
public Pat(Integer id, String name, Integer roomId) {
this.id = id;
this.name = name;
this.roomId = roomId;
}
public Pat(Integer id, String name, Integer roomId, String sex, String feel) {
this.id = id;
this.name = name;
this.roomId = roomId;
this.sex = sex;
this.feel = feel;
}
public Pat() {
}
public Pat(Integer id) {
this.id = id;
}
public Pat(Integer id, String name, String password, String sex) {
this.id = id;
this.name = name;
this.password = password;
this.sex = sex;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
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 Integer getRoomId() {
return roomId;
}
public void setRoomId(Integer roomId) {
this.roomId = roomId;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String tostring(){
return "病人id=" +getId() + "病人姓名为" + getName() + "病人性别为" + getSex() + "病人症状为" +getFeel();
}
}
Record(病例类)
package Model;
import java.math.BigDecimal;
public class Record {
public Integer id;
public Integer docid;
public Integer patid;
public Integer roomid;
public String date;
public BigDecimal money;
public String feel;
public String condition;
public Record(Integer id, Integer docid, Integer patid, Integer roomid, String date, BigDecimal money, String feel, String condition) {
this.id = id;
this.docid = docid;
this.patid = patid;
this.roomid = roomid;
this.date = date;
this.money = money;
this.feel = feel;
this.condition = condition;
}
public Record(Integer id, Integer docid, String condition) {
this.id = id;
this.docid = docid;
this.condition = condition;
}
public Record(Integer id, Integer patid, Integer roomid, String date, BigDecimal money, String feel, String condition) {
this.id = id;
this.patid = patid;
this.roomid = roomid;
this.date = date;
this.money = money;
this.feel = feel;
this.condition = condition;
}
public Record(Integer roomid) {
this.roomid = roomid;
}
public Record() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getDocid() {
return docid;
}
public void setDocid(Integer docid) {
this.docid = docid;
}
public Integer getPatid() {
return patid;
}
public void setPatid(Integer patid) {
this.patid = patid;
}
public Integer getRoomid() {
return roomid;
}
public void setRoomid(Integer roomid) {
this.roomid = roomid;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public BigDecimal getMoney() {
return money;
}
public void setMoney(BigDecimal money) {
this.money = money;
}
public String getFeel() {
return feel;
}
public void setFeel(String feel) {
this.feel = feel;
}
public String getCondition() {
return condition;
}
public void setCondition(String condition) {
this.condition = condition;
}
}
(2)通过编写前端,来进行相应的Dao以及Servlet编写
作为一个小主机,而不是一个服务器,我们的网站数据,比如病房信息,医生信息,这些我们需要自己去填充,这些可以选择直接在数据库里添加,不过也可以用java代码在运行网站时同步进行。我们来尝试一下。
这是首页的样子,我设计了一个按钮
事实上这个按钮不仅仅是让你进入官网的按钮,让我们来看看这个按钮背后是什么。
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>校医院官网入口</title>
<style>
body {
background-size:cover;
background-image: url("image/1.png");
}
</style>
<style>
body {
background-color: #f0f0f0; /* 柔和的背景颜色 */
display: flex;
justify-content: center; /* 水平居中 */
align-items: center; /* 垂直居中 */
height: 100vh; /* 充满视口的高度 */
margin: 0; /* 移除默认边距 */
font-family: Arial, sans-serif; /* 设置字体 */
}
form#no {
display: inline-block; /* 内联块级元素 */
}
input[type="submit"] {
background-color: #0056b3; /* 鲜艳的蓝色背景 */
color: white; /* 按钮文字颜色 */
padding: 20px 40px; /* 增加内边距 */
border: none; /* 无边框 */
border-radius: 25px; /* 圆形边缘 */
cursor: pointer; /* 指针光标 */
font-size: 18px; /* 较大字体大小 */
transition: all 0.3s ease; /* 平滑过渡效果 */
box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1); /* 轻微的阴影 */
position: relative; /* 相对定位 */
overflow: hidden; /* 隐藏溢出的内容 */
}
input[type="submit"]:hover {
background-color: #003d82; /* 悬停时更深的蓝色 */
}
input[type="submit"]:active {
background-color: #002955; /* 点击时的颜色 */
}
input[type="submit"]:before {
content: ''; /* 创建伪元素 */
position: absolute;
top: 50%;
left: 50%;
width: 300%; /* 宽度 */
height: 100%; /* 高度 */
background: rgba(255, 255, 255, 0.3); /* 白色半透明背景 */
transition: all 0.3s; /* 过渡效果 */
transform: translate(-50%, -50%) skewX(20deg); /* 定位和倾斜 */
opacity: 0; /* 默认不显示 */
}
input[type="submit"]:hover:before {
opacity: 1; /* 悬停时显示 */
}
</style>
</head>
<body>
<form id="no" action="http://localhost:8080/demo1/SetServlet" method="post">
<input type="submit" value="点击进入校医院官网">
</form>
</body>
</html>
这段代码
<form id="no" action="http://localhost:8080/demo1/SetServlet" method="post">
<input type="submit" value="点击进入校医院官网">
</form>
代表,你点击按钮后,你其实并没有进入官网,而是进入了一个叫SetServlet的的东西
而这个就是我们很需要掌握的东西——servlet
Servlet 是什么?
Java Servlet 是运行在 Web 服务器或应用服务器上的程序,它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
可以理解为,总体就是
网站提交——servlet处理——跳转新的网站
观察SetServlet
package Servlet;
import Dao.DeptDao;
import Dao.DocDao;
import jakarta.servlet.RequestDispatcher;
import jakarta.servlet.ServletException;
import jakarta.servlet.annotation.WebServlet;
import jakarta.servlet.http.HttpServlet;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
@WebServlet("/SetServlet")
public class SetServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.printf("doget");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
DeptDao.deleteAll();
DeptDao.setDept();
DocDao.deleteAll();
DocDao.setDoc();
RequestDispatcher dispatcher = request.getRequestDispatcher("/index.html");
dispatcher.forward(request, response);
}
}
在doPost里,我们执行了四个函数,从名字看出,就是清除了目前数据库里的科室、医生数据,再重新初始化了他们,具体数据不重要,重点在于之后的代码。
RequestDispatcher dispatcher = request.getRequestDispatcher("/index.html");
dispatcher.forward(request, response);
RequestDispatcher dispatcher = request.getRequestDispatcher("/index.html");
- 这行代码获取一个
RequestDispatcher
对象。RequestDispatcher
是一个接口,用于将请求转发到另一个资源(如JSP、servlet或HTML文件)。request
是一个HttpServletRequest
对象,代表客户端的请求。getServletContext().getRequestDispatcher()
方法用于获取RequestDispatcher
对象。这个方法接受一个路径参数,这里是"/index.html"
,表示要转发到的资源路径。- 通常,这个路径是相对于当前应用的根目录的。
dispatcher.forward(request, response);
- 这行代码使用
RequestDispatcher
对象的forward()
方法来执行请求的转发。forward()
方法接受两个参数:request
和response
。request
是HttpServletRequest
对象,包含了客户端发送的所有请求信息。response
是HttpServletResponse
对象,用于向客户端发送响应。- 调用
forward()
方法后,请求和响应对象会被传递到指定的资源(在这个例子中是/index.html
),而客户端不会意识到这个转发过程。对于客户端来说,它就像是直接请求了/index.html
。总结来说,这段代码的作用是将当前请求转发到应用中的
/index.html
资源,而不改变浏览器的URL,客户端用户不会感觉到这个转发过程。这通常用于实现MVC(Model-View-Controller)模式中的控制器逻辑,控制器决定展示哪个视图给用户。
所以这样就能做到用户每次输入东西,我们能在响应操作更新数据库的同时让用户跳转新的界面,运用这个逻辑,整个项目就像盖房子一样,盖一层,叠一层,再盖一层。
(3)运行的必要操作,url传参以及session保存数据
【1】url传参
首先我们来看一个我们很常见的东西
假如我在b站搜索a
那么注意上方的网站链接,其中有一个ketword=a;这就是两个html文件之间传递数据的一种方法,叫使用URL参数。
通过URL参数传递数据,然后在第二个页面中使用JavaScript解析这些参数。
看在本次实验中的应用
我们在servlet中查询到医生姓名后,通过url传递给我们跳转的html文件
然后在html文件中使用JavaScript解析 ,这样就能做到传参了
【2】session保存数据
我们知道,假如你在b站首页登录过,那么无论你进入b站的哪个视频,他都能知道你是哪个用户。
这代表每次的servlet里都是通过你登录的ID进行的对应的查询,但是servlet是通过html中的表得到值的,我们希望在整个用户操作流程中,html表单不用一直靠用户在表单中输入id,项目一直都知道用户是谁——随时能get他的id
这就需要session来做了
在Web开发中,
session
(会话)是一个非常重要的概念,它用于在用户与服务器之间的多个页面请求或访问之间维持状态。以下是session
的几个关键点:
状态保持:
session
允许服务器跟踪用户的状态。当用户在网站上浏览时,他们可能会在不同的页面之间跳转,session
使得服务器能够在这些页面之间保持用户的状态信息。数据存储:
session
可以在服务器端存储用户特定的信息,如用户的登录状态、购物车内容、用户偏好设置等。这些信息通常存储在服务器的内存中,也可以存储在数据库或文件系统中。唯一标识:每个用户会话都有一个唯一的标识符(通常是一个会话ID),用于区分不同的用户会话。这个ID在用户与服务器交互时被传递,以便服务器能够识别并关联用户的会话数据。
Cookie使用:在大多数Web应用中,
session
ID是通过Cookie传递给客户端浏览器的。当用户发起请求时,浏览器会发送这个Cookie,服务器通过这个Cookie中的会话ID来检索用户的会话数据。安全性:
session
可以提供一定程度的安全性,因为用户的状态信息存储在服务器端,而不是客户端。但是,session
数据也可能成为攻击的目标,因此需要采取措施来保护会话ID和会话数据,例如使用HTTPS来加密传输的会话ID。会话超时:
session
通常会有一个超时机制,如果用户在一段时间内没有活动,会话将自动结束,这有助于释放服务器资源并减少潜在的安全风险。跨会话持久化:在某些情况下,即使会话结束,也需要持久化用户的数据。这可以通过将数据存储在数据库或文件系统中来实现,即使会话ID失效,用户的数据也可以在后续的会话中被检索。
在不同的编程框架和平台中,
session
的实现和管理方式可能会有所不同,但基本原理是相似的。在Java Servlet中,HttpSession
接口提供了管理会话的方法,而在PHP中,session_start()
和$_SESSION
超全局变量用于处理会话。在其他框架和语言中也有类似的机制。
直接看实例。
“医生”身份的用户登录后,我们将用户输入的ID以及Password一同提交表单给到DocLoginServlet
在DocLoginServlet里,我们执行一定的查询工作,查询用户输入的ID是否存在,如果存在密码是否对应这样。
import Dao.*;
import Model.*;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
@WebServlet("/DocLoginServlet")
public class DocLoginServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.printf("doget");
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html");
String id = request.getParameter("id");//获取之前表单里的id
String password = request.getParameter("password");//密码获取之前表单里的密码
int ID;
ID = Integer.parseInt(id);//获取的均为String类型,转化为int
Doc Doc1 = new Doc(ID, password);//new一个对象
int roomid=DocDao.selectRoomId(Doc1);//在数据库中查找医生负责的科室号
HttpSession session = request.getSession(true);//Session操作
session.setAttribute("DocID", ID);
//当执行这行代码时,ID的值将被存储在会话中,并与键"DocID"关联。之后,可以在应用程序的任何地方使用session.getAttribute("DocID")来检索这个值,前提是它在会话的生命周期内。//
session.setAttribute("DocPassword",password);//同理
session.setAttribute("RoomID",roomid);//同理
if (DocDao.selectExist(Doc1)) {//如果这个医生确实存在
String encodedName="null";
String name=DocDao.selectName(Doc1);//查找医生的姓名
if(name!=null){
encodedName = URLEncoder.encode(name, StandardCharsets.UTF_8);
}
response.sendRedirect("/demo/DocHome.html?name="+encodedName");
}else {
response.sendRedirect("/demo/error.html");
}
}
}
重点在于我们将ID,设置给了一个键——“DocID”。这样我们在下一个servle里,比如修改密码
DocPasswordChangeServlet
package Servlet;
import Dao.DocDao;
import Model.Doc;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.*;
import jakarta.servlet.annotation.*;
import java.io.IOException;
@WebServlet("/DocPassWordChangeServlet")
public class DocPassWordChangeServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
String usedpassword=request.getParameter("usedpassword");
String nowpassword= request.getParameter("nowpassword");
HttpSession session=request.getSession(true);
Integer ID = (Integer) session.getAttribute("DocID");
Doc Doc=new Doc(ID,usedpassword);
if(DocDao.selectExist(Doc)){
session.setAttribute("DocPassword",nowpassword);
Doc Doc1 = new Doc(ID,nowpassword);
DocDao.updatekey(Doc1);
response.sendRedirect("Doc-while.html");
}else{
response.sendRedirect("error1.html");
}
}
}
我们在这里进行了DocID的获取,游离于代码,就像”末影箱“一样,在家放置,在外面取出
事实上session的使用还存在新旧的差别,比如这里的修改密码,我们就更新了DocPassword。
具体我相信在编程过程中是避免不了使用他的,一定要掌握。
4.整个程序流程展示
流程演示
四、实验心得
如果非要说心得体会,我真的只能说一切的结果都是碰壁后反思得到的
我开头所讲的那些配置方法,是我在不停报错后才得到的结果,才知道应该怎么做不应该怎么做,也许前人栽树后人乘凉说的就是这个吧。
回顾整个实验,我好像很做了几周,光端午后就连续编了5天,只能说编程真不是一个简单的事情,何况我毫无web前段开发的经历,不说理解servlet,就算是网页的css文件以及
<xxx>里框的到底是什么意思也根本搞不懂,表单又是什么,为什么按钮是靠submit提交表单跳转servlet的,url又是什么,为什么我有时候爆404有时候爆500的错误,我真觉得一路就过来已经不知道栽了多少次跟头了。。。。。。
Servlet创建要加urlpartern,同时要在web.xml文件里增加他的位置(这个在最新的,也就是Tomcat10之后已经可以只靠映射找到servlet了,回想当初还是很痛心,因为一直出不来东西)
Jstl要先下载对应的两个jar文件放在新建的lib文件夹下
虽然最后因为版本问题抛弃了jstl,选择了AJAX+HTML
抛开服务器的搭建单独打开网页是不可能的
一定要用Tomcat而不是TomEE,
Tomcat使用本地而不是远程
Model模型里的类的命名一定要遵循一定格式,比如开头不要大写
否则构造函数里没有this关键字,我也不知道为什么这个会影响某些时候程序的运行
Session的构造在删除前会一直存在,记住创造新的之前要把旧的转移一下,或者要更新
注意患者用ID,医生的session就要换名字——DocID
列表没有值要多进行debug处理。
网页结构改代码后运行没动静要查看源代码,害怕没更新
基本就没有了吧。
Java学到现在,我才觉得自己真的很喜欢编程,希望后面还有机会不忘记这门手艺吧。
五、注意事项
如果想要偷懒的同学(找我要付费的直接项目文件夹),建议至少了解网站的图形分布方式——CSS文件的写法,至少改变网站的按钮位置、大小,背景图片这种,否则被发现一概不负责。
还有其实如果仔细看完了“三、具体实验操作“,我相信有心的同学一定能在自己的能力范围内至少完成实验的60%,如果没有,就要反思自己是不是上课没有听讲,或者实验四都有点蒙混过关了,那就这样吧,祝大家JAVA越学越好。