Jersey框架一:Jersey 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[//r//n]");   
        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) + "[//r//n]");   
        }   
        System.out.println("[//r//n]");   
        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() + "[//r//n]");   
        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) + "[//r//n]");   
        }   
        System.out.println("[//r//n]");   
        System.out.println(response.getEntity(String.class) + "[//r//n]");   
    }   
}  

服务端日志如下:

二月 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[/r/n]   
accept:[text/plain][/r/n]   
content-type:[text/plain][/r/n]   
user-agent:[Java/1.7.0_65][/r/n]   
host:[127.0.0.1:10000][/r/n]   
connection:[keep-alive][/r/n]   
[/r/n]   
1814260800   
****** HTTP request ******   
GET http://127.0.0.1:10000/service/sean?desc=description HTTP/1.1[/r/n]   
auth:[123456][/r/n]   
accept:[text/plain][/r/n]   
content-type:[text/plain][/r/n]   
user-agent:[Java/1.7.0_65][/r/n]   
host:[127.0.0.1:10000][/r/n]   
connection:[keep-alive][/r/n]   
[/r/n]  

客户端日志如下:

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

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/19462.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论