第二次作业
一:项目原理:
JavaWeb项目使用Java语言编写,Java是一种跨平台的编程语言,可以在不同的操作系统和硬件平台上运行。JavaWeb项目通常采用Servlet容器作为服务器端运行环境,如Tomcat、Jetty等。Servlet容器负责加载和执行Servlet,处理HTTP请求和响应。
JavaWeb项目中的Servlet通常继承自HttpServlet类,HttpServlet类提供了一些方法,如doGet()和doPost(),用于处理HTTP请求。Servlet还可以使用Java的EJB(Enterprise JavaBeans)技术来实现业务逻辑。JavaWeb项目中的JSP页面实质上是一个Servlet,它在服务器端运行,可以动态生成HTML页面。JSP页面可以嵌入Java代码、表达式和脚本元素,从而能够根据不同的请求生成不同的页面内容。JavaWeb项目通常使用JDBC(Java Database Connectivity)技术来访问关系型数据库。JDBC是Java中用于访问数据库的标准API,它提供了一种连接数据库、执行SQL语句并获取结果的方法。JavaWeb项目通常使用JavaBean来封装数据和处理业务逻辑。JavaBean是一个遵循特定命名规则的Java类,它包含了一些属性和方法,可以用于存储数据、处理业务逻辑并与Servlet进行交互。JavaWeb项目通常使用一些开源框架来简化开发过程,如Spring、Struts、Hibernate等。Spring是一个轻量级的开源框架,它提供了IoC(Inversion of Control)容器和AOP(Aspect-Oriented Programming)功能,用于实现依赖注入、事务管理、安全性等。Struts是一个基于MVC架构的开源框架,它提供了丰富的组件和工具,用于构建Web应用程序。Hibernate是一个ORM(Object-Relational Mapping)框架,它可以将对象模型映射到关系型数据库中,简化了数据访问层的开发。
1.基本的思路

前后端交互原理:前后端通过HTTP协议进行通信。HTTP是一种应用层协议,用于在网络中传输数据。前端使用HTTP请求向服务器发送数据,服务器处理请求后返回响应数据给前端。前端请求参数的形式主要是GET和POST两种方式。GET一般从指定的服务器中获取数POST一般提交数据给指定的服务器处理。
前端应该告知后台那些有效信息,后台才能返回前端想要的数据。先将要展示的内容进行确定,再告知后台相关参数和数据格式等,最后等待并处理后端返回的结果。
二:使用技术栈:
后端:Java Servlet,JSP,JavaBeans,JDBC
前端:HTML,CSS,JavaScript,JQuery
数据库:MySQL实现登录和计算器的运算以及将操作人员及计算的数据记录下来
1.前端界面的实现:



2.使用AJAX(Asynchronous JavaScript and XML)请求来实现异步通信,从而提高用户体验和性能。AJAX允许在不需要重新加载整个页面的情况下,通过XMLHttpRequest对象发送请求并获取服务器响应。
结果如图:


3.登录的流程图:

三:计算器的功能实现:





