加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Jersey框架一:Jersey RESTful WebService框架简介

发布时间:2020-12-16 23:04:52 所属栏目:安全 来源:网络整理
导读:Jersey系列文章: Jersey框架一:Jersey RESTful WebService框架简介 Jersey框架二:Jersey对JSON的支持 Jersey框架三:Jersey对HTTPS的支持 ? 开发RESTful WebService意味着支持在多种媒体类型以及抽象底层的客户端-服务器通信细节,如果没有一个好的工具包

Jersey系列文章:

Jersey框架一:Jersey RESTful WebService框架简介

Jersey框架二:Jersey对JSON的支持

Jersey框架三:Jersey对HTTPS的支持

?

开发RESTful WebService意味着支持在多种媒体类型以及抽象底层的客户端-服务器通信细节,如果没有一个好的工具包可用,这将是一个困难的任务

为了简化使用JAVA开发RESTful WebService及其客户端,一个轻量级的标准被提出:JAX-RS API

Jersey RESTful WebService框架是一个开源的、产品级别的JAVA框架,支持JAX-RS API并且是一个JAX-RS(JSR 311和 JSR 339)的参考实现

Jersey不仅仅是一个JAX-RS的参考实现,Jersey提供自己的API,其API继承自JAX-RS,提供更多的特性和功能以进一步简化RESTful service和客户端的开发

?

Maven版本:3.1.0

Jersey版本:1.18

JDK版本:1.7.0_65

一,服务端

Maven配置如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
			http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>JERSEY_SERVER</groupId>
	<artifactId>JERSEY_SERVER</artifactId>
	<version>1.0</version>
	<dependencies>
		<dependency>
	    	<groupId>com.sun.jersey</groupId>
		    <artifactId>jersey-server</artifactId>
		    <version>1.18</version>
		</dependency>
		<dependency>
		    <groupId>com.sun.jersey</groupId>
		    <artifactId>jersey-grizzly2</artifactId>
		    <version>1.18</version>
		</dependency>
	</dependencies>
</project>

首先介绍几个注解:

@Path

用来为资源类或方法定义URI,当然除了静态URI也支持动态URI

