Java 从接口设置Jersey响应状态代码而不返回响应
我正在尝试设置以下REST端点的响应状态Java 从接口设置Jersey响应状态代码而不返回响应,java,hibernate,http,jersey,Java,Hibernate,Http,Jersey,我正在尝试设置以下REST端点的响应状态 @Path("/roles") public interface IRoleService { @POST @Consumes(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON) Role create(Role role); } 因为它创建了一个新的资源,所以如果它返回状态代码201,但当前返回200,则是合适的 我发现如何设置状态代码
@Path("/roles")
public interface IRoleService {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
Role create(Role role);
}
因为它创建了一个新的资源,所以如果它返回状态代码201,但当前返回200,则是合适的
我发现如何设置状态代码的唯一方法是让方法返回一个
javax.ws.rs.core.Response
并将其设置在那里,但我确实不希望我的所有接口都返回一个通用响应,而不是实际的响应对象(在本例中为角色
).一种方法是创建自定义注释并使用响应过滤器设置状态。比如说
注释
@NameBinding
@Target({METHOD, TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Status {
int DEFAULT_CODE = 0;
int code() default DEFAULT_CODE;
}
ContainerResponseFilter
@Status
@Provider
public class StatusFilter implements ContainerResponseFilter {
@Context
private ResourceInfo info;
@Override
public void filter(ContainerRequestContext req, ContainerResponseContext res) throws IOException {
Status status = getInterfaceAnnotation(info.getResourceMethod());
if (status != null) {
int code = status.code();
if (code != Status.DEFAULT_CODE && res.getStatus() == 200) {
res.setStatus(code);
}
}
}
private static Status getInterfaceAnnotation(Method resourceMethod) {
String methodName = resourceMethod.getName();
Class<?>[] paramTypes = resourceMethod.getParameterTypes();
Class<?> iface = resourceMethod.getDeclaringClass().getInterfaces()[0];
Method ifaceMethod;
try {
ifaceMethod = iface.getDeclaredMethod(methodName, paramTypes);
} catch (NoSuchMethodException e) {
return null;
}
return ifaceMethod.getAnnotation(Status.class);
}
}
如果您需要添加一些自定义头,也可以对头执行相同操作。从通用响应对象,您可以包装任何对象,并在客户端反序列化以返回实际对象。这就是让它通用的美妙之处。我可以理解你想通过这样做实现什么吗?想法是拥有透明的接口,这样你就可以确定什么对象作为响应实际到达。通过将其包装在响应对象中,您将失去这一点,并对调用方施加了额外的约束,调用方必须在响应体中预期错误的对象,否则,如果接口是按照我的方式定义的,他就不需要这样做。我认为这不会有任何区别。无论哪种方式,在客户端,您都必须将JSON对象转换为POJO,这需要您指定相应的类对象。这看起来正是我要查找的对象,谢谢。@Paul Samsotha class iface=resourceMethod.getDeclaringClass().getInterfaces()[0];给出的索引超出了范围。
Removed ElementType.Type.
@NameBinding
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Status {
int DEFAULT_CODE = 0;
int code() default DEFAULT_CODE;
}
statusFilter class:
@Provider
public class StatusFilter implements ContainerResponseFilter {
private static Logger logger = LoggerFactory.getLogger(StatusFilter.class);
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
Status status = resourceInfo.getResourceMethod().getAnnotation(Status.class);
if(status!=null){
int code = status.code();
if(code != Status.DEFAULT_CODE && responseContext.getStatus() == 200) {
responseContext.setStatus(code);
}
}
}
}
Then use it in the resource interface method declaration
@POST
@Status(code = 201)
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
GetUserResponse createUser(UserRequest userRequest);
Removed ElementType.Type.
@NameBinding
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Status {
int DEFAULT_CODE = 0;
int code() default DEFAULT_CODE;
}
statusFilter class:
@Provider
public class StatusFilter implements ContainerResponseFilter {
private static Logger logger = LoggerFactory.getLogger(StatusFilter.class);
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
Status status = resourceInfo.getResourceMethod().getAnnotation(Status.class);
if(status!=null){
int code = status.code();
if(code != Status.DEFAULT_CODE && responseContext.getStatus() == 200) {
responseContext.setStatus(code);
}
}
}
}
Then use it in the resource interface method declaration
@POST
@Status(code = 201)
@Produces(MediaType.APPLICATION_JSON)
@Consumes(MediaType.APPLICATION_JSON)
GetUserResponse createUser(UserRequest userRequest);