Expand my Community achievements bar.

@via annotation and adaptable attribute in model

Avatar

Level 7

I have read so many threads regarding @via and adatbale but still not sure whats the correct answers : if anyone can give clear picture on this

1) first question is when we use ????????????????????????????????

      a)  @Model(adaptables = SlingHttpServletRequest.class) or

       b)   @Model(adaptables =Resource.class)

Answers I found when need to do deal with resource properties use   a) and when reuire sling objcet then go fr 2nd )

2)

@Inject

page currentPage ...is working in both condition how ?

or we have to use like below

@Model(adaptables = SlingHttpServletRequest.class)

@Inject
@Via("resource")

private PageDecorator currentPage;

3)

@Model(adaptables=SlingHttpServletRequest.class) public interface MyModel {

// will return request.getResource().getValueMap().get("propertyName", String.class)//that is exactly mean by via resource

@Inject @Via("resource") String getPropertyName(); }

in the same context what does it mean by via request:??????????????????

and how it will get called if we do ????????????

@Model(adaptables=Resource.class)

@Inject @Via(request)

Resource resource;

4) if we use @Model(adaptables =Resource.class)

cant we inject request response currentdesgin and all other sling object ?????????????????

@inject @via(request)

SlingHttpServletrequest request;

p.s. i have checked all article and pages related to sling model available out there ...

wat are the senerio when we have to use @via("request") and @via("resource")

7 Replies

Avatar

Community Advisor

Hi

For example,Let us assume you have written below model and is using it for a component. So the component node which is generated will act as a resource (in Layman language )

1803980_pastedImage_2.png

Now since the model is adapting both request and resource , when we try to Inject a string like below , sling needs a clarity on to use which API . Whether request or resource. The below code might not give you output

      @Inject

       private String firstName;

   So we will call out and tell the sling to use Resource API and inject the property using Resource API specifically .  Does that makes sense ? This is my sole understanding and I would really like to hear from others too. Also to understand how the priority is decided when two adaptables are present this might help Re: Sling model two adapters, adapt problems

  Also, there are some operations which Resource API cannot do single-handedly ; you sometimes might need a request object to do some kind of business logic. Depending on that , we will decide whether to adapt resource alone or both request and resource is needed. For a simple model , just injecting the properties won't need SlingHttpServletRequest always ; adapting a Resource.class will work for such simple scenarios.

     Once you understand this basic difference with some example I would encourage you to post a question more specificly for us to help you to understand . Happy coding

Thanks

Veena

Avatar

Level 7

Thanks for the reply...

We use @via only when we are adapting both Request and Resource.

I have seen the scenerio in projects where we use via

@Model(adaptables = SlingHttpServletRequest.class)

public class Amit{

  @Inject

  @Via("request")

  Resource res;

In above case how resource object we ll get ?

request.getResource().getValueMap().get("propertyName", String.class)

Avatar

Level 7

Thanks for the reply...

We use @via only when we are adapting both Request and Resource.

I have seen the scenerio in projects where we use via

@Model(adaptables = SlingHttpServletRequest.class)

public class Amit{

  @Inject

  @Via("request")

  Resource res;

Avatar

Community Advisor

Thanks for pointing out that . I am sorry. Let me correct myself (meanwhile I will correct the above reply too) Its more of a use when you are Adapting a Request object and you need to Inject a resource . Below post might help you clarify

Usage of @Via in sling models

Avatar

Community Advisor

Re: Sling model two adapters, adapt problems This also might give you some clarity. Please read all the replies. Especially this reply  Re: Sling model two adapters, adapt problems  and this reply Re: Sling model two adapters, adapt problems  might give more clarity.

Avatar

Level 7

Hi AdobeID24​,

You can refer the links mentioned by Veena for more clarity.

The difference is simple. In WCMUsePojo we used HTL Global Objects. Sling models is more annotation driven.

Sling models ease the mapping of Sling/JCR resources into POJOs. This can be done using the resource or the request or both.

1) When we use each?

  • Consider you have a simple Node that stores details about an Image and you need to expose those details into HTL. You can define a Sling model and using @Inject define the properties of the Node that you want to be accessible in HTL:

@Model(adaptables = SlingHttpServletRequest.class)

public class Model3 {

  @Inject

   private String colour;

  @Inject

   private String path;

}

Now consider that one of the properties is not mandatory and you need to inject only when it is present:

@Model(adaptables = Resource.class)

public class MyModel {

  @Inject

  @Optional

   private String optionalPropertyName;

}

What if I need to pass a parameter from HTL into my Sling model to define the output? Since the parameter is part of the incoming request and not the JCR node, there has to be a way I can access those. For this, I use:

HTL:

<div data-sly-use.model3="${'org.example.models.Model3' @ colour='red', path=resource.path}"> ${model3.shine}</div>

Sling Model:

@Model(adaptables = SlingHttpServletRequest.class)

public class Model3 {

  @Inject

   private String colour;

  @Inject

   private String path;

}

If I use request then using request.getResource(), I can also get the resource from the same request. As a result, I can use only request and using "@Via" get hold of the resource objects. In short, when you need to inject a property from a class different from the one you are adapting from, use @Via.

@Model(adaptables = SlingHttpServletRequest.class)

public interface MyModel {

   // will return request.getResource().getValueMap().get("propertyName", String.class)
  @Inject

  @Via("resource")

  String getPropertyName();

}

2)  The following HTL objects will only get injected from a SlingHttpServletRequest adaptable and not Resource. So it will work when you either have only SlingHttpServletRequest or when you have both.

  • currentPage
  • componentContext
  • xssApi
  • currentDesign

3) You can get resource from the request and not vice versa. I don't think I have seen @Via request anywhere. This table should explain what all is accessible from a request, resourceresolver and a resource.

ClassDescriptionRequestResourceResolverResource
ResourceResolverResource resolverXXX
ResourceResourceXX
SlingHttpServletRequestSling requestX
SlingHttpServletResponseSling responseX
SlingScriptHelperSling script helperX

4) Same as 3). Whenever you need any Sling object you would need to use SlingHttpServletRequest and use @SlingObject or @Inject to get the objects into your sling model and if you need anything specifically using resource use @Via("resource").

Source:

Apache Sling :: Sling Models

Apache Sling :: HTL Scripting Engine