使用Java Servlets编写的简单账单分割应用程序
1. 简介
账单分割是一个常见的任务,但是对于分割的公平性和准确性要求较高。使用Java Servlets编写账单分割应用程序是一个很好的选择。Java Servlets是JavaEE技术中的一部分,是一种运行在服务器端的Java程序,可以接收和处理来自客户端的请求和响应。本文将介绍使用Java Servlets编写的简单账单分割应用程序的实现细节和使用方法。
2. 实现细节
2.1 项目结构
本项目的目录结构如下:
bill-splitter
├── src
│ ├── main
│ │ ├── java
│ │ │ ├── controllers
│ │ │ │ └── BillSplitterController.java
│ │ │ ├── models
│ │ │ │ ├── Bill.java
│ │ │ │ └── Person.java
│ │ │ └── views
│ │ │ ├── BillSplitterView.java
│ │ │ └── IndexView.java
│ │ └── webapp
│ │ ├── WEB-INF
│ │ │ └── web.xml
│ │ ├── css
│ │ │ └── styles.css
│ │ └── index.jsp
└── pom.xml
其中,BillSplitterController
是Java Servlets的控制器,负责接收和处理来自客户端的请求。对于本项目,控制器包含以下方法:
doGet()
: 处理GET请求,返回首页
doPost()
: 处理POST请求,计算账单分割结果并返回
Bill
和Person
是Java Bean,用来表示账单和账单中的人物。其中,Bill
包含以下属性:
totalAmount
: 总金额
tipAmount
: 小费金额
persons
: 账单中的人物
Person
包含以下属性:
name
: 姓名
amount
: 分摊金额
BillSplitterView
和IndexView
是Java类,用来渲染HTML模板。对于本项目,BillSplitterView
负责渲染计算结果页面,IndexView
负责渲染首页。通过Java类来渲染HTML模板可以提高代码的可维护性。
2.2 控制器实现
下面是控制器的实现代码:
package controllers;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
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 models.Bill;
import models.Person;
import views.BillSplitterView;
import views.IndexView;
@WebServlet("/")
public class BillSplitterController extends HttpServlet {
private BillSplitterView billSplitterView;
private IndexView indexView;
public BillSplitterController() {
billSplitterView = new BillSplitterView();
indexView = new IndexView();
}
// 处理GET请求
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
indexView.render(response.getWriter());
}
// 处理POST请求
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// 获取表单参数
double totalAmount = Double.parseDouble(request.getParameter("totalAmount"));
double tipPercent = Double.parseDouble(request.getParameter("tipPercent"));
int numPersons = Integer.parseInt(request.getParameter("numPersons"));
String[] names = request.getParameterValues("name");
// 计算账单分割结果
double tipAmount = totalAmount * tipPercent / 100;
double totalAmountWithTip = totalAmount + tipAmount;
double amountPerPerson = totalAmountWithTip / numPersons;
double[] amounts = new double[names.length];
for (int i = 0; i < names.length; i++) {
amounts[i] = amountPerPerson;
}
double diff = totalAmountWithTip - amountPerPerson * numPersons;
for (int i = 0; i < diff; i++) {
amounts[i] += 0.01;
}
// 构造Bill对象
List<Person> persons = new ArrayList<>();
for (int i = 0; i < names.length; i++) {
Person person = new Person(names[i], amounts[i]);
persons.add(person);
}
Bill bill = new Bill(totalAmount, tipAmount, persons);
// 渲染计算结果页面
billSplitterView.render(response.getWriter(), bill);
}
}
在doGet()
方法中,我们只需要返回首页即可。在doPost()
方法中,我们首先获取表单参数,然后计算账单分割结果,最后构造Bill
对象并渲染计算结果页面。在计算账单分割结果时,我们先平均分配金额,然后将剩余金额区分配给前diff
个人。这样做可以保证分割的结果准确和公平。
2.3 HTML模板渲染
下面是BillSplitterView
和IndexView
的实现代码:
package views;
import java.io.PrintWriter;
import models.Bill;
public class BillSplitterView {
public void render(PrintWriter writer, Bill bill) {
writer.println("<!DOCTYPE html>");
writer.println("<html>");
writer.println("<head>");
writer.println("<meta charset=\"UTF-8\">");
writer.println("<title>Bill Splitter - Result</title>");
writer.println("<link rel=\"stylesheet\" href=\"css/styles.css\">");
writer.println("</head>");
writer.println("<body>");
writer.println("<div id=\"content\">");
writer.println("<h1>Bill Splitter</h1>");
writer.println("<div id=\"result\">");
writer.println("<p>Total amount: " + bill.getTotalAmount() + "</p>");
writer.println("<p>Tip amount: " + bill.getTipAmount() + "</p>");
writer.println("<table>");
writer.println("<thead><tr><th>Name</th><th>Amount</th></tr></thead>");
writer.println("<tbody>");
for (Person person : bill.getPersons()) {
writer.println("<tr>");
writer.println("<td>" + person.getName() + "</td>");
writer.println("<td>" + person.getAmount() + "</td>");
writer.println("</tr>");
}
writer.println("</tbody>");
writer.println("</table>");
writer.println("<a href=\"/\">Back</a>");
writer.println("</div>");
writer.println("</div>");
writer.println("</body>");
writer.println("</html>");
}
}
package views;
import java.io.PrintWriter;
public class IndexView {
public void render(PrintWriter writer) {
writer.println("<!DOCTYPE html>");
writer.println("<html>");
writer.println("<head>");
writer.println("<meta charset=\"UTF-8\">");
writer.println("<title>Bill Splitter</title>");
writer.println("<link rel=\"stylesheet\" href=\"css/styles.css\">");
writer.println("</head>");
writer.println("<body>");
writer.println("<div id=\"content\">");
writer.println("<h1>Bill Splitter</h1>");
writer.println("<form method=\"post\" action=\"/\">");
writer.println("<p>Total amount:</p>");
writer.println("<input type=\"number\" name=\"totalAmount\">");
writer.println("<p>Tip percent:</p>");
writer.println("<input type=\"number\" name=\"tipPercent\">");
writer.println("<p>Number of persons:</p>");
writer.println("<input type=\"number\" name=\"numPersons\">");
writer.println("<p>Names of persons (separated by comma):</p>");
writer.println("<textarea name=\"name\"></textarea>");
writer.println("<input type=\"submit\" value=\"Calculate\">");
writer.println("</form>");
writer.println("</div>");
writer.println("</body>");
writer.println("</html>");
}
}
在上述代码中,我们通过PrintWriter
对象输出HTML代码。在计算结果页面,我们使用了HTML5新特性<table>
标签来展示账单分割结果。
3. 使用方法
要使用本项目,您需要在本地搭建一个Java Web服务器,比如Tomcat。步骤如下:
下载Tomcat并解压缩
在Tomcat根目录下创建webapps/bill-splitter/WEB-INF/classes/
目录
在上述目录下分别创建controllers
、models
和views
目录
将BillSplitterController.java
、Bill.java
、Person.java
、BillSplitterView.java
和IndexView.java
放入对应目录
将web.xml
和index.jsp
放入webapps/bill-splitter/WEB-INF/
目录
在webapps/bill-splitter/WEB-INF/classes/
目录下编译所有Java文件:javac controllers/*.java models/*.java views/*.java
启动Tomcat:bin/startup.bat
在浏览器中访问http://localhost:8080/bill-splitter/
您将看到如下界面:
按照提示填写表单即可计算账单分割结果。
4. 总结
本文介绍了使用Java Servlets编写的简单账单分割应用程序的实现细节和使用方法。本项目可以作为初学者练手的一个好项目,同时也可以帮助开发者快速地构建一个简单的账单分割应用程序。
如果您想深入学习Java Web开发,可以了解更多的JavaEE组件,比如JSP、JSTL、Servlet Filters、Java Persistence API等。