Java开发:RESTful服务与Spring MVC框架实践
1. 实现RESTful服务代码
1.1 前置要求
在开始之前,需要确保已经安装了Java和GlassFish v3服务器。可以从网站www.wrox.com下载相关代码和资源,这些文件位于下载内容的Lesson34文件夹中。
1.2 操作步骤
-
创建项目与包
:在Eclipse中创建一个名为Lesson34的动态Web项目,然后创建一个名为
com.practicaljava.lesson34的包。 -
复制类文件
:将DVD中的
Stock、StockResource和StockService类复制到上述创建的包中。 -
复制配置文件
:把清单34 - 4中的
web.xml文件复制到WebContent/WEB - INF目录下。 -
添加样式文件
:创建
WebContent/css文件夹,并将DVD中的main.css文件复制到该文件夹,为客户端UI添加颜色。 - 部署项目 :在GlassFish下部署Lesson34项目。右键点击服务器名称,选择“Add and Remove”,在弹出窗口中点击“Add”将Lesson34从左侧框移到右侧框,然后点击“Finish”。
-
访问项目
:打开Web浏览器,访问
http://localhost:8080/Lesson34/,会打开清单34 - 5中的index.html文件。 - 搜索股票信息 :在搜索字段中输入“IBM”并点击“Find”,将显示该股票的定价信息(硬编码)。
-
测试添加股票功能
:填写图34 - 3中的表单并点击“Add”,会向RESTful服务发送POST请求,该请求将映射到清单34 - 2中
StockResource类的addStock()方法。添加新股票后,可以在搜索字段中输入其名称并点击“Find”进行搜索。
1.3 提示
Eclipse IDE for Java EE Developers有创建REST资源的模板。右键点击项目名称,选择“New”,然后选择“RESTful Web Service From Pattern (Java EE 6)”,Eclipse会创建一个类似于清单34 - 2的带注解的类,可根据应用需求进行编辑。
2. Spring MVC框架简介
2.1 Spring框架的诞生
世纪之初,Java EE被称为J2EE,它是一个沉重且过度设计的标准。编写EJBs代码困难,需要编写大量样板代码,且当时Java注解尚未发明。虽然Java容器能处理多线程、事务、持久化和安全等问题,但开发者需要更轻量级的容器和更简单的编程模型。
2002年底,软件工程师Rod Johnson编写了《Expert One - on - One J2EE Design and Development》一书。一年后,该书的代码示例和开发建议以Spring框架的形式发布。
2.2 Spring框架的特点
Spring框架是一个Java容器,通过XML配置以松散耦合的方式为应用程序的对象提供生存空间。不过,这种松散耦合也带来了配置文件较大的问题。
Spring框架基于控制反转(IoC)原则构建,容器负责对象的实例化和定位。IoC也被称为“好莱坞原则”:“别打电话给我们,我们会打电话给你”。例如,在Spring框架下,容器会使用回调系统实例化
Order
对象并将其注入到
Customer
对象实例中,这是依赖注入模式的一个例子。
2.3 Spring框架的应用
近年来,Spring框架成为开发企业级Java应用的替代方案,它提供了一个基础设施,便于集成第三方框架和组件。例如,Spring和Hibernate持久化框架的组合是许多生产级应用的流行架构。虽然Java EE 6规范有了重大改进,但Spring/Hibernate组合仍然是开发企业级Java应用的优秀基础设施。
2.4 Bean Wiring
在Spring框架中,Bean通过XML文件进行配置。如果一个名为
Customer
的类需要一个
Order
Bean,可以通过在主Spring工厂
ApplicationContext
实例上调用
getBean("Order")
方法来查找该Bean,或者更好的做法是配置将
Order
注入到
Customer
中,示例代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns=http://www.springframework.org/schema/beans
xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="customerBean" class="com.practicaljava.lesson35.Customer">
<property name="order" ref="ord" />
</bean>
<bean id="ord" class="com.practicaljava.lesson35.Order"/>
</beans>
这种方式以松散耦合的方式将一个对象注入到另一个对象的字段中。
Customer
类知道在合适的时候会有人提供
Order
对象。这使得可以通过硬编码值来测试
Customer
的功能,只需将上述XML中的
com.practicaljava.lesson35.Order
改为
com.practicaljava.lesson35.FakeOrder
,当有真实数据时再改回来。
在简单情况下,可以通过setter或构造函数参数将更简单的值注入到Spring Bean属性中。可以在实例化
ApplicationContext
时将配置好的Bean文件名称提供给其构造函数。
2.5 Spring MVC概述
Spring框架由多个模块组成,可分为Web、核心和数据访问模块,并且可以根据需要按需使用。Web模块简化了Web应用程序的开发,核心模块为Spring容器中的Java组件提供基础设施和布线,数据访问模块创建数据访问的抽象层,以便在更换JDBC驱动程序或DBMS时无需更改Java代码。
Spring MVC模块用于开发Web应用程序。Spring管理Java类,被管理的类可称为Spring Bean。Spring框架提供了构建Web应用程序的解决方案,包括Spring Faces、Spring Web Flow、Spring JavaScript、Spring Security和Spring BlaseDS等模块,可以根据需要选择使用。
构建带有HTML客户端的Web应用程序主要有两种模型:
| 模型 | 描述 |
| ---- | ---- |
| 客户端连接到服务器端表示对象 | 客户端连接到服务器端的表示对象(如JSP),该对象负责进一步路由和处理请求,并形成要返回给客户端的下一个视图。 |
| 客户端连接到服务器端控制器对象 | 客户端连接到服务器端的控制器对象(无UI代码),该对象执行请求的路由和处理,并选择要返回给客户端的适当视图。 |
Spring框架采用第二种模型,
DispatcherServlet
拦截客户端请求并将其传递给适当的Java控制器处理。控制器创建
ModelAndView
对象并将其交给视图解析器,视图解析器找到要返回给客户端的视图组件。整个数据流如下:
graph LR
A[Request] --> B[Servlet Container with Spring Web MVC]
B --> C[DispatcherServlet]
C --> D[Controller]
D --> E[ModelAndView]
E --> F[ViewResolver]
F --> G[View]
G --> H[Response]
这种架构由易于扩展的Spring MVC层支持,其他框架可以集成到Spring基础设施中,如Spring和Hibernate常用于数据持久化,Adobe的BlaseDS框架或Apache Struts遗留框架也可以集成到Spring中。同时,Spring框架支持带有数据验证和错误处理的HTML表单。
3. 处理HTML表单
3.1 处理HTML表单的复杂性
处理HTML表单与之前的“Hello People”示例相比,稍微复杂一些。Spring框架自带集成的标签库,每个HTML元素都有对应的标签,特别是有用于处理HTML表单的表单标签库。
3.2 示例代码分析
3.2.1 ContactUs.jsp
以下是
ContactUs.jsp
的代码:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
<h2>Contact Manager</h2>
<form:form method="post" action="addQuestion.html">
<table>
<tr>
<td><form:label path="author">Who are you?</form:label></td>
<td><form:input path="author" /></td>
</tr>
<tr>
<td><form:label path="subject">Subject</form:label></td>
<td><form:input path="subject" /></td>
</tr>
<tr>
<td><form:label path="message">You Question</form:label></td>
<td><form:textarea path="message" /></td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Submit your question"/>
</td>
</tr>
</table>
</form:form>
</body>
</html>
当用户点击“Submit”时,请求会以
addQuestion.html
的URL发送到服务器。然后
DispatcherServlet
会将
addQuestion
与控制器中
addUserQuestion()
方法进行映射。
3.2.2 ContactUsController.java
package com.practicaljava.lesson35.controller;
import org.springframework.stereotype.Controller;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.servlet.ModelAndView;
import com.practicaljava.lesson35.model.ContactUs;
@Controller
@SessionAttributes
public class ContactUsController {
@RequestMapping(value="/addQuestion", method=RequestMethod.POST)
public String addUserQuestion(@ModelAttribute("contactUs") ContactUs
contactUs, BindingResult result){
System.out.println("New message:\nSubject:"
+contactUs.getSubject());
System.out.println("Author " + contactUs.getAuthor());
System.out.println("Message "+ contactUs.getMessage());
return "redirect:contactUs.html";
}
@RequestMapping("/contactUs")
public ModelAndView contactUs(){
return new ModelAndView("contactUs", "command", new ContactUs());
}
}
@ModelAttribute
将方法参数绑定到命名的模型属性,Spring框架会将模型中的属性映射到
ContactUs.jsp
中的相应属性。
3.2.3 ContactUs.java
public class ContactUs {
private String subject;
private String message;
private String author;
public String getSubject() {
return subject;
}
public void setSubject(String subject) {
this.subject = subject;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
3.3 测试流程
-
打开Web浏览器,输入URL:
http://localhost:8080/Lesson35/contactUs.html。@RequestMapping("/contactUs")注解会响应客户端,显示ContactUs.jsp页面。 -
在表单中输入一些值,然后点击“Submit”。此时
/addQuestion操作会与ContactUsController的addUserQuestion()方法匹配。 -
客户端接收到的值会打印在GlassFish服务器的日志文件中,该文件位于
logs/server.log(在你的域目录下)。
4. 总结
4.1 关键知识点回顾
- RESTful服务实现 :通过一系列步骤,包括创建项目、复制代码和配置文件、部署项目等,实现了一个简单的RESTful服务,并对其进行了功能测试。
- Spring MVC框架 :了解了Spring框架的诞生背景、特点和应用场景,掌握了Bean Wiring的配置方法,以及Spring MVC模块的架构和工作原理。
- HTML表单处理 :学会使用Spring框架的标签库处理HTML表单,包括表单的提交、数据绑定和处理等操作。
4.2 实践建议
在实际开发中,可以根据项目需求灵活运用这些技术。对于RESTful服务,可以进一步优化接口设计和数据处理逻辑;对于Spring MVC框架,可以根据具体业务场景选择合适的模块和配置方式,提高开发效率和代码质量。同时,要注意代码的可维护性和可测试性,通过合理的配置和设计,确保系统的稳定性和扩展性。
通过以上的学习和实践,相信你对Java开发中的RESTful服务和Spring MVC框架有了更深入的理解和掌握,能够在实际项目中运用这些技术解决问题。
超级会员免费看
2031

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