计算器代码:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Stack;
import javafx.scene.text.Text;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.lang.String;
public class MyCalculator
{
//建立需要的各种组件
String input = "";//显示在文本框中的字符串
Frame frame = new Frame("计算器");//整体的窗口
Button[] button = new Button[23];//需要的按钮
TextField textField = new TextField(15);//文本框
String[] name = {"sqrt","1/x","%","C","Del","7","8","9","+","-","4","5","6","*","/","1","2","3","(",")","0",".","="};//按钮的名称
Panel p1 = new Panel();//装载文本域的容器
Panel p2 = new Panel();//装载按钮的容器
public int getValue(String operation) {
int result = 0;
switch (operation) {
case "+":
result = 1;
break;
case "-":
result = 1;
break;
case "*":
result = 2;
break;
case "/":
result = 2;
break;
case "%":
result = 2;
break;
default:
break;
}
return result;
}
public boolean isOperator(String op){
return op.equals("+")||op.equals("-")||op.equals("*")||op.equals("/")||op.equals("%")||op.equals("(")||op.equals(")")||op.equals("sqrt")||op.equals("1/x");
}
public Double caculation(Double num1, Double num2, String op){
switch(op){
case "+":
return num2 + num1;
case "-":
return num2 - num1;
case "*":
return num2 * num1;
case "/":
return num2 / num1;
case "%":
return num2 % num1;
default:
return 0.0;
}
}
public String sqrt(String input){
String str[] = input.split(" ");
String r ="";
Double t = Math.sqrt(Double.parseDouble(str[str.length-1]));
if(str.length > 1){
r += str[0];
}
if(str.length == 1)
{
return t.toString();
}
for(int i =1 ;i<str.length-1;i++){
r += " "+str[i];
}
r +=" "+ t.toString();
return r;
}
public String reversal(String input){
String str[] = input.split(" ");
String r ="";
Double t = 1 / Double.parseDouble(str[str.length-1]);
if(str.length > 1){
r += str[0];
}
if(str.length == 1)
{
return t.toString();
}
for(int i =1 ;i<str.length-1;i++){
r += " "+str[i];
}
r +=" "+ t.toString();
return r;
}
public static String parseSuffixExpression(String ls){
MyCalculator m = new MyCalculator();
String str[] = ls.split(" ");
Stack<String> s1 = new Stack<>();
String s2 = ""; // 储存中间结果的Lists2
//遍历传入的ls
for (String item : str) {
System.out.println(item);
if (!m.isOperator(item)){
s2 += " "+item;
} else if (item.equals("(")) {
s1.push(item);
} else if (item.equals(")")) {
//如果是右括号“)”,则依次弹出s1栈顶的运算符,并压入s2,直到遇到左括号为止,此时将这一对括号丢弃
while(!s1.peek().equals("(")) {
s2 +=" "+s1.pop();
}
s1.pop();//!!! 将 ( 弹出 s1栈, 消除小括号
}else if(item.equals("sqrt")||item.equals("1/x")){
s2 += " "+item;
}
else {
//当item的优先级小于或者等于 s1 栈顶的运算符
// 将s1栈顶的运算符弹出并加入到s2中,再次转到(4.1)与s1中新的栈顶运算符相比较
//编写一个Operate类,再编写getValue方法来获取当前运算符的优先级
while (s1.size() != 0 && m.getValue(s1.peek()) >=m.getValue(item)){
//把s1中的运算符加入s2,直到,item的优先级大于s1栈顶的运算符,退出循环,并且将item压入s1
s2 += " "+s1.pop();
}
//还需要将item压入栈
s1.push(item);
}
}
//将s1中剩余的运算符依次弹出并加入s2
while(s1.size() != 0) {
s2 += " "+s1.pop();
}
return s2; //注意因为是存放到List, 因此按顺序输出就是对应的后缀表达式对应的List
}
//用栈来实现后缀表达式的计算
public Double compute(String input){
MyCalculator m = new MyCalculator();
String str[] = input.split(" ");
Stack<Double> s = new Stack<Double>();
for(int i=0;i<str.length;i++)
{
if(!m.isOperator(str[i]) ){
s.push(Double.parseDouble(str[i]));
}
else{
Double result = m.caculation(s.pop(), s.pop(), str[i]);
s.push(result);
}
}
return s.pop();
}
public void init()
{
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
{
System.exit(0);
}
});
//为Panel容器添加视图,并设置好布局键盘布局
textField.setFont(new Font("宋体",Font.PLAIN,50));//设置字体格式
textField.setEditable(false);
//将文本域添加到p1容器中
p1.add(textField);
//设置按钮容器的布局
p2.setLayout(new GridLayout(5,5,5,5));
//为每个button命名
for(int i=0; i<23; i++)
{
button[i] = new Button(name[i]);
}
//设置按钮点击后的监听器
ActionListener listener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
String buttonname = e.getActionCommand();
input += buttonname;
if(buttonname.equals("+")||buttonname.equals("-")||buttonname.equals("*")||buttonname.equals("/")||buttonname.equals("(")||buttonname.equals(")")||buttonname.equals("%"))
{
input = input.substring(0, input.length() - 1); //将这些符号去掉
if(buttonname == "("){
input += buttonname+" ";
}else if(buttonname == ")"){
input +=" "+buttonname;
}else if(buttonname == "1/x"){
input = input.substring(0, input.length() - 2);
input +=" "+buttonname;
}
else{
input += " "+buttonname +" "; //在数字后加空格再加符号再加空格,为了将符号在str中单独占一格
}
}
if(buttonname.equals("sqrt")){
input = input.substring(0,input.length()-4);
input = sqrt(input);
textField.setText("");
textField.setText(input);
}
if(buttonname.equals("1/x")){
input = input.substring(0,input.length()-3);
input = reversal(input);
textField.setText("");
textField.setText(input);
}
//点击等于号的后的行为
if(buttonname.equals("="))
{
input = input.substring(0, input.length() - 1);
input = parseSuffixExpression(input);
String str="";
for(int i =1;i<input.length();i++){
str += input.charAt(i);
}
input = compute(str).toString();
textField.setText(input); //输出计算结果
}
//点击清除键后的行为
if(buttonname.equals("C"))
{
input = "";
}
//点击退格键后的行为
if(buttonname.equals("Del"))
{
input = input.substring(0, input.length() - 3); //先将输入的"Del"删去
if(input.endsWith(" ")) //如果input的后面跟的是" ",则input最后的输入是一个计算符号,删去符号和用以区分数字符号的" "
input = input.substring(0,input.length() - 3);
else if(input.endsWith("t")){
input = input.substring(0,input.length() - 5);
}
else if(input.endsWith("x")){
input = input.substring(0,input.length() - 4);
}
else //删去一个数字
input = input.substring(0, input.length() - 1);
}
//得到结果后如果再点击其他键,就执行清除
textField.setText(input);
}
};
//将监听器装到每个按钮上
for(int x = 0;x<23;x++)
{
button[x].addActionListener(listener);
}
//将按钮装到p2容器中,注意装完监听器后再将按钮装到容器中
for(int x = 0;x<23;x++)
{
p2.add(button[x]);
}
//组装容器到窗口上
frame.add(p1,BorderLayout.NORTH);
frame.add(p2);
//设置frame窗口大小并设置可见
frame.setBounds(200,200,500,500);
frame.setVisible(true);
}
//主函数
public static void main(String[] args)
{
new MyCalculator().init();
}
}
四:使用jdbc作为桥梁连接数据库:
1.注册驱动:(反射)2.创建连接3创建数据库对象4获取结果集合(迭代)







五:数据库端的数据记录


浙公网安备 33010602011771号