无法使用 Glassfish4 和 JAX-RS 绑定 ContainerRequestFilter
Cannot bind a ContainerRequestFilter using Glassfish4 and JAX-RS
我在将 ContainerRequstFilter 附加到 Glassfish4 中一个非常简单的 JAX-RS rest 应用程序时遇到问题。
我相信我已经遵循了 javadoc 和其他各种教程来源的说明,但我现在完全不知所措。
完整的源代码(非常短)如下,具有预期的功能:
- (login) 用户可以在 http://localhost/app/api/login/uname/password 登录,响应为 "You are logged in, uname"
- (验证)用户访问 http://localhost/app/api/login/verify/uname 并且响应是 401 未授权。
第二位表示作为过滤器实现。实际发生的是第一位(登录)有效,第二位(验证)完全忽略过滤器(日志中没有任何内容表明过滤器 运行)。也就是说,输出只是 "Every thing is fine, uname",而不是 401 错误。
我想了解的是将过滤器附加到验证操作的方法。供参考
- 我是 运行 glassfish 4.1 build 13
- 我正在使用 gradle 通过部署操作进行编译和部署
- assassin deploy --force --contextroot /app /path/to/app.war
- Glassfish 报告它正在使用 Jersey 2.10.4
这是与应用程序相关的完整源代码:
RestApp.java
package test.pack;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api")
public class RestApp extends Application
{
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(Login.class);
return classes;
}
}
Login.java
package test.pack;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
@Stateless
@Path("login/")
@Produces("text/json")
public class Login
{
@GET
@Path("{username}/{password}")
public Response login(@PathParam("username") String username, @PathParam("password") String password)
{
System.out.println("Logging in");
return Response.ok("You are logged in, " + username).build();
}
@GET
@Path("/verify/{username}")
@Secured
public Response verify(@PathParam("username") String username)
{
System.out.println("Verify");
return Response.ok("Everything is fine, " + username).build();
}
Secured.java
package test.pack;
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
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Secured
{
}
LoggedInFilter.java
package test.pack;
import java.io.IOException;
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.core.Response;
@Secured
public class LoggedInFilter implements ContainerRequestFilter
{
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
System.out.println("request");
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
呃。真尴尬。
我访问的下一个教程有解决方案,即在 RestApp 中注册过滤器 class。
RestApp.java
@ApplicationPath("/api")
public class RestApp extends Application
{
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(Login.class);
return classes;
}
@Override
public Set<Object> getSingletons()
{
Set<Object> singletons = new HashSet<Object>();
singletons.add(new LoggedInFilter());
return singletons;
}
}
我会在这里留下答案而不是删除问题,因为它只是在我阅读的 4 个教程之一中,所以这可能至少有点有趣。
我在将 ContainerRequstFilter 附加到 Glassfish4 中一个非常简单的 JAX-RS rest 应用程序时遇到问题。
我相信我已经遵循了 javadoc 和其他各种教程来源的说明,但我现在完全不知所措。
完整的源代码(非常短)如下,具有预期的功能:
- (login) 用户可以在 http://localhost/app/api/login/uname/password 登录,响应为 "You are logged in, uname"
- (验证)用户访问 http://localhost/app/api/login/verify/uname 并且响应是 401 未授权。
第二位表示作为过滤器实现。实际发生的是第一位(登录)有效,第二位(验证)完全忽略过滤器(日志中没有任何内容表明过滤器 运行)。也就是说,输出只是 "Every thing is fine, uname",而不是 401 错误。
我想了解的是将过滤器附加到验证操作的方法。供参考
- 我是 运行 glassfish 4.1 build 13
- 我正在使用 gradle 通过部署操作进行编译和部署
- assassin deploy --force --contextroot /app /path/to/app.war
- Glassfish 报告它正在使用 Jersey 2.10.4
这是与应用程序相关的完整源代码:
RestApp.java
package test.pack;
import java.util.HashSet;
import java.util.Set;
import javax.ws.rs.ApplicationPath;
import javax.ws.rs.core.Application;
@ApplicationPath("/api")
public class RestApp extends Application
{
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(Login.class);
return classes;
}
}
Login.java
package test.pack;
import javax.ejb.Stateless;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
@Stateless
@Path("login/")
@Produces("text/json")
public class Login
{
@GET
@Path("{username}/{password}")
public Response login(@PathParam("username") String username, @PathParam("password") String password)
{
System.out.println("Logging in");
return Response.ok("You are logged in, " + username).build();
}
@GET
@Path("/verify/{username}")
@Secured
public Response verify(@PathParam("username") String username)
{
System.out.println("Verify");
return Response.ok("Everything is fine, " + username).build();
}
Secured.java
package test.pack;
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
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.METHOD})
public @interface Secured
{
}
LoggedInFilter.java
package test.pack;
import java.io.IOException;
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.core.Response;
@Secured
public class LoggedInFilter implements ContainerRequestFilter
{
@Override
public void filter(ContainerRequestContext requestContext) throws IOException
{
System.out.println("request");
requestContext.abortWith(Response.status(Response.Status.UNAUTHORIZED).build());
}
}
呃。真尴尬。
我访问的下一个教程有解决方案,即在 RestApp 中注册过滤器 class。
RestApp.java
@ApplicationPath("/api")
public class RestApp extends Application
{
@Override
public Set<Class<?>> getClasses()
{
Set<Class<?>> classes = new HashSet<Class<?>>();
classes.add(Login.class);
return classes;
}
@Override
public Set<Object> getSingletons()
{
Set<Object> singletons = new HashSet<Object>();
singletons.add(new LoggedInFilter());
return singletons;
}
}
我会在这里留下答案而不是删除问题,因为它只是在我阅读的 4 个教程之一中,所以这可能至少有点有趣。