@Path("service") 
public class MyResource {
	@Path("{sub_path}")
    @GET
    public String getResource(@PathParam("sub_path") String resourceName) {
......

如果此时客户端请求的URI为http://127.0.0.1:10000/service/sean,则sub_path的值为sean

@PathParam用来将请求URI的一部分作为方法参数传入方法中

对URI的动态部分,可以自定义校验正则表达式,如果请求参数校验失败,容器返回404 Not Found

@Path("{sub_path:[A-Z]*}")

@GET

表明被注解的方法响应HTTP GET请求,@POST@PUT@DELETE同理

@Consumes

定义请求的媒体类型,如果不指定,则容器默认可接受任意媒体类型,容器负责确认被调用的方法可接受HTTP请求的媒体类型,否则返回415 Unsupported Media Type

方法级注解将覆盖类级注解

@Produces

定义响应媒体类型,如果不指定,则容器默认可接受任意媒体类型,容器负责确认被调用的方法可返回HTTP请求可以接受媒体类型,否则返回406 Not Acceptable

方法级注解将覆盖类级注解

@QueryParam

public String getResource(
		@DefaultValue("Just a test!") @QueryParam("desc") String description) {
	......
}

如果请求URI中包含desc参数,例如:http://127.0.0.1:10000/service/sean?desc=123456,则desc参数的值将会赋给方法的参数description,否则方法参数description的值将为@DefaultValue注解定义的默认值

@Context

将信息注入请求或响应相关的类,可注入的类有:Application,UriInfo,Request,HttpHeaders和SecurityContext

@Singleton@PerRequest

默认情况下,资源类的生命周期是per-request,也就是系统会为每个匹配资源类URI的请求创建一个实例,这样的效率很低,可以对资源类使用@Singleton注解,这样在应用范围内,只会创建资源类的一个实例

服务端程序如下:

package com.sean;
 
import java.io.IOException;
import java.net.URI;
import java.util.Iterator;

import javax.ws.rs.Consumes;
import javax.ws.rs.DefaultValue;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Request;
import javax.ws.rs.core.UriBuilder;
import javax.ws.rs.core.UriInfo;

import org.glassfish.grizzly.http.server.HttpServer;

import com.sun.jersey.api.container.grizzly2.GrizzlyServerFactory;
import com.sun.jersey.api.core.PackagesResourceConfig;
import com.sun.jersey.api.core.ResourceConfig;
import com.sun.jersey.spi.resource.Singleton;
 
@Singleton
@Path("service") 
public class MyResource {
	
	@Path("{sub_path:[a-zA-Z0-9]*}")
    @GET
    @Consumes({MediaType.TEXT_PLAIN,MediaType.APPLICATION_JSON})
    @Produces(MediaType.TEXT_PLAIN)
    public String getResourceName(
    		@PathParam("sub_path") String resourceName,@DefaultValue("Just a test!") @QueryParam("desc") String description,@Context Request request,@Context UriInfo uriInfo,@Context HttpHeaders httpHeader) {
        System.out.println(this.hashCode());

//		将HTTP请求打印出来
		System.out.println("****** HTTP request ******");
		StringBuilder strBuilder = new StringBuilder();
		strBuilder.append(request.getMethod() + " ");
		strBuilder.append(uriInfo.getRequestUri().toString() + " ");
		strBuilder.append("HTTP/1.1[rn]");
		System.out.println(strBuilder.toString());
		MultivaluedMap<String,String> headers = httpHeader.getRequestHeaders();
		Iterator<String> iterator = headers.keySet().iterator();
		while(iterator.hasNext()){
			String headName = iterator.next();
			System.out.println(headName + ":" + headers.get(headName) + "[rn]");
		}
		System.out.println("[rn]");
		String responseStr =resourceName + "[" + description + "]";
        return responseStr;
    }
    
    public static void main(String[] args) {
    	URI uri = UriBuilder.fromUri("http://127.0.0.1").port(10000).build();
    	ResourceConfig rc = new PackagesResourceConfig("com.sean");
    	try {
			HttpServer server = GrizzlyServerFactory.createHttpServer(uri,rc);
			server.start();
		} catch (IllegalArgumentException e) {
			e.printStackTrace();
		} catch (NullPointerException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}
    	try {
			Thread.sleep(1000*1000);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
    }
}

?

二,客户端

Maven配置如下:

<project xmlns="http://maven.apache.org/POM/4.0.0" 
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
		xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
				http://maven.apache.org/xsd/maven-4.0.0.xsd">
  	<modelVersion>4.0.0</modelVersion>
  	<groupId>JERSEY_CLIENT</groupId>
  	<artifactId>JERSEY_CLIENT</artifactId>
 	<version>1.0</version>
  	<dependencies>		
		<dependency>
	    	<groupId>com.sun.jersey</groupId>
		    <artifactId>jersey-client</artifactId>
		    <version>1.18</version>
		</dependency>
		<dependency>
		    <groupId>com.sun.jersey</groupId>
		    <artifactId>jersey-grizzly2</artifactId>
		    <version>1.18</version>
		</dependency>
	</dependencies>
</project>

客户端程序如下:

package com.sean;

import java.net.URI;
import java.util.Iterator;

import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.UriBuilder;

import com.sun.jersey.api.client.Client;
import com.sun.jersey.api.client.ClientResponse;
import com.sun.jersey.api.client.WebResource;
import com.sun.jersey.api.client.config.ClientConfig;
import com.sun.jersey.api.client.config.DefaultClientConfig;

public class JerseyClient {

	public static void main(String[] args) {
//		要使用Jersey Client API,必须首先创建Client的实例
//		有以下两种创建Client实例的方式
		
//     方式一
	    ClientConfig cc = new DefaultClientConfig();
	    cc.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT,10*1000);
//	    Client实例很消耗系统资源,需要重用
//	    创建web资源,创建请求,接受响应都是线程安全的
//	    所以Client实例和WebResource实例可以在多个线程间安全的共享
	    Client client = Client.create(cc);
	    
//	    方式二
//	    Client client = Client.create();
//	    client.setConnectTimeout(10*1000);
//	    client.getProperties().put(ClientConfig.PROPERTY_CONNECT_TIMEOUT,10*1000);
	    
//	    WebResource将会继承Client中timeout的配置
	    WebResource resource = client.resource("http://127.0.0.1:10000/service/sean?desc=description");
		
	    String str = resource
				.accept(MediaType.TEXT_PLAIN)
				.type(MediaType.TEXT_PLAIN)
				.get(String.class);
	    System.out.println("String:" + str);
	    
	    URI uri = UriBuilder.fromUri("http://127.0.0.1/service/sean").port(10000)
	    		.queryParam("desc","description").build();
	    resource = client.resource(uri);
	    
        //header方法可用来添加HTTP头
	    ClientResponse response = resource.header("auth","123456")
				.accept(MediaType.TEXT_PLAIN)
				.type(MediaType.TEXT_PLAIN)
				.get(ClientResponse.class);
//	    将HTTP响应打印出来
	    System.out.println("****** HTTP response ******");
	    StringBuilder strBuilder = new StringBuilder();
		strBuilder.append("HTTP/1.1 ");
		strBuilder.append(response.getStatus() + " ");
		strBuilder.append(response.getStatusInfo() + "[rn]");
		System.out.println(strBuilder.toString());
		MultivaluedMap<String,String> headers = response.getHeaders();
		Iterator<String> iterator = headers.keySet().iterator();
		while(iterator.hasNext()){
			String headName = iterator.next();
			System.out.println(headName + ":" + headers.get(headName) + "[rn]");
		}
		System.out.println("[rn]");
		System.out.println(response.getEntity(String.class) + "[rn]");
	}
}

?

服务端日志如下:

二月 06,2015 4:33:33 下午 com.sun.jersey.api.core.PackagesResourceConfig init
INFO: Scanning for root resource and provider classes in the packages:
  com.sean
二月 06,2015 4:33:33 下午 com.sun.jersey.api.core.ScanningResourceConfig logClasses
INFO: Root resource classes found:
  class com.sean.Test
  class com.sean.MyResource
二月 06,2015 4:33:33 下午 com.sun.jersey.api.core.ScanningResourceConfig init
INFO: No provider classes found.
二月 06,2015 4:33:33 下午 com.sun.jersey.server.impl.application.WebApplicationImpl _initiate
INFO: Initiating Jersey application,version 'Jersey: 1.18 11/22/2013 01:21 AM'
二月 06,2015 4:33:34 下午 org.glassfish.grizzly.http.server.NetworkListener start
INFO: Started listener bound to [127.0.0.1:10000]
二月 06,2015 4:33:34 下午 org.glassfish.grizzly.http.server.HttpServer start
INFO: [HttpServer] Started.
1814260800
****** HTTP request ******
GET http://127.0.0.1:10000/service/sean?desc=description HTTP/1.1[rn]
accept:[text/plain][rn]
content-type:[text/plain][rn]
user-agent:[Java/1.7.0_65][rn]
host:[127.0.0.1:10000][rn]
connection:[keep-alive][rn]
[rn]
1814260800
****** HTTP request ******
GET http://127.0.0.1:10000/service/sean?desc=description HTTP/1.1[rn]
auth:[123456][rn]
accept:[text/plain][rn]
content-type:[text/plain][rn]
user-agent:[Java/1.7.0_65][rn]
host:[127.0.0.1:10000][rn]
connection:[keep-alive][rn]
[rn]

客户端日志如下:

String:sean[description]
****** HTTP response ******
HTTP/1.1 200 OK[rn]
Transfer-Encoding:[chunked][rn]
Date:[Fri,06 Feb 2015 08:33:38 GMT][rn]
Content-Type:[text/plain][rn]
[rn]
sean[description][rn]

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读