# Api接口开发
本文作者:youhong.ai (opens new window)
部门: 上海大区EBU7部开发1部
职位: 开发工程师
接口开发在我们项目开发过程中是非常多的,也是我们前后端数据交互和第三方数据交互的主要手段之一,本文章将重点介绍如何使用 Jersey 的 API 和注解来创建 RESTful Web 服务。我们将创建一个简单的示例,展示如何定义资源类、路径、HTTP 方法等。
# 框架介绍
Ecology 系统使用的RESTful Web Service框架是Jersey
,Jersey
是JAX-RS标准的参考实现,是Java领域中最纯正的REST服务开发框架。项目地址:Jersey (opens new window)
Jersey源代码的托管地址是JerseyGitHub (opens new window),我们可以通过git命令,将Jersey主干代码迁出到本地。示例如下。
git clone https://github.com/jersey/jersey.git
Jersey问答
StackOverflow是专业的程序员问答系统,Jersey的问题列表地址是:http://stackoverflow.com/questions/tagged/jersey (opens new window)。该链接在Jersey官网首页底部被列出,可见Jersey对问答系统的重视。另外,邮件列表也是一种知识共享的途径,读者可以自行订阅,地址是:https://jersey.java.net/mailing.html (opens new window)。
# 接口开发
注意: ecology的接口开发,在开发完接口后,进行访问接口时,有固定前缀/api
# Jersey 注解
Jersey 使用一组注解来简化 RESTful 服务的开发。以下是一些常用的 Jersey 注解:
@Path
: 定义资源类或方法的路径。@GET
,@POST
,@PUT
,@DELETE
: 定义 HTTP 方法。@PathParam
: 从 URI 中提取路径参数。@QueryParam
: 从查询参数中提取参数。@Produces
: 指定资源类或方法的响应类型。@Consumes
: 指定资源类或方法能够处理的请求类型。
# 创建资源类
首先,让我们创建一个简单的资源类。在 com.api.example.web
包下创建一个名为 MyResourceApi.java
的类:
package com.api.example.web;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
/**
* <h1>我的自定义api</h1>
* </br>
* <p>create: 2023/12/23 18:48</p>
*
* <p></p>
*
* @author youHong.ai
*/
@Path("/myresource")
public class MyResourceApi {
@GET
public String get() {
return "Hello from MyResource!";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
在上述代码中,我们使用了 @Path("/myresource")
注解来定义资源的路径,使用 @GET
注解来定义处理 GET 请求的方法。
看下请求结果
Hello from MyResource!
# 路径参数
Jersey 允许你从 URI 中提取路径参数。修改 MyResourceApi.java
,添加一个带路径参数的方法:
package com.api.example.web;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
/**
* <h1>我的自定义api</h1>
* </br>
* <p>create: 2023/12/23 18:48</p>
*
* <p></p>
*
* @author youHong.ai
*/
@Path("/myresource")
public class MyResourceApi {
@GET
public String get() {
return "Hello from MyResource!";
}
@GET
@Path("/{name}")
public String getByName(@PathParam("name") String name) {
return "Hello, " + name + "!";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
在上述代码中,我们使用了 @PathParam
注解来提取路径参数,并且使用@Path
为方法也添加了路径映射。例如,访问 `/myresource/Ecology 将返回 "Hello, Ecology!"。
# 查询参数
Jersey 也支持从查询参数中提取参数。修改 MyResourceApi.java
,添加一个带查询参数的方法:
package com.api.example.web;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.QueryParam;
/**
* <h1>我的自定义api</h1>
* </br>
* <p>create: 2023/12/23 18:48</p>
*
* <p></p>
*
* @author youHong.ai
*/
@Path("/myresource")
public class MyResourceApi {
@GET
public String get() {
return "Hello from MyResource!";
}
@GET
@Path("/greet")
public String greet(@QueryParam("name") String name) {
return "Hello, " + name + "!";
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
在上述代码中,我们使用了 @QueryParam
注解来提取查询参数。例如,访问 /myresource/greet?name=Ecology
将返回 "Hello, Ecology!"。
# 响应类型
你可以使用 @Produces
注解来指定资源类或方法的响应类型。默认情况下,Jersey 会将返回的对象转换为 JSON。
package com.api.example.web;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
/**
* <h1>我的自定义api</h1>
* </br>
* <p>create: 2023/12/23 18:48</p>
*
* <p></p>
*
* @author youHong.ai
*/
@Path("/myresource")
public class MyResourceApi {
@GET
public String get() {
return "Hello from MyResource!";
}
@GET
@Path("getText")
@Produces(MediaType.TEXT_PLAIN)
public String getText() {
return "Hello from MyResource!";
}
@GET
@Path("getJSON")
@Produces(MediaType.APPLICATION_JSON)
public String getJSON() {
Map<String,Object> result = new HashMap<>();
result.put("code",200);
result.put("msg", "success");
result.put("data", "Hello from MyResource!");
return JSONObject.toJSONString(result);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
在上述代码中,我们使用了 @Produces(MediaType.TEXT_PLAIN)
注解来指定响应类型为纯文本。使用@Produces(MediaType.APPLICATION_JSON)
注解来指定响应类型为json
# 请求参数类型
package com.api.example.web;
import com.alibaba.fastjson.JSONObject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import java.util.HashMap;
import java.util.Map;
/**
* <h1>我的自定义api</h1>
* </br>
* <p>create: 2023/12/23 18:48</p>
*
* <p></p>
*
* @author youHong.ai
*/
@Path("/myresource")
public class MyResourceApi {
@GET
public String get() {
return "Hello from MyResource!";
}
@POST
@Path("postJSON")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String postJSON(String json) {
Map<String,Object> result = new HashMap<>();
result.put("code",200);
result.put("msg", "success");
result.put("data",json);
return JSONObject.toJSONString(result);
}
@POST
@Path("postJSONObj")
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public String postJSONObj(Map<String,Object> params) {
Map<String,Object> result = new HashMap<>();
result.put("code",200);
result.put("msg", "success");
result.put("data",params);
return JSONObject.toJSONString(result);
}
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# 升级打包
当我们写完接口后,如何让接口生效呢,让接口运行在我们的ecology服务其中?
接下来给大家讲解说明一下如何升级打包
# 代码结构整理
在开发规范
中我们提到了开发的代码有一定的规范建议,所以我们在开发过程中代码会在不同的目录结构下,当我们写完代码后,编译完成的class
文件也必须要保持原有的src
目录结构(包名结构),我们需要将涉及到的本次开发的所有class
文件进行整合打包,其路径一定与原来的src
目录结构一致,只不过上层目录不同。
源码的上层目录是src
,但是class
最终整理打包的目录需要看当前运行的服务器环境(服务运行的根路径),如果是信创环境,则是ecology/WEB-INF/classes
,如果是非信创环境(Resin)则是ecology/classbean
,后续举例以Resin
为例
那么按照上述接口开发
中的案例文件com.api.example.web.MyResourceApi
最终需要生成的压缩包目录则是
ecology/com/api/example/web/MyResourceApi.class
如图所示,这样将升级包压缩后,上传服务器,与ecology同级目录下解压文件(解压如果涉及到覆盖文件,请记得备份原始文件),合并内容即可完成升级,然后启动服务器,则可以测试我们刚写的代码
如果存在第三方jar包的依赖,则将jar包存放在ecology/WEB-INF/lib
下
将升级包与ecology放到同级目录下
然后停止服务器,解压文件
解压成功合并文件之后,重启服务器,访问我们之前写好的接口