Restful接口学习笔记
框架:Jersey架构,Maven管理
前言:个人认为restful总体上采用的是MVC架构思想,但是Jersey这个框架体现的不明显。所以我在我的代码中模块逻辑操作处理(相当于代码中的resource文件夹),还有控制块数据操作处理(即代码中的server文件夹)完全分成两部分。而MVC架构中的视图部分由于没有需求暂时没有开发。REST 是一种架构原则,其中将 web 服务视为资源,可以由其 URL 唯一标识。RESTful Web 服务的关键特点是明确使用 HTTP 方法来表示不同的操作的调用。
创建一个helloworld Maven工程:
l 使用工程根目录下的pox.xml文件实现工程的建立和配置管理
l 工程资源被加载在src/main/java中
下面这个在com.example包中的类就是资源类,实现了一个简单的JAX-RS资源:
package com.example;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
@Path("helloworld") //标记该资源的路径
public class HelloWorldResource {
@GET //使用HTTP GET操作方法
@Produces("text/plain") //以text/plain类型发送给客户端
public String getHello() {
return "Hello World!";
}
}
资源加载器:
public class MyApplication extends Application {
@Override
public Set<Class<?>> getClasses() {
final Set<Class<?>> classes = new HashSet<Class<?>>(); // register root resource
classes.add(HelloWorldResource.class);
return classes;
}
}
启动工程,网页中输入URL:
http://localhost:8080/myapp/helloworld
显示:Hello World!
Jersey架构和Maven工程的一些相关知识:
ujersey常用注解解释(这里只是到现在为止我自己的项目里用到过的):
Annotation | 作用 | 说明 |
@GET | 查询请求 | 相当于数据库的查询数据操作 |
@POST | 插入请求 | 相当于数据库的插入数据操作 |
@PUT | 更新请求 | 相当于数据库的更新数据操作 |
@DELETE | 删除请求 | 相当于数据的删除数据操作 |
@Path | url路径 | 定义资源的访问路径,client通过这个路径访问资源。比如:@Path("user") |
@Produces | 指定返回MIME格式 | 资源按照指定数据格式返回,可取的值有:MediaType.APPLICATION_XXX。比如:@Produces(MediaType.APPLICATION_XML) |
@Consumes | 接受指定的MIME格式 | 只有符合这个参数设置的请求再能访问到这个资源。比如@Consumes("application/x-www-form-urlencoded") |
@PathParam | uri路径参数 | 写在方法的参数中,获得请求路径参数。比如:@PathParam("username") String userName |
@QueryParam | uri路径请求参数 | 写在方法的参数中,获得请求路径附带的参数。比如:@QueryParam("desc") String desc |
@DefaultValue | 设置@QueryParam参数的默认值 | 如果@QueryParam没有接收到值,就使用默认值。比如:@DefaultValue("description") @QueryParam("desc") String desc |
@FormParam | form传递的参数 | 接受表单传递过来的参数。比如:@FormParam("name") String userName |
@Context | 获得一些系统环境信息 | 通过@Context可以获得以下信息:UriInfo、ServletConfig、ServletContext、HttpServletRequest、HttpServletResponse和HttpHeaders等 |
upom.xml文件配置:
使用Maven工具管理工程非常的方便,相关的配置只需要修改pom.xml文件就可以轻松办到,看下面的例子
设置组ID、artifactID和版本号:
<groupId>com</groupId>
<artifactId>VIID</artifactId>
<version>V5</version>
<packaging>war</packaging>
<name>com.sdk Maven Webapp</name>
<url>http://maven.apache.org</url>
添加需要的依赖包:
<dependency>
<groupId>org.glassfish.jersey.media</groupId>
<artifactId>jersey-media-multipart</artifactId>
<version>2.23.2</version>
</dependency>
相关依赖包查询网址:http://maven.outofmemory.cn/或者http://mvnrepository.com/或其它。
当需要添加新的依赖库时,只需要查到相关的依赖库ID和版本号,将其添加到pom.xml中点击Maven Projects下的刷新按钮,Maven工具会自动下载。
添加额外的配置文件或者其它资源:
当需要添加新的依赖库时,只需要查到相关的依赖库ID和版本号,将其添加到pom.xml中点击Maven Projects下的刷新按钮,Maven工具会自动下载。
添加额外的配置文件或者其它资源:
<resources>
<resource>
<directory>src/main/resource</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
<include>**/*.cfg</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
这个可以将src/main/resource下文件一同编译进classes文件下方便调用
添加插件:
添加插件:
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>maven-jetty-plugin</artifactId>
<version>6.1.26</version>
</plugin>
加入jetty插件,方便程序调试
将pom.xml全部配置好后记得点击刷新按钮。
u web.xml配置:
这个文件主要用来配置Jersey Servlet
将pom.xml全部配置好后记得点击刷新按钮。
u web.xml配置:
这个文件主要用来配置Jersey Servlet
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<servlet>
<servlet-name>VIID.MyApplication</servlet-name>
<servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
<!-- 配置自己的资源加载类去加载资源 -->
<init-param>
param-name>javax.ws.rs.Application</param-name>
<param-value>VIID.MyApplication</param-value>
</init-param>
<!-- 配置默认的资源包路径,使用默认的配置类去加载资源 -->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>VIID.MyApplication</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
以上的VIID.MyApplication为自己写好的资源加载器,个人喜欢这一种方式加载自己想要加载的资源,可控性强。接下来介绍这个资源加载器如何编写。
u 资源加载器编写:
u 资源加载器编写:
public class MyApplication extends ResourceConfig {
public MyApplication() {
// 加载resources
register(HelloResource.class);
register(UserResource.class);
// 注册数据转换器
register(JacksonJsonProvider.class);
// 注册日志
register(LoggingFilter.class);
}
}
当然,如果觉得把自己写的资源一个一个使用register()方法注册上去太麻烦,也可以像之前讲的一样,把所有资源放在VIID.resource文件夹里,统一注册:
u 编写自己的资源:
接下来是一些注解的使用方法(参照前文的Jersey常用注释解释表格):
u Jersey客户端代码编写示例:
构建QueryParam参数:
构建表单:
表单中加入文件:
public MyApplication() {
/** 注册资源 */
packages("VIID.resource");
register(LoggingFeature.class);
register(MultiPartFeature.class);
register(JacksonJsonProvider.class);
property(JsonGenerator.PRETTY_PRINTING, true);
}
u 编写自己的资源:
@Path("helloworld") //标记该资源的路径
public class HelloWorldResource {
@GET //使用HTTP GET操作方法
@Produces("text/plain") //以text/plain类型发送给客户端
public String getHello() {
return "Hello World!";
}
}
接下来是一些注解的使用方法(参照前文的Jersey常用注释解释表格):
@Path("user")
public class UserResource {
//这个类的方法都在下面
//这个方法主要介绍@GET,@Path,@Produces,@PathParam,@DefaultValue,@QueryParam注解的使用
@GET
@Path("{username}")
@Produces(MediaType.APPLICATION_JSON)
public User getUser(@PathParam("username") String userName,
@DefaultValue("description") @QueryParam("desc") String desc) {
User user = new User();
user.setId(new Random().nextInt());
user.setUserName(userName);
user.setDesc(desc);
return user;
}
//访问URL:{host}:{port}/{serviceName}/user/username?desc=xxx;username可以随便写
//这个方法主要介绍@POST,@Consumes,@FormParam,@Context注解的使用
@POST
@Path("updateUser")
@Consumes("application/x-www-form-urlencoded")
publicString updateUser(@FormParam("name") String userName,
@FormParam("desc") String desc,
@Context HttpHeaders headers) {
String token =
headers.getRequestHeader(HttpHeaders.AUTHORIZATION).get(0);
User user = new User();
user.setId(1);
user.setUserName(userName);
user.setDesc(desc);
System.out.println(user + access_token);
return token;
//访问URL:{host}:{port}/{serviceName}/user/updateUser;这个是通过提交表单访问的
}
}
完成以上这些,restful接口工程基本可以建立并使用了。
u Jersey客户端代码编写示例:
public static String path = "http://localhost:8080/VIID/";
public static void test(){
ClientConfig cc = new DefaultClientConfig();
Client client = Client.create(cc);
WebResource resource = client.resource(path + "gethello");
JSONObject req = new JSONObject();
try {
req.put("name", "Jake");
} catch (JSONException e) {
e.printStackTrace();
}
ClientResponse response = resource
.header(HttpHeaders.AUTHORIZATION, "AGHJ3ad") //给http请求数据头中的AUTHORIZATION域加入数据
.accept(MediaType.APPLICATION_JSON) //设定接收数据为JSON格式
.type("application/json") //设定发送数据为JSON格式
.post(ClientResponse.class, req); //使用post请求,请求参数为req
JSONObject resp = response.getEntity(JSONObject.class); //获得服务器返回数据
System.out.println(resp.toString());
}
构建QueryParam参数:
MultivaluedMapImpl params = new MultivaluedMapImpl();
params.add("desc ", s);
ClientResponse response = resource.queryParams(params)
.header(HttpHeaders.AUTHORIZATION, UserLoginCode)
.get(ClientResponse.class);
构建表单:
FormDataMultiPart formDataMultiPart = new FormDataMultiPart();
formDataMultiPart.field("filename", "008");
表单中加入文件:
FileDataBodyPart fdp = new FileDataBodyPart("file", new File(filename));
FormDataMultiPart formDataMultiPart = newFormDataMultiPart();
formDataMultiPart.field("filename", "008")
.bodyPart(fdp);ClientResponse response = resource
.type(MediaType.MULTIPART_FORM_DATA)
.post(ClientResponse.class, formDataMultiPart);
pom.xml client依赖库:
u Tomcat部署
首先将整个工程使用IDEA中Jetty插件打包,或者到工程目录下cmd输入命令:
mvn clean package(这个得先建立maven环境变量);
再将编译好的war包放在Tomcat目录中的webapp目录下,重启Tomcat即可。
我这里建议所有调通以后,使用Jerry插件调试,再使用Tomcat部署
<dependency>
<groupId>com.sun.jersey</groupId>
<artifactId>jersey-client</artifactId>
<version>1.18.3</version>
</dependency>
u Tomcat部署
首先将整个工程使用IDEA中Jetty插件打包,或者到工程目录下cmd输入命令:
mvn clean package(这个得先建立maven环境变量);
再将编译好的war包放在Tomcat目录中的webapp目录下,重启Tomcat即可。
我这里建议所有调通以后,使用Jerry插件调试,再使用Tomcat部署
(不过有时候Jetty插件和Tomcat默认配置不太一样,所以个别情况下结果会友差别,需要注意)。