本文展示一個基於 Servlet + JSP 的簡易計算器完整案例,涵蓋前端按鈕交互、輸入顯示、退位刪除、關閉窗口等 JavaScript 邏輯,以及後端四則運算、取模、除零保護、Session 狀態保持與重定向回顯等核心功能。
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Servlet 計算器</title>
</head>
<body bgcolor="#afb4db">
<%
String s1 = "";
Object ob = session.getAttribute("jg");
if (ob != null) {
s1 = ob.toString();
}
session.invalidate(); // 讀取後清除,避免重複顯示
%>
<form action="TestJSQ" method="post">
<table border="1" align="center">
<tr align="center"><td colspan="4">簡易計算器</td></tr>
<tr>
<td colspan="4">
<textarea name="text" id="tt" cols="22" rows="1"><%= s1 %></textarea>
</td>
</tr>
<tr align="center">
<td><input type="reset" value="C"></td>
<td><input type="button" value="off" onclick="doselect(this)"></td>
<td><input type="button" value="+" onclick="doselect(this)"></td>
<td><input type="button" value="←" onclick="doselect(this)"></td>
</tr>
<tr align="center">
<td><input type="button" value="7" onclick="doselect(this)"></td>
<td><input type="button" value="8" onclick="doselect(this)"></td>
<td><input type="button" value="9" onclick="doselect(this)"></td>
<td><input type="button" value="-" onclick="doselect(this)"></td>
</tr>
<tr align="center">
<td><input type="button" value="4" onclick="doselect(this)"></td>
<td><input type="button" value="5" onclick="doselect(this)"></td>
<td><input type="button" value="6" onclick="doselect(this)"></td>
<td><input type="button" value="×" onclick="doselect(this)"></td>
</tr>
<tr align="center">
<td><input type="button" value="1" onclick="doselect(this)"></td>
<td><input type="button" value="2" onclick="doselect(this)"></td>
<td><input type="button" value="3" onclick="doselect(this)"></td>
<td><input type="button" value="/" onclick="doselect(this)"></td>
</tr>
<tr align="center">
<td><input type="button" value="." onclick="doselect(this)"></td>
<td><input type="button" value="0" onclick="doselect(this)"></td>
<td><input type="submit" value="=" onclick="doselect(this)"></td>
<td><input type="button" value="%" onclick="doselect(this)"></td>
</tr>
</table>
</form>
<script language="javascript">
function doselect(bt) {
var obj = document.getElementById('tt');
var s = bt.value;
obj.innerHTML += s; // 追加按鈕值
if (s == "←") { // 退位刪除
var a = obj.value;
s = a.substring(0, a.length - 1); // 修正:原代碼 -2 有誤
obj.innerHTML = s;
}
if (s == "off") {
window.close();
}
}
</script>
</body>
</html>
package com.sp.web;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
public class Test_JSQ extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html; charset=UTF-8");
String st = request.getParameter("text").trim();
// 解析運算符位置
int opIndex = -1;
if (st.contains("+")) opIndex = st.indexOf("+");
else if (st.contains("-")) opIndex = st.indexOf("-");
else if (st.contains("×")) opIndex = st.indexOf("×"); // 注意:前端用 ×,此處需一致
else if (st.contains("/")) opIndex = st.indexOf("/");
else if (st.contains("%")) opIndex = st.indexOf("%");
if (opIndex == -1) {
response.getWriter().write("無效表達式");
return;
}
Double n1 = Double.parseDouble(st.substring(0, opIndex));
Double n2 = Double.parseDouble(st.substring(opIndex + 1, st.length() - 1)); // 去掉末尾 =
String op = st.charAt(opIndex) + "";
String rs = "";
try {
switch (op) {
case "+": rs = (n1 + n2) + ""; break;
case "-": rs = (n1 - n2) + ""; break;
case "×": rs = (n1 * n2) + ""; break;
case "/":
if (n2 != 0.0) rs = (n1 / n2) + "";
else rs = "error: 除數不能為零";
break;
case "%": rs = (n1 % n2) + ""; break;
default: rs = "不支持的運算符";
}
} catch (NumberFormatException e) {
rs = "數值格式錯誤";
}
HttpSession session = request.getSession();
session.setAttribute("jg", rs);
response.sendRedirect("jisuanqi.jsp");
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
textarea 用 innerHTML 追加字符(注意:textarea 應用 value 屬性更標準)← 通過 substring(0, length-1) 實現off 呼叫 window.close() 嘗試關閉窗口(瀏覽器安全策略可能攔截)C 使用 <input type="reset"> 重置表單數字1運算符數字2=(以 = 結尾)indexOf 定位運算符,substring 截取兩操作數n2 != 0.0 判斷sendRedirect 回 JSP,JSP 讀取後 invalidate() 清除| 問題 | 原因 | 修正方案 |
|---|---|---|
| 運算符 × 前後端不一致 | JSP 用 ×,Servlet 解析用 x | 統一使用 * 或 ×,建議前端用 * 避免編碼問題 |
| substring 截取長度錯誤 | 原代碼 a.length-2 | 應為 a.length-1(去掉末尾 =) |
| textarea 用 innerHTML | textarea 無 innerHTML,應用 value | obj.value += s、obj.value = s |
| 無法處理連續運算 | 單次請求只解析一個運算符 | 引入表達式解析器或前端即時計算 |
| 異常處理簡陋 | NumberFormatException 僅捕獲 | 增加輸入驗證、正則預檢 |
這個案例雖簡單,但完整演示了「前端收集表達式 → 後端解析計算 → Session 傳遞結果 → 重定向回顯」的經典 Web 交互模式,是 Servlet/JSP 入門的優秀實踐。