`
农村外出务工男JAVA
  • 浏览: 105642 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

Jersey的绑定机制

阅读更多

一:简介

    因为项目需要,最近研究了下restful风格的编程方式,这里也Jersey为例。Jersey是一个restful框架,其提供了面向切面的Providers功能,一般情况下我们可以手动注册到Application中,但是它支持更加灵活的方式,这就是jersey提供的绑定机制。

二:客户端封装

   Jersey Client的每次创建连接都必须耗资源,我们可以用连接池模式进行封装。

  

package com.jersey.client;

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;

import org.apache.http.impl.conn.PoolingClientConnectionManager;
import org.glassfish.jersey.apache.connector.ApacheClientProperties;
import org.glassfish.jersey.apache.connector.ApacheConnectorProvider;
import org.glassfish.jersey.client.ClientConfig;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

/**
 * 对Jersey客户端得封装 
  1、使用spring提供的几个bean实现 InitializingBean ,
 * FactoryBean 工厂bean,其返回的对象不是指定类的一个实例,其返回的是该FactoryBean的getObject方法所返回的对象
 *  DisposableBean
 *  bean的销毁
 * 
 * @author tanjie
 *
 */
@SuppressWarnings("deprecation")
@Service("jerseyClient")
public final class JerseyClient implements FactoryBean<Client>,
		InitializingBean, DisposableBean {

	/**
	 * 返回Client实例
	 */
	private Client client;

	private ClientConfig clientConfig;

	/**
	 * httpclient连接的最大连接数
	 */
	private int maxTotal = 1000;

	/**
	 * httpclient每个主机地址的并发数
	 */
	private int defaultMaxPerRoute = 100;
	
	/**
	 * 无参构造函数,spring管理的对象必须提供一个
	 */
	public JerseyClient(){
		
	}

	public JerseyClient(int maxTotal, int defaultMaxPerRoute) {
		this.maxTotal = maxTotal;
		this.defaultMaxPerRoute = defaultMaxPerRoute;
	}

	/**
	 * spring会在初始化bean之后执行该方法,优先于init-method执行,但是init-method不依赖spring,只是其采用
	 * 反射实现,效率上没有实现InitalizingBean高
	 */
	@Override
	public void afterPropertiesSet() throws Exception {
		if (null == clientConfig) {
			clientConfig = new ClientConfig();
			final PoolingClientConnectionManager connectionManager = new PoolingClientConnectionManager();
			connectionManager.setMaxTotal(maxTotal);
			connectionManager.setDefaultMaxPerRoute(defaultMaxPerRoute);
			clientConfig.property(ApacheClientProperties.CONNECTION_MANAGER,
					connectionManager);
			clientConfig.connectorProvider(new ApacheConnectorProvider());
			client = ClientBuilder.newClient(clientConfig);
		}else{
			// 默认创建一个
			client = ClientBuilder.newClient();
		}
	}

	/**
	 * 实例销毁
	 */
	@Override
	public void destroy() throws Exception {
		if (null != client) {
			client.close();
		}
	}

	@Override
	public Client getObject() throws Exception {
		return this.client;
	}

	@Override
	public Class<?> getObjectType() {
		return this.client.getClass();
	}

	@Override
	public boolean isSingleton() {
		return true;
	}

}

  2.1 按名称绑定

    使用@NameBinding

  

package com.tanjie.jersey.绑定机制;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

import javax.ws.rs.NameBinding;

/**
 * 通过名称绑定
 */
@NameBinding
@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(value=RetentionPolicy.RUNTIME)
public @interface Banding {

}

  绑定@Provider

 

package com.jersey.绑定机制;

import java.io.IOException;

import javax.annotation.Priority;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Banding
@Priority(Priorities.USER)
@Provider
public class NameBindingFilter implements ContainerRequestFilter,
		ContainerResponseFilter {

	/**
	 * @param requestContext服务器请求过滤器
	 * 可以分为预处理:即当服务器接收到请求后先执行处理
	 * 后处理:当服务器接收到请求并处理后在进行处理(默认情况系)
	 * 二者可同时执行
	 */
	@Override
	public void filter(ContainerRequestContext requestContext)
			throws IOException {
		System.out.println("AirNameBindingFilter请求前"
				+ requestContext.getMethod());
	}
	
	/**
	 * 服务器响应请求后的过滤器
	 * @param requestContext 容器请求上下文
	 * @param responseContext 容器响应上下文
	 */
	@Override
	public void filter(ContainerRequestContext requestContext,
			ContainerResponseContext responseContext) throws IOException {
		System.out.println("AirNameBindingFilter请求后"
				+ requestContext.getMethod() + ",url:"
				+ responseContext.getStatus());
	}

}

  提供rest接口

package com.jersey.resources;

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.MediaType;

import com.jersey.vo.User;
import com.jersey.绑定机制.Banding;

@Banding
@Path("/helloword")
public class RestfulHello {

	/**
	 * @GET 方法是幂等的,因为读取同一个资源,总是得到相同的数据,GET方法也是线程安全的
	 * 因为读取资源不会对其状态做改到
	 * 1、在接口中定义了资源请求的类型后,在实现类上不用再定义
	 * @return
	 */
	@GET
	@Produces(MediaType.TEXT_PLAIN)
	public String sayHello() {
		return "restful hello word";
	}

	@GET
	@Path("/{param}")
	@Produces("text/plain;charset=UTF-8")
	public String sayHello2UserByText(@PathParam("param") String username) {
		return "Hello " + username;
	}

	@GET
	@Path("/get")
	@Produces(MediaType.APPLICATION_JSON)
	public User HH(@QueryParam("username") String username) {
		User user = new User();
		user.setId(1);
		user.setName(username);
		return user;
	}
}

  单元测试:

 

package com.jersey_restful;

import javax.annotation.Resource;
import javax.ws.rs.client.Client;
import javax.ws.rs.client.Invocation.Builder;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.GenericType;
import javax.ws.rs.core.Response;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = { "classpath:applicationContext.xml" })
public class NameBindTest{

	@Resource(name = "jerseyClient")
	private transient Client jerseyClient;

	@Test
	public void test() {
		WebTarget target = jerseyClient.target(
				"http://localhost:8080/jersey_restful/restful/helloword")
		Builder builder = target.request();
		Response response = builder.get();
		GenericType<String> genericType = new GenericType<String>(String.class);
		if (200 == response.getStatus()) {
			System.out.println("请求OK");
			System.out.println("返回值:" + response.readEntity(genericType));
		}
	}
}

  运行效果:

AirNameBindingFilter请求前GET
请求OK
返回值:restful hello world
AirNameBindingFilter请求后GET,url:200

 

  2.2 动态绑定

    Jersey支持动态绑定,可以更个性化的加载,在运行期只要匹配的动态绑定扩展的方法,面向切面的Provider就会被加载

   定义动态绑定:

  

package com.tanjie.jersey.绑定机制;

import javax.ws.rs.GET;
import javax.ws.rs.container.DynamicFeature;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;

import com.tanjie.jersey.resources.RestfulHello;

@Provider
public final class 动态绑定  implements DynamicFeature{

	@Override
	public void configure(ResourceInfo resourceInfo, FeatureContext context) {
		    boolean 是否是这个类 = RestfulHello.class.isAssignableFrom(resourceInfo.getResourceClass());
	        boolean 是否是这个方法名 = resourceInfo.getResourceMethod().getName().contains("sayHello");
	        boolean 是否是这个请求类型 = resourceInfo.getResourceMethod().isAnnotationPresent(GET.class);
	        if (是否是这个类 && 是否是这个方法名 && 是否是这个请求类型) {
	            context.register(AirDynamicBindingFilter.class);
	        }
	}

}

  切面

 

public class AirDynamicBindingFilter implements ContainerRequestFilter {
	
    @Override
    public void filter(final ContainerRequestContext requestContext) throws IOException {
    	   System.out.println("动态绑定业务处理");
    }
}

  浏览器执行:

http://localhost:8080/jersey_restful/restful/helloword

  运行效果:

动态绑定业务处理

  如果继续执行:

http://localhost:8080/jersey_restful/restful/helloword/get?username=zs

  则不会有满足切面条件。

分享到:
评论

相关推荐

    jersey1.18 jar包

    5. 数据绑定:Jersey支持多种数据绑定机制,如JAXB、Gson、Jackson等,将Java对象序列化为JSON或XML。 6. 过滤器和拦截器:可以通过实现ContainerRequestFilter和ContainerResponseFilter接口,对请求和响应进行...

    jersey1.4 所需 Jar 包

    13. **扩展性**:Jersey允许通过SPI(Service Provider Interface)机制添加自定义功能,如提供新的消息处理器或资源解析器。 14. **测试**:Jersey提供测试框架,使得开发者可以轻松地编写单元测试和集成测试,...

    jersey-archive-1.19.zip

    5. **扩展性**:通过 SPI(Service Provider Interface)机制,可以扩展 Jersey 的功能。 总结 Jersey 作为 JAX-RS 的实现,为开发者提供了一个强大且灵活的工具,用于构建 RESTful Web 服务。通过深入理解其核心...

    Jersey开发指南

    - **请求参数处理**:通过`@QueryParam`和`@PathParam`等注解来绑定URL中的查询参数或路径参数到方法参数上。 - **实体处理**:支持多种数据格式(如JSON、XML等),可通过`@Consumes`和`@Produces`注解指定请求和...

    Jersey 2.17 User Guide pdf

    4. 参数注解,如@*Param,它们用于方法参数的绑定。 5. 子资源的处理,如何创建和使用子资源。 6. 根资源类的生命周期以及依赖注入规则。 7. @Context注解的使用方法。 8. 程序化资源模型的创建。 在应用程序部署和...

    完整jersey包和jackson-all-1.9.2.jar

    2. **功能特性**:Jersey提供了丰富的功能,包括但不限于HTTP方法支持(GET、POST、PUT、DELETE等)、URI模板、请求和响应过滤器、实体提供者和消费者、安全性和认证机制、支持多种数据格式(XML、JSON等)。...

    Springboot通过自定义注解绑定Filter与handler

    在JAX-RS中,提供了NameBinding机制,简单理解NameBinding,就是把指定过滤器/拦截器通过自定义的名称注解绑定在某些匹配的资源方法上。Jersey, RESTeasy等框架都有相应的实现。 该代码利用Springboot模拟实现了...

    jersey 1.18全依赖包

    4. **jaxb-impl-2.2.3-1.jar**:Java Architecture for XML Binding (JAXB) 是一个用于XML到Java对象绑定的标准,使得XML数据可以直接转换为Java对象,反之亦然。在Jersey中,JAXB用于序列化和反序列化JSON或XML响应...

    Jersey-2-User-Guide.pdf

    Jersey提供了一组工具来简化RESTful服务的创建,包括处理HTTP请求、数据绑定、依赖注入、拦截器、过滤器以及异步支持等。 ### Maven原型创建项目 在Jersey 2.x版本中,可以使用Maven原型来快速生成一个新的RESTful...

    Jersey Demo

    1. **路由管理**:Jersey 提供了注解机制,如 `@Path`,可以将特定的 HTTP 路径映射到 Java 类或方法上,方便地定义资源路径。 2. **HTTP 方法处理**:通过 `@GET`, `@POST`, `@PUT`, `@DELETE` 等注解,可以直接在...

    Jersey2中文文档_高清版_带目录可跳转

    3. **过滤器与拦截器**:Jersey2 提供了过滤器(Filter)和拦截器(Interceptor)机制,允许在请求处理之前或之后执行自定义逻辑,如认证、日志记录等。 4. **客户端API**:除了服务器端功能,Jersey2 还提供了...

    jersey-example

    - **安全与认证**:结合 OAuth2、JWT 或其他机制实现身份验证和授权。 - **服务版本控制**:通过 URL 或请求头实现服务的版本管理。 - **性能优化**:利用缓存、异步处理、分页等技术提升服务性能。 - **集成其他...

    Jersey java code

    7. **模块化和扩展性**:Jersey可以通过插件机制添加额外的功能,如支持OAuth、CORS、JWT等。 通过深入学习和实践jersey-samples-1.4中的示例,开发者可以更好地掌握RESTful Web服务开发,并在实际项目中灵活运用...

    Developing-Restful-Web-Services-with-Jersey-2-0

    2. **丰富的功能集**:提供了广泛的API集合,用于处理HTTP请求、响应以及数据绑定。 3. **社区支持**:拥有活跃的开发者社区,可以提供技术支持和解决方案。 4. **易于集成**:能够轻松地与其他Java框架集成,如...

    jaxb jar包,还需要jersey包

    Java Architecture for XML Binding (JAXB) 是一个Java标准,它提供了在Java对象和XML文档之间进行绑定的能力。这意味着你可以将Java对象转换为XML格式的数据,反之亦然。JAXB允许开发者在不直接处理XML语法的情况下...

    jersey-mvc-jasper-源码.rar

    1. **Jersey MVC框架的源代码**:包括了路由、控制器、模型绑定、视图渲染等关键组件,这些可以帮助你理解Jersey MVC是如何将请求映射到处理函数,并如何生成响应的。 2. **Jasper引擎的源代码**:展示了JSP编译和...

    about_Jersey:试试Jersey

    2. **自动绑定**:Jersey 可以自动将请求参数绑定到资源方法的参数,包括路径参数、查询参数、头参数和请求体。 3. **内容协商**:Jersey 提供了内容协商机制,可以根据客户端的 Accept 头部自动选择合适的响应格式...

    jersey-jaxrs-filter-example

    2. **Jersey**:Jersey是JAX-RS规范的开源实现,它提供了一整套工具和服务,包括资源类的自动扫描、依赖注入、异常处理、数据绑定等,使得开发者可以更专注于业务逻辑。 3. **过滤器(Filter)**:在JAX-RS中,过滤...

    动态发布rest接口及服务调用

    Jersey还支持多种数据绑定机制,如JSON、XML,以及客户端API,方便服务调用。 结合Jetty和Jersey,我们可以实现动态发布REST接口。首先,需要在项目中引入Jetty和Jersey的相关依赖。接着,创建一个Jetty服务器实例...

    servlet_restful风格所需jar包

    - `jersey-apache-client`:为Apache HttpClient提供了绑定,允许你利用HttpClient的特性与RESTful服务交互。 - `jersey-guice`:整合了Google Guice依赖注入框架,使得配置和管理Jersey组件更加容易。 综合这些...

Global site tag (gtag.js) - Google Analytics