如何在Spring Boot中实现Jersey的Namebinding注解绑定技术?
Great question! Implementing Jersey's Namebinding for authentication in Spring Boot is actually straightforward once you break it down step by step. Let me walk you through the process with concrete code examples:
1. Create a Custom Namebinding Annotation
First, we'll define an annotation that acts as our marker for protected endpoints. This is where @NameBinding comes in—it links our annotation to the filter we'll create next.
import javax.ws.rs.NameBinding; import java.lang.annotation.Retention; import java.lang.annotation.Target; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; @NameBinding @Retention(RUNTIME) @Target({TYPE, METHOD}) public @interface Secured { }
2. Build the Authentication Filter
Next, we'll implement a ContainerRequestFilter and attach our @Secured annotation to it. This tells Jersey that any endpoint marked with @Secured should go through this filter.
import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.core.Response; import javax.ws.rs.ext.Provider; import java.io.IOException; @Secured // Bind this filter to our custom annotation @Provider public class AuthenticationFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { // Extract the authentication token from the request header String authHeader = requestContext.getHeaderString("Authorization"); // Implement your actual authentication logic here if (authHeader == null || !validateToken(authHeader)) { // If validation fails, abort the request with 401 Unauthorized requestContext.abortWith( Response.status(Response.Status.UNAUTHORIZED) .entity("Invalid or missing authentication token") .build() ); } } // Replace this with your real token validation logic private boolean validateToken(String authHeader) { // Example: Check if the token matches a valid value return "Bearer valid-token-123".equals(authHeader); } }
3. Register the Filter with Jersey in Spring Boot
We need to tell Spring Boot's Jersey setup about our filter and any resource classes. Create a configuration class extending ResourceConfig:
import org.glassfish.jersey.server.ResourceConfig; import org.springframework.stereotype.Component; @Component public class JerseyConfig extends ResourceConfig { public JerseyConfig() { // Register our authentication filter register(AuthenticationFilter.class); // Register your Jersey resource classes (the endpoints) register(MyProtectedResource.class); } }
4. Protect Your Endpoints
Now just add the @Secured annotation to any endpoint (or entire resource class) that needs authentication:
import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces; import javax.ws.rs.core.MediaType; @Path("/api") public class MyProtectedResource { // This endpoint doesn't require authentication @GET @Path("/public") @Produces(MediaType.TEXT_PLAIN) public String publicEndpoint() { return "This is a public endpoint!"; } // This endpoint is protected by our authentication filter @Secured @GET @Path("/protected") @Produces(MediaType.TEXT_PLAIN) public String protectedEndpoint() { return "This is a protected endpoint—you must be authenticated to see this!"; } }
Quick Tip: Handling Authentication Errors Cleanly
If you want more control over error responses, you can create an ExceptionMapper to handle WebApplicationException (or custom exceptions) and return consistent JSON/XML responses instead of plain text.
内容的提问来源于stack exchange,提问作者Ricardo

