我已經構建了一個EmployeeEndpoint,它持有不同的方法,如創建,更新,刪除等等。爲了簡化這個問題,我只使用了create方法。Java - 自定義註釋將不被考慮
因爲我想要一個可伸縮的應用程序,我已經構建了一個包含基本方法的接口。在接口中,我現在可以使用JAX-RS-Annotations註釋這些方法。因爲它們將被繼承,所以我只需要重寫EmployeeEndpoint中的接口方法。
接口
public interface RESTCollection<T> {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public T create(T entity) throws Exception;
}
端點
@Stateless
@Path(「employee「)
public class EmployeeEndpoint implements RESTCollection<Employee> {
@Override
public Employee create(Employee employee) throws Exception {
return this.createEmployee(employee);
}
}
上面的示例工作正常。如果我想添加自定義的註釋,我可以這樣做:
解決方案1
public interface RESTCollection<T> {
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Permissions(Role.Admin)
public T create(T entity) throws Exception;
}
或
解決方案2
@Stateless
@Path(「employee「)
public class EmployeeEndpoint implements RESTCollection<Employee> {
@Override
@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
@Permissions(Role.Admin)
public Employee create(Employee employee) throws Exception {
return this.createEmployee(employee);
}
}
但解決 ISN」這是一個好主意,因爲不是每個實體都可以創建o只有一位管理員。並與解決方案我放棄了可擴展性的優勢和更少的註釋代碼。所以最好的辦法是:
解決方案3
@Stateless
@Path(「employee「)
public class EmployeeEndpoint implements RESTCollection<Employee> {
@Override
@Permissions(Role.Admin)
public Employee create(Employee employee) throws Exception {
return this.createEmployee(employee);
}
}
但現在當我趕上權限,註釋的JAX-RS」 ContainerRequestFilter界面方法稱爲過濾器中,我得到的null
的價值,我不明白。
@Context
private ResourceInfo resourceInfo;
resourceInfo.getResourceMethod().getAnnotation(Permissions.class) // is null
註釋
@NameBinding
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
public @interface Permissions {
Role[] value() default {};
}
枚舉
public enum Role {
Admin,
User
}
是否有可能以任何方式去解決或不同的方法,我得到同樣的效果?
UPDATE
由於原因似乎並沒有被我貼我會告訴你我AuthorizationFilter代碼。因此我使用this後。
AuthorizationFilter
@Provider
@Priority(Priorities.AUTHORIZATION)
public class AuthorizationFilter implements ContainerRequestFilter {
@Inject
@AuthenticatedUser
private User authenticatedUser;
@Context
private ResourceInfo resourceInfo;
@Override
public void filter(ContainerRequestContext requestContext) throws IOException {
Class<?> resourceClass = resourceInfo.getResourceClass();
List<Role> classRoles = extractRoles(resourceClass);
Method resourceMethod = resourceInfo.getResourceMethod();
List<Role> methodRoles = extractRoles(resourceMethod);
try {
if (methodRoles.isEmpty()) checkPermissions(classRoles, requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));
else checkPermissions(methodRoles, requestContext.getHeaderString(HttpHeaders.AUTHORIZATION));
} catch (NotAuthorizedException e) {
requestContext.abortWith(
Response.status(Response.Status.UNAUTHORIZED).build());
} catch (Exception e) {
requestContext.abortWith(
Response.status(Response.Status.FORBIDDEN).build());
}
}
private List<Role> extractRoles(AnnotatedElement annotatedElement) {
if (annotatedElement == null) return new ArrayList<Role>();
else {
Permissions perms = annotatedElement.getAnnotation(Permissions.class);
if (perms == null) return new ArrayList<Role>();
else {
Role[] allowedRoles = perms.value();
return Arrays.asList(allowedRoles);
}
}
}
private void checkPermissions(List<Role> allowedRoles, String authorizationHeader) throws NotAuthorizedException, Exception {
if (!allowedRoles.isEmpty()) {
if (authorizationHeader == null || !authorizationHeader.startsWith("Bearer "))
throw new NotAuthorizedException("Authorization header must be provided");
else if (!allowedRoles.contains(this.authenticatedUser.getRole()))
throw new Exception("User has no permissions");
}
}
}
你是什麼意思「權限根本不考慮」? –
當我在JAX-RS的ContainerRequestFilter接口方法中捕獲Permissions-Annotation時,我會看到'null'的值。 – Nadine
剛剛測試過,它工作正常。你得到一個NullPointerException或是調用null的結果? –