java जर्सी और HK2-वर्तमान उपयोगकर्ता इंजेक्शन



dependency-injection jersey (1)

मैं एक साधारण आराम ऐप बनाने के लिए जर्सी 2.17 और HK2 के साथ काम कर रहा हूं। मेरे पास एक ContainerRequestFilter रिक्स्टफ़िल्टर है, जो कि किसी भी अनुरोध को अस्वीकार करता है जिसमें "वर्तमान उपयोगकर्ता" कुकी नहीं होती है

मेरे पास ऐसा कुछ है:

@Path("/users")
public class UserResource { 

      private UserService userService; 

      @GET
      @Path("/orders")
      @Produces("application/json")
      public List<Order> findOrdersOfCurrentUser() { 
            // some ugly code to access headers, extract cookies, and finally
            // extract username (a String) from a particular cookie

            return this.userService.findOrdersByUsername(username) ; 
      }
}

मैं उस से कुछ और अधिक सुंदर कोड चाहता हूँ इस कदर:

 @Path("/users")
 public class UserResource { 

          private UserService userService; 

          @CurrentUsername
          private String currentUser; 

          @GET
          @Path("/orders")
          @Produces("application/json")
          public List<Order> findOrdersOfCurrentUser() { 
                return this.userService.findOrdersByUsername(username) ; 
          }
    }

मैं वास्तव में एचके 2 के लिए नया हूँ और इसे करने का रास्ता खोजने के लिए वास्तविक कठिन हो रहा है।

मैं सिर्फ सही इंटरफ़ेस (या बढ़ाने के लिए कक्षा) को लागू करने के लिए कह रहा हूं


आप जो देख रहे हैं वह तुच्छ नहीं किया जाता है एक तरह से आप यह संभाल सकते हैं, SecurityContext अंदर SecurityContext कंटैंटसेट सेट कर रहे हैं, जैसा कि यहां देखा गया है । इसमें HK2 के साथ कोई प्रत्यक्ष संपर्क शामिल नहीं है। फिर आप अपने संसाधन वर्ग में SecurityContext को इंजेक्ट कर सकते हैं। और उपयोगकर्ता के द्वारा प्राप्त करें

securityContext.getUserPrincipal().getName();

यदि आप वास्तव में कस्टम एनोटेशन के साथ उपयोगकर्ता नाम इंजेक्शन के साथ जाना चाहते हैं, तो आपको एक InjectionResolver रीसोलर बनाने की आवश्यकता होगी ( कस्टम इंजेक्शन एनोटेशन को परिभाषित करना देखें । आप कंटेनरआरक्वेंस ContainerRequestContext (कंटेनररक्वेंस्टफ़िल्टर में फ़िल्टर विधि को पास किए गए एक ही) या SecurityContext में InjectionResolver । उदाहरण के लिए

फ़िल्टर

@Provider
@PreMatching
public class UserFilter implements ContainerRequestFilter {

    public static final String USER_PROP = "user";

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        requestContext.setProperty(USER_PROP, new User("peeskillet"));
    }
}

टिप्पणी

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface CurrentUser {   
}

InjectionResolver

public class CurrentUserInjectionResolver implements InjectionResolver<CurrentUser> {

    javax.inject.Provider<ContainerRequestContext> requestContext;

    @Inject
    public CurrentUserInjectionResolver(
        javax.inject.Provider<ContainerRequestContext> requestContext) {
        this.requestContext = requestContext;
    }

    @Override
    public Object resolve(Injectee injectee, ServiceHandle<?> sh) {
        if (User.class == injectee.getRequiredType()) {
            return requestContext.get().getProperty(UserFilter.USER_PROP);
        }
        return null;
    }

    @Override
    public boolean isConstructorParameterIndicator() { return false; }

    @Override
    public boolean isMethodParameterIndicator() { return false; }
}

इंजेक्शन रेशोवर को बाँध लें

@Provider
public class UserFeature implements Feature {

    @Override
    public boolean configure(FeatureContext context) {
        context.register(new AbstractBinder(){
            @Override
            public void configure() {

                bind(CurrentUserInjectionResolver.class)
                .to(new TypeLiteral<InjectionResolver<CurrentUser>>(){})
                        .in(Singleton.class);
            }
        });
        return true;          
    } 
}

संसाधन

@Path("user")
public class UserResource {

    @CurrentUser 
    private User user;

    @GET
    public Response getCurrentUser() {
        return Response.ok(user.getUsername()).build();
    }
}

अब मुझे इस द्वितीय दृष्टिकोण के बारे में निश्चित नहीं है, कम से कम फिल्टर के बारे में एक हिस्सा है @PreMatching फ़िल्टर अगर मैं इसे प्री-मेलिंग नहीं करता, तो User शून्य हो जाएगा। ऐसा प्रतीत होता है कि InjectResolver में अभी तक हमारे द्वारा निर्धारित संपत्ति नहीं है, जिसका अर्थ है कि ऐसा होने वाला प्रतीत होता है कि InjectResolver को फिल्टर के सामने बुलाया जा रहा है। मुझे इस पर गौर करना होगा। इसे प्री-मेलिंग करना, आईएमओ को आवश्यक नहीं होना चाहिए।

निजी तौर पर हालांकि, मैं केवल SecurityContext का उपयोग करने के पहले दृष्टिकोण के साथ जाता था। मैं ऊपर दी गई लिंक में एक पूर्ण उदाहरण है इस दृष्टिकोण के साथ, यदि जरूरी हो तो आप जर्सी की RolesAllowedDynamicFeature का लाभ उठा सकते हैं।





hk2