- 浏览: 27440 次
- 性别:
- 来自: 贵阳
文章分类
最新评论
很多 web 应用程序是以数据为中心 — 它们显示数据并允许用户新建或更新数据。这听上去很简单,但真到了一些基本操作,如在数据库中读写数据,情况却非常糟糕。尽管如此,Java Persistence API (JPA) 却极大地减少了必须编写的冗长的样板式代码。我们将看一个使用 JPA 的简单例子。 本文中,将开发一个简单的管理青年足球联赛的应用程序。开始时将建立一个简单的数据模型,用于跟踪球队及其队员。将使用 JPA 完全访问这些数据。以第一个数据模型 这是典型的 JPA 注释类。使用 在 清单 1 中,还要声明另一个字段, 清单 2 中显示的 既然已经声明两个类,只要告诉 JPA 运行时如何连接数据库。通过创建 persistence.xml 文件来完成。JPA 运行时需要找到该文件,并使用其中的元数据。最简单的方法是放入 /META-INF 目录,这是源代码的子目录(需要将它放到输出编译类的根目录中)。清单 3显示 persistence.xml 文件。 回头看看 清单 1 和 清单 2,所有代码都是通用的 JPA 代码。实际上曾使用的都是 JPA 注释和它的常量。对已使用的数据库和 JPA 实现没有什么特别的。正如在 清单 3 中看到的,persistence.xml 文件正是存放这些特定内容的地方。有一些出色的 JPA 实现可用,包括 OpenJPA 和 TopLink(见 参考资料)。已经使用过古老的 Hibernate,因此有几个 Hibernate 相关属性已经指定。这些多数都是简单易懂的,如 JDBC 驱动器和 URL,而且是很有用的,如通知 Hibernate 登陆到正在执行的 SQL (一些您肯定不想放在产品环境中的内容,但对于调试却很重要)。 在 清单 3 中,您还会注意到使用了 Apache Derby 数据库。实际上,使用的是数据库的嵌入式版本。您不必单独启动数据库,且担心配置。此外,在连接 URL 中您也指出应该自动创建数据库,并且您也通知 Hibernate 自动创建模式(这是 如果是五年前创建该应用程序,现在可能会使用一些 Java Server Pages (JSPs) 或 Java Server Faces (JSFs) 或一些其他模板技术。不需要服务器上为该应用程序创建 UI,而是使用 Dojo 在客户端创建。所需要做的就是让客户端代码使用 Ajax 来访问数据。也可使用模板解决方案来解决这类问题,但使用 Java API for RESTful Web Services (JAX-RS) 要简单得多。一开始我们创建一个类,用于读取数据库中所有 清单 4 显示的是类数据访问对象类,名为 现在已经理解了 清单 4 中 JPA 部分,我们再探讨其中的 JAX-RS 部分。您首先会注意到的是使用 接下来,第一个方法 这就是要使用 JAX-RS 将类公开给客户端所要做的所有事情。尽管如此,您可能会问自己:如果该方法返回 通过添加 现在回到 清单 4 看看类的第二个方法, 清单 6 中的 要完成 JAX-RS 需要做的最后一件事是显示用于包装所有内容的配置。为此,只需修改应用程序的 web.xml 文件。清单 7 显示的是应用程序的 web.xml。 如您在 清单 7 中所见,应用程序中只有一个 servlet 声明。该 servlet 是由 Jersey 所提供的,这是使用的 JAX-RS 实现。传递一个初始化参数给 servlet — 包中含有您希望 JAX-RS 了解的所有类。本例中,有一个存放数据模型的包和一个存放数据访问对象的包。您希望能找到这些模型,以便 JAX-RS 能够将其转换为 JSON。当然,需要找到 DAO 以便 JAX-RS 能将请求路由到它们。最后,请注意 servlet 映射。这里指定了您的 URL 路径的 /resources 部分。现在已经准备好在客户端使用所有后台代码创建一个使用 Dojo 的 UI。 Dojo 工具箱提供了几乎所有构造 web 应用程序客户端所需的库或工具。您会看到它在使用 Ajax、表单、JSON 和创建 UI 小部件时如何提供帮助。(它可以做的更多,而这恰好是在该简单例子中您所需要的。)它是如此庞大的一个系统,您可能想要下载完整的工具箱并根据您应用程序所需自定义构造。对于本应用程序示例,您可以换用 Google Ajax API 来访问您所需要的工具箱的各个部分。这很方便,而且具有性能优势,因为 Google 的 Dojo 版本是通过 Google 自己的高效内容发布网站(CDN)提供的。 您的应用程序是以数据为中心的,因此开始时可以加入一些数据。我们将使用 Dojo 创建 UI 来添加 注意在 清单 8 中,您引用了来自 Google CDN 的基础 Dojo 库。完成之后,您就可以使用 然后可以使用 Dojo 为按钮点击关联一个事件处理函数。事件处理函数停止表单提交,并使用在 该表单,与 清单 8 中的一样,是一个有效的 HTML 表单。尽管如此,元素中却添加了 Dojo 特定属性。请注意,有一个 这里,再次用到了 Dojo 的 Ajax 工具访问数据,此工具由先前创建的 JAX-RS 终端所提供。这次使用的是 这段代码将向 清单 12 显示了 Dojo 的 现在已完成足球应用程序示例,有很多方法显示联赛中的球员。您可以轻松扩展此处的简单示例,如添加球员编辑功能,对 grid 排序,甚至可以加入更多的数据,如比赛和结果。 本文演示了快速创建丰富的、以数据为中心的 web 应用程序的方法。使用了几项关键技术移除服务器端和客户端的繁杂的样板式代码:JPA、JAX-RS 和 Dojo。很多情况下,可以直接使用默认的惯例设置进一步减少 web 应用程序中的代码量。其结果是使用最少的代码创建非常先进的 web 应用程序。使用到的所有技术都是可扩展和具有量产品质的,因此您可放心扩展此应用程序示例(或您自己的应用程序),直接用于更加健壮的用例。更棒的是没有壁垒。使用的是服务器端的开放标准。例如,可以轻松转换数据库技术。在前台使用 REST 和 JSON,这意味着可以使用不同的 UI 套件,或者可以轻松连接上移动客户端。 学习 获得产品和技术 讨论Team
开始。清单 1 显示了此类。
清单 1. Team
数据模型类
@Entity
public class Team {
....
....@Id
....@GeneratedValue(strategy = GenerationType.IDENTITY)
....private long id;
....
....private String name;
....
....@OneToMany
....private Collection<Player> players;
....
// getters and setters........
}
@Entity
注释来声明该类将映射到数据库。可以选择指定类的表名,或者在使用与类相同的名称时实现约定。其次,您要注释该类的 id
字段。想要它成为表的主键,使用 @Id
注释来声明。从逻辑角度来看,id
并不重要;只将其用于数据库。因为想要数据库充分发挥其价值,使用 @GeneratedValue
注释。name
字段。它是球队的名字。请注意该字段没有 JPA 注释。默认情况下,这会映射到同名列,这已符合本文意图。最后,每个球队都有多名队员与之关联。使用 @OneToMany
注释让 JPA 运行时知道这是一个管理关系,球队有多名球员。在 Java 类中,这是 Player
对象的 java.util.Collection
。清单 2 显示 Player
类被引用。
清单 2. Player
数据模型类
@Entity
public class Player {
....
....@Id
....@GeneratedValue(strategy = GenerationType.IDENTITY)
....private long id;
....
....private String firstName;
....
....private String lastName;
....
....private int age;
....
....@ManyToOne (cascade=CascadeType.ALL)
....private Team team;
....
// getters and setters
}
Player
类与 清单 1 中的 Team
类类似。它的字段更多,但大多数情况下不必担心注释这些字段。JPA 将帮助您正确完成。清单 1 和 清单 2 的一个不同之处是如何指定 Player
类与 Team
类的关系。本例中使用 @ManyToOne
注释,因为一个 Team
中有多个 Players
。请注意,还指定了一个级联策略(cascade policy)。参考 JPA 文档,选择适用于您的本应用程序的级联策略。本例中,使用该级联策略可以同时创建新的 Team
和 Player
,JPA 将保存两者,这将方便应用程序开发。
清单 3. 足球应用程序的 persistence.xml
<persistence version="1.0"
....xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
....xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
....<persistence-unit name="soccer">
........<class>org.developerworks.soccer.model.Team</class>
........<class>org.developerworks.soccer.model.Player</class>
........<properties>
............<property name="hibernate.dialect"
value="org.hibernate.dialect.DerbyDialect" />
............<property name="hibernate.connection.driver_class"....
value="org.apache.derby.jdbc.EmbeddedDriver" />
............<property name="hibernate.connection.url"
value="jdbc:derby:soccerorgdb;create=true" />
............<property name="hibernate.hbm2ddl.auto" value="update" />
............<property name="hibernate.show_sql" value="true" />
............<property name="hibernate.connection.characterEncoding"
value="UTF-8" />
............<property name="hibernate.connection.useUnicode"
value="true" />
........</properties>
....</persistence-unit>
</persistence>
hibernate.hbm2ddl.auto
属性)。因此如果只运行应用程序,可以创建数据库及表。这有益与开发,但当然您会希望产品系统设置不一样。现在数据模型代码已经生成,并可通过 JPA 访问,我们将查看开放该数据,以便应用程序能使用它。Teams
以及创建新的 Teams
。清单 4 显示该类。
清单 4. Teams
的数据访问类
@Path("/teams")
public class TeamDao {
....
....private EntityManager mgr =
DaoHelper.getInstance().getEntityManager();
....
....@GET
....@Produces("application/json")....
....public Collection<Team> getAll(){
........TypedQuery<Team> query =
mgr.createQuery("SELECT t FROM Team t", Team.class);
........return query.getResultList();
....}
....
....@POST
....@Consumes("application/x-www-form-urlencoded")
....@Produces("application/json")
....public Team createTeam(@FormParam("teamName") String teamName){
........Team team = new Team();
........team.setName(teamName);
........EntityTransaction txn = mgr.getTransaction();
........txn.begin();
........mgr.persist(team);
........txn.commit();
........return team;
....}
}
TeamDao
。随后我们将注释这个类,但首先我们讲解一下数据访问。该类引用 JPA 类EntityManager
。这是 JPA 的中心类,并提供对底层数据库的访问。作为检索联赛中所有球队的首选方法,使用 EntityManager
来创建查询。查询使用 JPA 的查询语言,它与 SQL 相似。该查询获取所有 Teams
。对于第二个方法,只要用传入的球队名创建新的Team
,用 EntityManager
创建事务、保存新球队并执行事务。所有代码都是普通的 JPA 代码,因为所有类和接口都是基础 API 的一部分。@Path
注释来向基于 HTTP 的客户端公开此类。/teams
字符串指定该类的相对路径。完整的 URL 路径是 <host>/SoccerOrg/resources/teams
。/SoccerOrg
将会指定您的 web 应用程序的路径(当然,您可以配置成不同的,也可完全移除)。/resources
部分将用于指定 JAX-RS 终端。/teams
对应@Path
注释并指定使用哪些 JAX-RS 类。getAll
有一个相关的 @GET
注释。它指定如果接收到 HTTP GET
请求,则调用该方法。接着,该方法有个@Produces
注释。它声明响应的 MIME 类型。本例中,您要生成 JSON,因为它是基于 JavaScript 的客户端最易使用的。Team
对象的java.util.Collection
,又如何发送给 web 客户端?@Produces
注释声明您想以 JSON 方式发送,但 JAX-RS 如何将其序列化成 JSON?其实要完成这步您只需在 Team
类中多加一个注释,如 清单 5 中所示。
清单 5. 修改过的 Team
类
@XmlRootElement
@Entity
public class Team {
....
// unchanged from Listing 1
........
}
@XmlRootElement
注释,JAX-RS 现在可以将这个类转换成 JSON 对象。您也许记得这个类。它不是 JAX-RS 的一部分;而是 Java Architecture for XML Binding (JAXB) API 的一部分,而这又是核心 Java 1.6 平台的核心部分。该注释看上去像指出它用于 XML,但实际上可用于各种 JAXB 输出,包括 JSON。还有很多其他 JAXB 注释,但您在本例中只要用到这个。它只使用常用方法将Team
类所有字段序列化成 JSON。createTeam
方法。该方法使用 @POST
注释来指定当接收到 HTTP POST
请求时调用该方法。下一步,它用 @Consumes
注释来声明它能使用 哪种 POST
请求。此处指定的值对应于内容类型头部的 HTTP 请求。本例中,它指定为 x-www-form-urlencoded
。它是提交 HTML 表单时将会接收到的类型。因此,该方法会在 /SoccerOrg/resources/teams 终端提交 HTML 表单时调用。最后,请注意该方法只用一个输入参数,一个名为 teamName
的字符串。请注意该参数用 @FormParam
注释声明。它告诉 JAX-RS 运行时在请求主体内查找一个名为 teamName
的表单参数(注释值)并将其绑定到传入方法注释的变量中。有了这些,就可以轻松处理表单提交并且将其嵌入到代码中。如果提交很多数据,可能会导致混乱。本例中,您也许想使用更结构化的方法。清单 6 显示的是创建 Player
对象的简单例子。
清单 6. 使用 JAX-RS 处理结构化的 POST
数据
@Path("/players")
public class PlayerDao {
....private EntityManager mgr =
DaoHelper.getInstance().getEntityManager();
....
....@POST
....@Consumes("application/json")
....@Produces("application/json")
....public Player addPlayer(JAXBElement<Player> player){
........Player p = player.getValue();
........EntityTransaction txn = mgr.getTransaction();
........txn.begin();
........Team t = p.getTeam();
........Team mt = mgr.merge(t);
........p.setTeam(mt);
........mgr.persist(p);
........txn.commit();
........return p;
....}
....
....@GET
....@Produces("application/json")
....public List<Player> getAllPlayers(){
........TypedQuery<Player> query =
............mgr.createQuery("SELECT p FROM Player p", Player.class);
........return query.getResultList();
....}
}
PlayerDao
类与 清单 5 中的 TeamDao
类很像。需要检查的主要要差异是它的 addPlayer
方法。该方法处理 HTTP POST
请求,类似于 TeamDao
中的 createTeam
方法。然而,它使用 application/json — 也就是说它希望获得的是 JSON 数据。这有两个含义,首先,请求需要指定 application/json 的内容类型,从而可以调用该方法。其次,post 的主体应该是 JSON 数据。请注意该方法的输入参数是 JAXBElement<Player>
类型,也就是说它是 Player
对象的 JAXB 包装。它告诉 JAX-RS 自动将传送的数据解析成JAXBElement
包装,所以您不必编写任何解析代码。请注意,在方法的主体中,只用一行代码获取完整的 Player
对象,然后它可使用 JPA 将新的 Player
保存到数据库。
清单 7. 应用程序的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
....xmlns="http://java.sun.com/xml/ns/javaee"
....xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
....xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
....id="Soccer_Org" version="2.5">
<display-name>SoccerOrg</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
<servlet>
<servlet-name>JAXRS-Servlet</servlet-name>
<servlet-class>com.sun.jersey.spi.container.servlet.
ServletContainer</servlet-class>
<init-param>
<param-name>com.sun.jersey.config.property.packages</param-name>
<param-value>org.developerworks.soccer.model;org.developerworks.
soccer.web</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>JAXRS-Servlet</servlet-name>
<url-pattern>/resources/*</url-pattern>
</servlet-mapping>
</web-app>
Teams
。清单 8 显示所有您所需要的代码。
清单 8. 使用 Dojo 添加 Teams
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test Harness</title>
<link rel="stylesheet" type="text/css"
....href="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dijit
/themes/soria/soria.css"/>
<script type="text/javascript"
src="http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojo/dojo.xd.js"
djConfig="parseOnLoad: true"></script>
<script type="text/javascript">
....function init(){
.... var btn = dijit.byId("addTeamBtn");
.... dojo.connect(btn, "onClick", function(event){
.... ....event.preventDefault();
event.stopPropagation();
dojo.xhrPost({
form : dojo.byId("addTeamForm"),
....handleAs: "json",
....load : function(data){
........addTeam(data);
........alert("Team added");
....},
....error : function(error){
.... alert("Error adding team: " + error);
....}
});
.... });
....}
</script>
</head>
<body class="soria">
....Add a Team<br/>
....<form method="POST" action="/SoccerOrg/resources/teams" id="addTeamForm">
........<label for="teamName">Team Name:</label>
........<input name="teamName" type="text" id="teamName"
dojoType="dijit.form.TextBox"/>
........<button type="submit" id="addTeamBtn" dojoType=
"dijit.form.Button">Add Team</button>
....</form>
....<script type="text/javascript">
........dojo.require("dijit.form.Button");
.... dojo.require("dijit.form.TextBox");
.... dojo.addOnLoad(init);
....</script>
</body>
</html>
dojo.require
函数请求 Dojo 额外部分(见 清单 8 中代码底部)。请注意您刚创建了一个普通 HTML 表单,但使用了一些额外的 Dojo 相关属性。这告诉 Dojo 在可视化元素中加入额外的样式,并在对应的 DOM 元素中加入额外功能。告诉 Dojo 一旦其他东西加载(所有 Dojo 组件)就执行 init
函数。此函数中,使用 dijit.byId
函数取得表单中按钮的事件处理函数。Dijit
是 Dojo 的小部件库。可以使用 dojo.byId
来根据 ID 引用任何 DOM 元素,但类似的 dijit.byId
会赋给小部件额外的功能(如果元素标记为 widget,则如 清单 8 中按钮所示)。dojo.xhrPost
函数中使用 Ajax。该函数使 POST
HTML 表单很容易。它通过检测 HTML 表单的 action
属性区分 Ajax 客户端。它还读取所有的表单元素并将它们传递到 Ajax POST
。当它接收到服务器返回的响应,它就调用传递给 xhrPost
的 load
函数。请注意,通过设置传递给 xhrPost
函数的handleAs
属性来返回 JSON。很快将看到 addTeam
函数,但可以直接传入数据对象,因为已将 JSON 数据安全解析成可用的 JavaScript 对象。该 addTeam
函数将与另一表单联合使用,来添加 Players
。清单 9 显示的是表单的 HTML。
清单 9. 添加 Player
表单
Add a Player<br/>
<form id="addPlayerForm" action="/SoccerOrg/resources/players">
....<label for="firstName">First Name:</label>
....<input name="firstName" id="firstName" type="text"
dojoType="dijit.form.TextBox"/>
....<label for="lastName">Last Name:</label>
....<input type="text" name="lastName" id="lastName"
dojoType="dijit.form.TextBox"/><br/>
....<label for="age">Age:</label>
....<input type="text" name="age" id="age"
dojoType="dijit.form.TextBox"/><br/>
....<label for="team">Team:</label>
....<select id="team" name="team" dojoType="dijit.form.
Select"></select>
....<button type="submit" id="addPlayerBtn" dojoType=
"dijit.form.Button">Add Player</button>
</form>
<script type="text/javascript">
dojo.require("dijit.form.Select");
dojo.addOnLoad(loadTeams);
</script>
SELECT
元素,它将作为 Teams
的下拉列表,让用户可选择将 Player
加入哪个 Team
。这是需要从服务器加载的动态数据。请注意在启动时还加入了另一个函数 — loadTeams
函数。它用于从服务器加载球队。清单 10 显示了该函数,以及 addTeam
函数,如您所见,它在 清单 9曾被引用。
清单 10. loadTeams
和 addTeam
函数
var teams = {};
function loadTeams(){
....var select = dijit.byId("team");
....dojo.xhrGet({
........url: "/SoccerOrg/resources/teams",
........handleAs:"json",
........load : function(data){
............var i = 0;
............for (i in data.team){
................addTeam(data.team[i]);
............}
........},
........error : function(error){
............alert("Error loading team data: " + error);
........}
....});
}
function addTeam(team){
....teams[team.id] = team;
....var select = dijit.byId("team");
....var opt = {"label":team.name, "value":team.id};
....select.addOption(opt);
}
dojo.xhrGet
,它向 Ajax 终端发出 HTTP GET
请求。在此例中,需要指定它的 URL,否则它与 清单 9 中所看到的 xhrPost
一样。最后,是 addTeam
方法。这里再次使用 Dojo 小部件的额外功能向显示球队的下拉列表轻松添加新选项。现在已经看到球员表单是如何创建的,再看看处理提交的代码(见 清单 11)。
清单 11. 添加新 Player
var button = dijit.byId("addPlayerBtn");
dojo.connect(button, "onClick", function(event){
.... event.preventDefault();
event.stopPropagation();
var data = dojo.formToObject("addPlayerForm");
var team = teams[data.team];
data.team = team;
data = dojo.toJson(data);
var xhrArgs = {
postData: data,
handleAs: "json",
load: function(data) {
alert("Player added: " + data);
dojo.byId("gridContainer").innerHTML = "";
loadPlayers();
},
error: function(error) {
alert("Error! " + error);
},
url: "/SoccerOrg/resources/players",
headers: { "Content-Type": "application/json"}
};
var deferred = dojo.xhrPost(xhrArgs);
});
PlayerDao.addPlayer
方法提交数据,该方法您已在前面的 清单 6 中见过。这段代码预计将 Player
对象序列化成 JSON 数据结构。首先,您再次使用 Dojo 来包装表单上按钮点击处理函数。下一步,使用 Dojo 的函数 dojo.formToObject
来将表单中数据转换成 JavaScript 对象。然后稍微修改 JavaScript 对象,以匹配服务器能接收的结构。然后使用 Dojo 的 dojo.toJson
函数将它转换成 JSON 字符串。现在它传给 dojo.xhrPost
,与 addTeam
表单提交方式一样。请注意,您添加了 HTTP 头部 Content-Type
来保证它路由到 PlayerDao.addPlayer
方法。xhrPost
也有一个 load
函数,它会在 Ajax 请求从服务器携带成功响应返回后调用。本例中,它会清空页面上名为 gridContainer
的元素,并调用名为 gridContainer
的元素,loadPlayers
的函数。这是另一个用来显示所有球员的 Dojo 小部件。清单 12 显示用于此目的的 HTML 和 JavaScript 。
清单 12. Player grid HTML 和 JavaScript
<style type="text/css">
@import
"http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojox/grid/resources/Grid.css";
@import
"http://ajax.googleapis.com/ajax/libs/dojo/1.4/dojox/grid/resources/soriaGrid.css";
.dojoxGrid table { margin: 0; }
html, body { width: 100%; height: 100%; margin: 0; }
</style>
<script type="text/javascript">
function loadPlayers(){
....var pStore = new dojox.data.JsonRestStore({
........target: "/SoccerOrg/resources/players"
....});
....pStore._processResults = function(data, deferred){
........return {totalCount:deferred.fullLength || data.player.length,
items: data.player};
....};
var pLayout = [{
field: "firstName",
name: "First Name",
width: "200px"
},
{
field: "lastName",
name: "Last Name",
width: "200px"
},
{
field: "age",
name: "Age",
width: "100px"
},
{
field : "teamName",
name : "Team",
width: "200px"
}];
var grid = new dojox.grid.DataGrid({
store: pStore,
clientSort: true,
rowSelector: "20px",
structure: pLayout
}, document.createElement("div"));
dojo.byId("gridContainer").appendChild(grid.domNode);
grid.startup();
}
</script>
<div id="gridContainer" style="width: 100%; height: 100%;"></div>
<script type="text/javascript">
dojo.require("dojox.grid.DataGrid");
dojo.require("dojox.data.JsonRestStore");
dojo.addOnLoad(loadPlayers);
</script>
DataGrid
小部件。它是 Dojo 中一个更丰富的小部件,因此也需要额外的 CSS。要新建一个 grid,要做两件事。首先,需要创建数据源。本例中,是来自服务器的 JSON 数据,因此创建一个新的 JsonRestStore
对象,并将它指向将会产生数据的服务器 URL。然后覆盖 _processResults
。只需要这样做,因为它能预计接收 JSON 数组的数据,并且 JAX-RS 终端将会生成更复杂一点的对象(它有一个属性,名为 player
,它的值是 JsonRestStore
预计接收的 JSON 数组)。grid 还需要布局元数据,以描述显示哪些列,以及 JavaScript 对象对应的属性是什么。然后就可以创建 grid 并将它放入 DOM 目录树中。
描述
名字
大小
下载方法
文章源代码
SoccerOrg.zip
14KB
HTTP
相关推荐
`javax.xml.ws.Service`是JAX-WS规范的一部分,用于创建和实例化Web服务客户端。当这个类报错,通常是因为缺失了如wsimport工具或者相关的API依赖。而这个压缩包提供了解决这个问题的解决方案,用户只需将提供的四个...
标题中的“一个包含jax-ws和jax-rs的例子(含服务端和客户端)”是指这是一个示例项目,它演示了如何使用Java API for XML Web Services (JAX-WS)和Java API for RESTful Web Services (JAX-RS)来创建和消费Web服务。...
Java API for XML Web Services (JAX-WS) 是Java平台上的一个标准接口,用于创建和消费Web服务。它是Sun Microsystems在2004年推出的一个重要框架,旨在简化Web服务的开发,使得Java开发者能够更方便地实现基于SOAP...
Learn how to design and develop distributed web services in Java using RESTful architectural principals and the JAX-RS specification in Java EE 6. With this hands-on reference, you'll focus on ...
Learn how to design and develop distributed web services in Java, using RESTful architectural principles and the JAX-RS 2.0 specification in Java EE 7. By focusing on implementation rather than theory...
本篇将详细介绍如何使用Java技术栈,特别是JAX-WS和JAX-RS,以及Maven和Spring来创建这两种不同类型的Web服务。 首先,让我们关注SOAP Web服务的创建,这是通过JAX-WS实现的。JAX-WS是Java API for XML Web ...
SpringMVC和JAX-RS是两种在Java世界中广泛使用的Web开发框架,它们都用于构建RESTful服务,但有着不同的设计哲学和技术实现。这个压缩包"SpringMVC精品资源--JAX-RS & SpringMVC supported maven build.zip"显然是一...
3. **实体序列化与反序列化**: JAX-RS支持自动将Java对象转换为JSON或XML,反之亦然,这通常通过实现MessageBodyReader/Writer接口或者使用库如Jackson或Gson完成。 4. **提供者与容器**: JAX-RS不强制使用特定的...
在实际项目中,你需要根据需求选择合适的jar包,并在应用的`web.xml`或使用Java配置来注册JAX-RS的应用实例。例如,使用Jersey,你可以这样配置: ```xml <!-- web.xml --> <servlet-name>Jersey Web Application...
综上所述,JAX-RS 2.1规范为Java开发者提供了一套完整的指导方针和工具集,帮助他们在遵循RESTful架构风格的基础上,快速构建Web服务和客户端应用程序。它不仅简化了资源的创建和配置,还提供了强大的运行时支持,...
JAX-RS,全称Java API for RESTful Web Services,是Java平台上的一个标准,用于构建RESTful风格的Web服务。REST(Representational State Transfer)是一种轻量级、基于HTTP协议的设计模式,常用于实现分布式系统中...
1. **JAX-RS基础**:JAX-RS是Java标准JSR 311和JSR 339的一部分,用于简化创建RESTful Web服务。它通过注解如`@Path`, `@GET`, `@POST`, `@PUT`, `@DELETE`等,使得开发者可以直接在Java方法上声明HTTP操作。 2. **...
作者Bill Burke以其在Java技术方面的深厚底蕴和对RESTful架构的深刻理解,引领读者深入理解并掌握JAX-RS 2.0标准。 书中首先介绍了REST的概念以及其与HTTP的重生之间的联系。REST(Representational State Transfer...
JAX-RS(JSR 311)指的是Java API for RESTful Web Services,Roy Fielding也参与了JAX-RS的制订,他在自己的博士论文中定义了REST。对于那些想要构建RESTful Web Services的开发者来说,JAX-RS给出了不同于JAX-WS...
JAX-RS 使用注解来定义资源的行为和属性,使得开发者可以轻松地创建 RESTful Web 服务。 @Path 注解 @Path 注解是 JAX-RS 中最基本的注解之一,它用来指定资源的 URI 路径。该注解可以应用在类级别和方法级别上。在...
5. **启动配置**:在Java应用服务器或容器中配置JAX-RS应用程序,通常通过`Application`类或`web.xml`配置文件完成。 在"bookkeeping"实例中,开发者可能已经创建了一个`BookkeepingResource`类,其中包含了处理...
通过理解和实践这个“RESTfulExample”,你可以熟练掌握如何在JAX-RS和Jersey环境中处理文件上传,为你的Web服务增加更多功能。这是一项基础但重要的技能,对于构建交互性强、数据传输丰富的应用程序非常有价值。
CXF允许开发者使用JAX-RS和JAX-WS标准来编写Web服务,并提供了丰富的功能,如WSDL(Web Services Description Language)生成、客户端API生成、数据绑定、安全支持等。 **4. CXF与Spring的整合** 将CXF与Spring...
本篇文章将深入探讨如何使用CXF和Spring框架实现基于JAX-RS的Web服务,包括基本的增、删、改、查操作。 1. **环境准备** - **JDK**: 首先确保安装了支持JAX-RS的Java版本,通常JDK 8或以上。 - **Maven**: 项目...
RESTLet是JAX-RS的一个实现,它提供了一种灵活的方式来构建RESTful应用程序。RESTLet框架支持多种功能,包括URI模板、过滤器、客户端代理、安全性和国际化。这个框架特别适合于那些希望以更直接和自定义的方式处理...