Java Web开发:Servlet与JSP的综合运用
1. 页面背景颜色修改
若要更改页面背景颜色,可在“Choose a new color”文本框中输入新的颜色值,然后点击“Change Color”按钮。颜色以“#”开头,后面跟随三个两位十六进制数,例如在某些示例中可能是“AA”、“FF”和“AA”。这些数字分别代表颜色中红、绿、蓝的含量,取值范围从最小值“00”到最大值“FF”。
若你对十六进制颜色不太熟悉,在测试Servlet时可尝试以下颜色:
| 颜色代码 | 颜色名称 |
| ---- | ---- |
| #FF0000 | 亮红色 |
| #00FF00 | 亮绿色 |
| #0000FF | 亮蓝色 |
| #FFAAAA | 浅红色 |
| #AAFFAA | 浅绿色 |
| #AAAAFF | 浅蓝色 |
| #FFCC66 | 奶油糖果色 |
2. Java Servlet概述
javax.servlet和javax.servlet.http包中的类主要用于与Web服务器交换信息。Java Servlet是通用网关接口(Common Gateway Interface)的替代方案,是编程语言在Web上检索和呈现数据的常用方式。
Servlet可以利用Java语言的所有特性(图形用户界面除外),因此可用于创建复杂的Web应用程序。如今,Servlet被广泛应用于运行电子商务店面,接收用户订单,连接产品数据库,并在用户购买时收集账单信息。此外,它还用于运行讨论板、内容管理系统和许多其他类型的动态生成的网站。
2.1 Java Applet与Servlet通信
若要使Java Applet与Servlet通信,若希望Applet在与Servlet通信后继续运行,Servlet必须与包含Applet的Web页面位于同一台机器上。出于安全原因,Applet不能与托管它的机器以外的任何机器建立网络连接。
若要让Applet在Web浏览器中加载Servlet,可调用Applet的getAppletContext()方法获取一个AppletContext对象,然后调用该对象的showDocument(URL)方法,并将Servlet的URL作为参数传入。
2.2 小测验
以下是几个问题,用于复习相关知识:
1. 如果一个Servlet同时被五个Web用户运行,Servlet的init()方法会被调用多少次?
a. 5
b. 1
c. 0 - 1
2. 以下哪种技术不属于Tomcat的一部分?
a. Java Servlet
b. JavaServer Pages
c. Java API for XML Processing
3. 当从Web页面上的表单提交数据,并且数据作为URL的一部分显示在浏览器的地址栏中时,使用的是哪种请求?
a. GET请求
b. POST请求
c. HEAD请求
答案如下:
1. c. init()方法在Web服务器首次加载Servlet时被调用。这可能在这五个用户请求Servlet之前就已经发生,因此它可能调用init()一次,也可能根本不调用。
2. c. Java API for XML Processing
3. a. GET请求将表单字段编码到URL中,然后将该URL作为请求提交给Web浏览器。
2.3 认证练习
以下是一个可能在Java编程认证测试中遇到的问题,请在不查看相关材料或使用Java编译器测试代码的情况下回答。
public class CharCase {
public static void main(String[] arguments) {
float x = 9;
float y = 5;
char c = '1';
switch (c) {
case 1:
x = x + 2;
case 2:
x = x + 3;
default:
x = x + 1;
}
System.out.println("Value of x: " + x);
}
}
当x被显示时,它的值是多少?
a. 9.0
b. 10.0
c. 11.0
d. 程序将无法编译
答案可在相关网站查询。
2.4 练习
为扩展你对所学主题的了解,可尝试以下练习:
- 创建SetColor Servlet的修改版本,使其还能让你选择页面上文本的不同颜色。
- 创建一个Servlet,将表单中输入的数据存储在文件中。
部分练习的解决方案可在相关网站获取。
3. JavaServer Pages(JSP)介绍
Java Servlet便于动态生成HTML文本,生成随用户输入和数据变化的页面。然而,Servlet在生成不变的HTML文本时较为困难,因为使用Java语句输出HTML既繁琐又乏味。而且,每次需要更改HTML时,都需要Java程序员进行编辑、重新编译并部署到Web上,很少有组织愿意让非程序员承担这项任务。
JavaServer Pages(JSP)是解决这一问题的方案,它允许创建将静态HTML与Servlet输出以及Java语言元素(如表达式和Java语句)混合的文档。
3.1 JSP概述
JSP是Sun Microsystems和Apache Software Foundation的Tomcat规范的一部分,它是Servlet的补充,而非替代。JSP便于分离两种Web内容:
- 静态内容:Web页面中不变的部分,如在线商店对每个产品的描述。
- 动态内容:Web页面中由Servlet生成的部分,如商店中每个产品的定价和可用性数据,这些数据会随商品售罄而变化。
3.2 创建JSP
创建JSP的方式与创建HTML文档类似,可使用文本编辑器或Web发布程序(如Microsoft FrontPage 2002或Macromedia Dreamweaver)。保存页面时,使用.jsp文件扩展名来表明该文件是JSP而非HTML文档。然后,该页面可以像HTML文档一样发布在Web服务器上(前提是服务器支持Tomcat)。
当用户首次请求JSP时,Web服务器会编译一个新的Servlet来呈现该页面。此过程会导致页面加载缓慢,但后续请求不会再出现这种情况,因为服务器会保留这个Servlet以供后续使用。
3.3 JSP的组成元素
JSP由三种元素组成,每种元素都有类似于HTML的特殊标记:
- Scriptlets:页面加载时执行的Java语句,每个语句都被<%和%>标记包围。
- Expressions:被求值的Java表达式,其输出会显示在页面上,这些表达式被<%=和%>标记包围。
- Declarations:用于创建实例变量和处理页面编译成Servlet时所需的其他设置任务的语句,这些语句被<%!和%>标记包围。
3.4 使用表达式
以下是一个包含表达式的JSP示例,该表达式调用了java.util.Date()构造函数,用于显示当前时间和日期。
<!-- time.jsp -->
<html>
<head>
<title>Clock</title>
</head>
<body>
<h1 align="Center">
<%= new java.util.Date() %>
</h1>
</body>
</html>
将该文件保存后,上传到Web服务器上存储其他Web页面的文件夹中。与Java Servlet不同,JSP可以放在Web上可访问的任何文件夹中。
当首次加载该页面的URL时,Web服务器会将JSP编译成Servlet。此后,服务器会保留这个Servlet,后续请求将不再进行编译。
在JSP的表达式和其他元素中,可以引用以下几个Servlet变量:
- application:用于与Web服务器通信的Servlet上下文。
- config:用于查看Servlet初始化方式的Servlet配置对象。
- out:Servlet输出流。
- request:HTTP Servlet请求。
- response:HTTP Servlet响应。
- session:当前的HTTP会话。
以下是另一个示例,展示了如何在页面上使用request变量:
<!-- environment.jsp -->
<html>
<head>
<title>Environment Variables</title>
</head>
<body>
<ul>
<li>Accept: <%= request.getHeader("Accept") %>
<li>Accept-Encoding: <%= request.getHeader("Accept-Encoding") %>
<li>Connection: <%= request.getHeader("Connection") %>
<li>Content-Length: <%= request.getHeader("Content-Length") %>
<li>Content-Type: <%= request.getHeader("Content-Type") %>
<li>Cookie: <%= request.getHeader("Cookie") %>
<li>Host: <%= request.getHeader("Host") %>
<li>Referer: <%= request.getHeader("Referer") %>
<li>User-Agent: <%= request.getHeader("User-Agent") %>
</ul>
</body>
</html>
在该页面的第7 - 15行,每行都包含一个对getHeader()方法的调用,用于检索不同的HTTP请求头。输出的值取决于Web服务器和所使用的Web浏览器。
3.5 使用Scriptlets
在JSP中还可以使用Java语句(如调用方法、为变量赋值、创建条件语句等),这些语句以<%标记开始,以%>标记结束,多个语句可以包含在这些标记内。
以下是一个名为shopforbooks.jsp的Web页面示例,它显示了一个书籍列表,并提供了指向每本书在在线书店页面的超链接。
<!-- shopforbooks.jsp -->
<html>
<head>
<title>Shop for Books</title>
</head>
<body>
<h2 align="Left">Favorite Books</h2>
<%
String[] bookTitle = { "Catch-22", "Something Happened", "Good as Gold" };
String[] isbn = { "0684833395", "0684841215", "0684839741" };
String amazonLink = "http://www.amazon.com/exec/obidos/ASIN/";
String bnLink = "http://shop.bn.com/booksearch/isbnInquiry.asp?isbn=";
String store = request.getParameter("store");
if (store == null) {
store = "Amazon";
}
for (int i = 0; i < bookTitle.length; i++) {
if (store.equals("Amazon"))
out.println("<li><a href=\"" + amazonLink + isbn[i] + "\">" + bookTitle[i] + "</a>");
else
out.println("<li><a href=\"" + bnLink + isbn[i] + "\">" + bookTitle[i] + "</a>");
}
%>
<p>Preferred Bookstore:
<form action="shopforbooks.jsp" method="POST">
<p><input type="radio" value="Amazon" <%= (store.equals("Amazon") ? " checked" : "") %> name="store"> Amazon.Com
<p><input type="radio" value="BN" <%= (store.equals("BN") ? " checked" : "") %> name="store"> Barnes & Noble
<p><input type="submit" value="Change Store">
</form>
</body>
</html>
该JSP页面底部包含一个表单,允许用户选择他们喜欢的在线书店。在第28行,表单提交到该JSP页面的URL,因为JSP实际上也是Servlet,所以它们也可以接收通过POST或GET发送的表单数据。
3.6 使用Declarations
JSP中可以插入的最后一种元素是声明,它是在页面编译成Servlet时定义变量或方法的语句。声明通常与表达式和Servlet结合使用,被<%!和%>标记包围。
以下是一个使用声明来显示页面访问计数器的JSP示例:
<!-- counter.jsp -->
<%@ page import="counter.*" %>
<html>
<head>
<title>Counter Example</title>
</head>
<body>
<h1>JSP Stats</h1>
<%! Counter visits; %>
<%! int count; %>
<%
visits = new Counter(application.getRealPath("counter.dat"));
count = visits.getCount() + 1;
%>
<p>This page has been loaded <%= count %> times.
<% visits.setCount(count); %>
</body>
</html>
在尝试这个页面之前,需要创建一个辅助类Counter,其代码如下:
// Counter.java
package counter;
import java.io.*;
import java.util.*;
public class Counter {
private int count;
private String filepath;
public Counter(String inFilepath) {
count = 0;
filepath = inFilepath;
}
public int getCount() {
try {
File countFile = new File(filepath);
FileReader file = new FileReader(countFile);
BufferedReader buff = new BufferedReader(file);
String current = buff.readLine();
count = Integer.parseInt(current);
buff.close();
} catch (IOException e) {
// do nothing
} catch (NumberFormatException nfe) {
// do nothing
}
return count;
}
public void setCount(int newCount) {
count = newCount;
try {
File countFile = new File(filepath);
FileWriter file = new FileWriter(countFile);
BufferedWriter buff = new BufferedWriter(file);
String output = "" + newCount;
buff.write(output, 0, output.length());
buff.close();
} catch (IOException e) {
// do nothing
}
}
}
成功编译该类后,将其存储在Web服务器上与之前创建的Java Servlet相同的文件夹中。虽然Counter类不是Servlet,但Tomcat会在该文件夹中查找JSP页面引用的类。
3.7 创建Web应用程序
通过结合Java类、Servlet和JSP,可以创建交互式Web应用程序,这些应用程序能够根据用户输入以复杂、连贯的方式动态生成内容。
为了展示Java技术的多个方面如何在Web上协同工作,下面将创建一个名为Guestbook的Web应用程序,该应用程序允许访问者为网站创建者留下消息。
Guestbook项目由以下三部分组成:
- guestbook.jsp:一个JSP页面,用于显示Web服务器上文本文件中的留言簿条目,并提供一个表单,让访问者可以添加条目。
- guestbookpost.jsp:一个JSP页面,用于将新的留言簿条目保存到文本文件中。
- Guestbook.java:一个Java类,用于在将留言簿条目保存之前过滤掉一些字符。
3.7.1 guestbook.jsp代码
<!-- guestbook.jsp -->
<%@ page import="java.util.*,java.io.*" %>
<html>
<head>
<title>Visitors Who Signed our Guestbook</title>
</head>
<body>
<h3>Visitors Who Signed our Guestbook</h3>
<%
String id = request.getParameter("id");
boolean noSignatures = true;
try {
String filename = application.getRealPath(id + ".gbf");
FileReader file = new FileReader(filename);
BufferedReader buff = new BufferedReader(file);
boolean eof = false;
while (!eof) {
String entry = buff.readLine();
if (entry == null)
eof = true;
else {
StringTokenizer entryData = new StringTokenizer(entry, "^");
String name = (String) entryData.nextElement();
String email = (String) entryData.nextElement();
String url = (String) entryData.nextElement();
String entryDate = (String) entryData.nextElement();
String ip = (String) entryData.nextElement();
String comments = (String) entryData.nextElement();
out.print("<p>From: " + name);
if (!email.equals("None"))
out.println(" <" + email + "><br>");
else
out.println("<br>");
if (!url.equals("None"))
out.println("Home Page: <a href=\"" + url + "\">" + url + "</a><br>");
out.println("Date: " + entryDate + "<br>");
out.println("IP: " + ip);
out.println("<blockquote>");
out.println("<p>" + comments);
out.println("</blockquote>");
noSignatures = false;
}
}
buff.close();
} catch (IOException e) {
out.println("<p>This guestbook could not be read because of an error.");
log("Guestbook Error: " + e.toString());
}
if (noSignatures)
out.println("<p>No one has signed our guestbook yet.");
%>
<h3>Sign Our Guestbook</h3>
<form method="POST" action="guestbookpost.jsp">
<table border="0" cellpadding="5" cellspacing="0" width="100%">
<tr>
<td width="15%" valign="top" align="right">Your Name:</td>
<td width="50%"><input type="text" name="name" size="40"></td>
</tr>
<tr>
<td width="15%" valign="top" align="right">Your E-mail Address:</td>
<td width="50%"><input type="text" name="email" size="40"></td>
</tr>
<tr>
<td width="15%" valign="top" align="right">Your Home Page:</td>
<td width="50%"><input type="text" name="url" size="40"></td>
</tr>
<tr>
<td width="15%" valign="top" align="right">Your Comments:</td>
<td width="50%"><textarea rows="6" name="comments" cols="40"></textarea></td>
</tr>
</table>
<p align="center"><input type="submit" value="Submit" name="B1">
<input type="reset" value="Reset" name="Reset"></p>
<input type="hidden" name="id" value="<%= id %>">
</form>
</body>
</html>
保存该页面后,将其存储在支持Tomcat的Web服务器上任何可以存储页面的文件夹中。只要有一个空的留言簿文件,就可以在项目的其他部分完成之前进行测试。创建该文件的方法是在系统上保存一个空的文本文件,并将其命名为cinema.gbf,然后将其存储在与guestbook.jsp相同的Web文件夹中。
当加载该JSP页面时,必须包含一个参数来指定要加载的留言簿的ID,例如:http://www.java21pro.com/guestbook.jsp?id=cinema
3.7.2 guestbookpost.jsp代码
<!-- guestbookpost.jsp -->
<%@ page import="java.util.*,java.io.*,guestbook.*" %>
<html>
<head>
<title>Thank You For Signing Our Guestbook</title>
</head>
<body>
<h3>Thank You For Signing Our Guestbook</h3>
<%
String id = request.getParameter("id");
String[] entryFields = { "name", "email", "url", "comments" };
String[] entry = new String[4];
for (int i = 0; i < entryFields.length; i++) {
entry[i] = Guestbook.filterString(request.getParameter(entryFields[i]));
}
Date now = new Date();
String entryDate = now.toString();
String ip = request.getRemoteAddr();
%>
<p>Your entry looks like this:
<p>From: <%= entry[0] %><%= (!entry[1].equals("None") ? "<"+entry[1]+">" : "") %><br>
<% if (!entry[2].equals("None")) { %>
Home Page: <a href="<%= entry[2] %>"><%= entry[2] %></a><br>
<% } %>
Date: <%= entryDate %><br>
IP: <%= ip %>
<blockquote>
<p><%= entry[3] %>
</blockquote>
<%
try {
boolean append = true;
String filename = application.getRealPath(id + ".gbf");
FileWriter fw = new FileWriter(filename, append);
BufferedWriter fileOut = new BufferedWriter(fw);
String newEntry = entry[0] + "^" + entry[1] + "^" + entry[2] + "^" + entryDate + "^" + ip + "^" + entry[3];
fileOut.write(newEntry, 0, newEntry.length());
fileOut.newLine();
fileOut.close();
} catch (IOException e) {
out.println("<p>This guestbook could not be updated because of an error.");
log("Guestbook Error: " + e.toString());
}
%>
<p><a href="guestbook.jsp?id=<%= id %>">View the Guestbook</a>
</body>
</html>
guestbookpost.jsp页面用于收集Web表单中的数据,去除不能放入留言簿的字符,并将结果存储在文本文件中。每个留言簿都有自己的文件,文件名以留言簿的ID参数开头,以.gbf文件扩展名结尾。
3.7.3 Guestbook.java代码
在尝试Guestbook应用程序之前,需要创建一个Java类Guestbook,用于在留言簿条目发布之前过滤掉一些不需要的文本。由于留言簿条目在文件中的存储方式,有三个字符不能包含在留言簿中:
- 插入符号(^)
- 回车符(Java中整数值为13)
- 换行符(Java中整数值为10)
以下是Guestbook类的代码:
// Guestbook.java
package guestbook;
public class Guestbook {
public static String filterString(String input) {
input = replaceText(input, '^', ' ');
input = replaceText(input, (char)13, ' ');
input = replaceText(input, (char)10, ' ');
return input;
}
private static String replaceText(String inString, char oldChar, char newChar) {
while (inString.indexOf(oldChar) != -1) {
int oldPosition = inString.indexOf(oldChar);
StringBuffer data = new StringBuffer(inString);
data.setCharAt(oldPosition, newChar);
inString = data.toString();
}
return inString;
}
}
通过以上内容,我们详细介绍了Java Servlet和JSP的相关知识,包括页面背景颜色修改、Servlet的基本概念、Applet与Servlet的通信、JSP的组成元素及使用方法,以及如何创建一个完整的Web应用程序Guestbook。希望这些内容能帮助你更好地理解和应用Java Web开发技术。
4. 总结与展望
4.1 技术总结
在Java Web开发领域,Servlet和JSP是两个至关重要的技术。Servlet主要负责与Web服务器进行信息交换,能够利用Java语言的强大功能(除图形用户界面外)创建复杂的Web应用程序。它广泛应用于电子商务、讨论板、内容管理系统等众多动态网站中。
而JSP则是Servlet的有力补充,它允许开发者将静态HTML与动态的Servlet输出以及Java语言元素相结合,极大地提高了开发效率。JSP由Scriptlets、Expressions和Declarations三种元素组成,每种元素都有其独特的用途和标记方式。通过这些元素,开发者可以在页面中灵活地使用Java语句、表达式和声明变量,实现动态内容的生成。
4.2 开发流程回顾
下面通过一个mermaid流程图来回顾一下使用Servlet和JSP开发Web应用程序的基本流程:
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px
A(需求分析):::process --> B(设计架构):::process
B --> C(创建Servlet):::process
B --> D(创建JSP页面):::process
C --> E(部署到Web服务器):::process
D --> E
E --> F(测试与调试):::process
F --> G(上线发布):::process
从流程图可以看出,开发一个完整的Web应用程序需要经过需求分析、架构设计、Servlet和JSP的创建、部署、测试以及最终的上线发布等步骤。每个步骤都紧密相连,缺一不可。
4.3 未来发展趋势
随着互联网技术的不断发展,Java Web开发也在不断演进。未来,Servlet和JSP可能会与更多的新技术相结合,如微服务架构、容器化技术(如Docker)和云计算平台(如AWS、阿里云等)。这些新技术将进一步提高Web应用程序的性能、可扩展性和可靠性。
同时,随着前端技术的飞速发展,前后端分离的开发模式也越来越受到青睐。在这种模式下,Servlet和JSP可能更多地负责后端的业务逻辑处理,而前端则使用更专业的前端框架(如Vue.js、React.js等)来实现页面的展示和交互。
4.4 学习建议
对于想要深入学习Java Web开发的开发者来说,除了掌握Servlet和JSP的基础知识外,还应该不断学习和实践。可以通过阅读相关的技术书籍、参加线上线下的培训课程、参与开源项目等方式来提升自己的技能。
此外,多做项目实践也是非常重要的。可以从一些简单的项目开始,逐步积累经验,然后尝试开发一些复杂的Web应用程序。在实践过程中,要善于总结问题和解决问题,不断优化自己的代码和开发流程。
5. 常见问题解答
5.1 Servlet相关问题
5.1.1 Servlet的init()方法调用次数问题
在实际开发中,经常会遇到Servlet的init()方法调用次数的疑问。当多个Web用户同时请求一个Servlet时,init()方法的调用次数取决于Web服务器加载Servlet的时机。如果Web服务器在所有用户请求之前就已经加载了Servlet,那么init()方法只会被调用一次;如果在用户请求时Servlet还未加载,那么init()方法会在首次加载时被调用。所以,init()方法可能被调用一次,也可能不被调用。
5.1.2 Servlet与Applet通信问题
若要实现Java Applet与Servlet的通信,需要注意安全限制。由于安全原因,Applet只能与托管它的机器上的Servlet进行通信。如果要让Applet在Web浏览器中加载Servlet,可以通过调用Applet的getAppletContext()方法获取AppletContext对象,然后调用该对象的showDocument(URL)方法,并将Servlet的URL作为参数传入。
5.2 JSP相关问题
5.2.1 JSP编译问题
当用户首次请求JSP页面时,Web服务器会将其编译成Servlet。这个过程可能会导致页面加载缓慢,但后续请求不会再出现这种情况,因为服务器会保留编译后的Servlet。如果在编译过程中出现问题,可能是由于代码语法错误、服务器配置问题或缺少相关的依赖库等原因导致的。需要仔细检查代码和服务器配置,确保一切正常。
5.2.2 JSP中变量引用问题
在JSP的表达式和其他元素中,可以引用一些Servlet变量,如application、config、out、request、response和session等。这些变量在Servlet开发中也经常使用,需要熟悉它们的用途和方法。例如,request变量可以用于获取HTTP请求的相关信息,response变量可以用于发送HTTP响应。
5.3 综合问题
5.3.1 如何优化Web应用程序性能
要优化Web应用程序的性能,可以从多个方面入手。首先,要合理设计数据库,优化数据库查询语句,减少不必要的数据库访问。其次,对于静态资源(如图片、CSS、JavaScript等),可以进行压缩和缓存,减少网络传输时间。此外,还可以使用负载均衡技术来分担服务器的压力,提高系统的并发处理能力。
5.3.2 如何确保Web应用程序的安全性
Web应用程序的安全性至关重要。为了确保安全性,需要对用户输入进行严格的验证和过滤,防止SQL注入、XSS攻击等安全漏洞。同时,要对敏感数据进行加密处理,如用户密码、支付信息等。此外,还可以使用HTTPS协议来加密数据传输,防止数据在传输过程中被窃取。
6. 结语
通过本文的介绍,我们全面了解了Java Web开发中Servlet和JSP的相关知识,包括页面背景颜色修改、Servlet的基本概念、Applet与Servlet的通信、JSP的组成元素及使用方法,以及如何创建一个完整的Web应用程序Guestbook。同时,我们还对开发流程进行了回顾,探讨了未来的发展趋势,并解答了一些常见的问题。
希望本文能够帮助你更好地掌握Java Web开发技术,在实际项目中能够灵活运用Servlet和JSP,开发出高效、稳定、安全的Web应用程序。在未来的学习和实践中,不断探索和创新,将Java Web开发技术推向新的高度。
超级会员免费看

被折叠的 条评论
为什么被折叠?



