@NameBinding注解名称绑定过滤器/拦截器,只针对某一些资源方法执行处理逻辑
一、为什么要用名称绑定
一般情况下,借助Spring的过滤器或者拦截器等对Http请求或响应进行处理就能满足需求。但是在有些场景下若只需对特定的xxxResource做拦截处理,这个时候使用@NameBinding注解名称绑定指定过滤器或拦截器,就能够对特点资源方法拦截处理。
(但是这种场景下为什么不用切面实现还没搞清楚,欢迎评论区补充!过滤器、拦截器、切面的区别可以参考上篇博客。)
二、案例详解
2.1 导入依赖
@NameBinding注解属于javax.ws.rs的注解,需要导入指定的依赖:
<!-- 扫描Resteasy风格接口必须加此依赖,否则报404-->
<dependency><groupId>org.jboss.resteasy</groupId><artifactId>resteasy-spring-boot-starter</artifactId><version>4.4.0.Final</version>
</dependency>
2.2 声明绑定注解
package com.wyw.learn.namebindingvsaop;import javax.ws.rs.NameBinding;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@NameBinding // 添加该注解后,只需要在接口和拦截器/过滤器添加@NameBindingAnno注解即可绑定接口与拦截器/过滤器的关系
public @interface AddDescForDish {、}
2.3 注解绑定拦截器/过滤器
该案例中绑定过滤器,注意实现ContainerResponseFilter接口的过滤器需要添加@Provicer注解,该过滤器才可生效;
package com.wyw.learn.namebindingvsaop;import org.springframework.stereotype.Component;import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;
import java.io.IOException;
import java.util.Arrays;/*** @author name: silk* @version 1.0* @description: TODO* @date 2024/4/22 16:48*/
@Component
@Provider
@AddDescForDish
public class NameBindingResponseFilter implements ContainerResponseFilter {@Overridepublic void filter(ContainerRequestContext req, ContainerResponseContext resp) throws IOException {Object entity = resp.getEntity();Class<?> clazz = entity.getClass();System.out.println("clazz: " + clazz);Arrays.stream(entity.getClass().getDeclaredFields()).forEach(field -> {field.setAccessible(true);if ("description".equals(field.getName())) {try {field.set(entity, "这是NameBinding逻辑");} catch (IllegalAccessException e) {e.printStackTrace();}}});}
}
2.4 注解绑定接口
该接口必须是RestEasy风格,因为@NameBinding是javax.ws.rs的注解;
package com.wyw.learn.namebindingvsaop;import com.wyw.learn.excel.Dish;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Component;import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import java.math.BigDecimal;/*** @author name: silk* @version 1.0* @description: TODO* @date 2024/4/22 16:11*/
@Path("/nameBinding")
@Component
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@RequiredArgsConstructor
public class NameBindingTestController {@Path("/nameBinding")@GET@AddDescForDishpublic Dish testNameBinding() {Dish dish = new Dish();dish.setName("糖醋小排");dish.setPrice(new BigDecimal("100"));return dish;}@Path("/noNameBinding")@GETpublic Dish testNoNameBinding() {Dish dish = new Dish();dish.setName("鱼香肉丝");dish.setPrice(new BigDecimal("200"));return dish;}
}
2.5 调用结果