Le lundi 19 décembre 2011 à 23:41, Sergey Beryozkin a écrit :

> Hi Brice
> On 19/12/11 20:28, Brice wrote:
> > Le lundi 19 décembre 2011 à 17:07, Brice a écrit :
> > > Hi Sergey,
> > >  
> > > I had some time to work on these and I still have issues.
> > >  
> > > For the Language, finally it will be dealt with PathParam 
> > > /path/to/fr_FR/resource , however my LocaleParameterHandler is never 
> > > called.
> > > InjectionUtils.handleParameter actually look for the first matching 
> > > constructor accepting a string, regardless the provider has a 
> > > ParameterHandler or not for that type. I'm using 2.3.3.
> > >  
> >  
> >  
> > For that it seems there is no real solution, and Locale is not the only 
> > class we have in this situation.
> >  
> > I read this 
> > http://cxf.547215.n5.nabble.com/ParameterHandler-not-invoked-for-Date-parameter-td3322606.html
> >  but it didn't help :/
> That actually works now - because Date will throw an exception in case  
> of unrecognized formats and this is then handled by registered Parameter  
> handlers.
>  
>  

OK. However I meant (at time of writing) it didn't help for objects in general 
with a single String argument constructor that don't fail, and I don't want to 
instantiate them through this constructor. Sorry I wasn't clear enough.

> > The current workaround is to have a CXFLocaleWrapper, that pretty much 
> > sucks, but it works. I looked at the code of future versions of the 
> > InjectionUtils, it doesn't seem to be fixed, yet I'm still a CXF neophyte.
> > Could it work with a custom RequestHandler, or an Interceptor right before 
> > the actual invocation (thinking loudly) ?
> >  
>  
>  
> I've been kind of reluctant to get ParameterHandlers getting in front of  
> the default parameter class instantiation algorithm. May be it's not a  
> big deal but I was just too overcautious may be.
> The case with the Date class was probably the only real problem which  
> has now been fixed.
> We have a case number 2 now which is really to do with the Locale single  
> constructor bug. I think I may just do 'if (Locale)' check and start  
> considering checking ParameterHandlers first once/if we have a case  
> number 3 :-), we'll do something.
>  
>  

If you don't want to break things which I totally understand, You might 
introduce some annotation reading, like @OverrideConstructor.
Or some way to specify the instanciatiuon strategy for the type.
> I'm wondering if you can just use String parameter as an alternative and
> check for '_' in meantime ?
>  
>  

I'm not sure to follow you there. Do you mean wrinting code like this :
    @GET
    @Path("{locale}/doit")
    Response doSomethingWithLocale(@PathParam("locale") String locale);


I'm not sure I proceed like that, because I would also like to perform some 
generic verification/validation on the parameters (usually the most common 
parameters), but maybe ParameterHandlers are not really made for that.
How would do add a layer of validation before the actual call. I was thinking 
to add an interceptor after the JAXRSInInterceptor.


> > > Also for the ExceptionMapper, I cannot access the OperationResourceInfo, 
> > > the code 
> > > "messageContext.getContextualProperty(OperationResourceInfo.class)" 
> > > actually returns "null" at that time. In the stackframe the code is 
> > > executing from JAXRSUtils.convertFaultToResponse() line 1170.
> > Investigating the injected MessageContext, I have found one place where 
> > OperationResouceInfo, but it's clearly not future proof
> >  
> > So injection looks like that
> > @Context private MessageContext messageContext;
> >  
> >  
> > And I fetch the OperationResourcveInfo this way :
> > OperationResourceInfoStack operationResourceInfoStack = 
> > (OperationResourceInfoStack)
> > messageContext.getContextualProperty("org.apache.cxf.jaxrs.model.OperationResourceInfoStack");
> > OperationResourceInfo ori = (OperationResourceInfo) 
> > operationResourceInfoStack.peek().getMethodInfo();
> >  
> > peeking in a stack is a bit scabrous in my opinion.
> >  
> >  
> >  
> > Instead I wrote a RequestHandler that actually fetch the information from 
> > the message itself and store this information in an injected MessageContext 
> > :
> > OperationResourceInfo operationResourceInfo = 
> > message.getExchange().get(OperationResourceInfo.class);
> > SupplementaryInfo si = 
> > operationResourceInfo.getAnnotatedMethod().getAnnotation(SupplementaryInfo.class);
> >  
> > messageContext.put(BusinessServiceXFConstants.SERVICE_NAME, si.value());
> >  
> > And I can retrieve these values with more confidence in the ExceptionMapper.
> > It does seem safe also as it's only contextual to the message; is it 
> > possible to confirm that point ?
> >  
>  
>  
> This approach looks good; I'm not sure yet why  
> messageContext.getContextualProperty(OperationResourceInfo.class) does  
> not work; well - I just checked, message.getContextualProperty expects  
> a String parameter so OperationResourceInfo.class.toString() is used as  
> a key but OperationResourceInfo.class is used as a key as is when saving.
> The above approach looks OK, or use  
> PhaseInterceptorChain.getCurrentMessage().getExchange().get(OperationResourceInfo.class);
>  
>  

Ok, cool this looks even better.





On yet another topic, and just to confirm as it seems to be ok: do 
ExceptionMappers are ordered from the most specific exception to the most 
generic? For example I have some business exceptions, some known technical 
exceptions, but I'd like to catch also all "undeclared" throwables, so any 
added ExceptionMapper belately won't affect the fact that a ThrowableMapper 
will be used only if no other ExceptionMapper matches?
  



Regards,
Brice

>  
> Cheers, Sergey
>  
> >  
> >  
> >  
> > Anyway thanks for your ideas and suggestions.
> >  
> >  
> > --
> > Brice
> > >  
> > >  
> > > Le vendredi 16 décembre 2011 à 11:00, Sergey Beryozkin a écrit :
> > >  
> > > > Hi Brice
> > > > On 15/12/11 20:04, Brice wrote:
> > > > > Hi Sergey,
> > > > >  
> > > > > I think I hit another issue. I think I got a workaround, yet I'm not 
> > > > > sure it is the best way to do this. But first I'll explain the faced 
> > > > > problem :
> > > > >  
> > > > >  
> > > > > I would like to map some exception that might be raised during the 
> > > > > message handling, some raised by the invoker; so an ExceptionMapper 
> > > > > could fit in with some elegance.
> > > > > However, in my Response I would like to get some "technical" data 
> > > > > that will most probably located on an annotation aside the other 
> > > > > JAXRS annotations (@GET, @Path, etc.).
> > > > > But the signature is "Response toResponse(Exception)", so I don't 
> > > > > have any information on the targeted object.
> > > > >  
> > > >  
> > > >  
> > > >  
> > > > You can get CXF-specific MessageContext injected in that mapper and use
> > > > messageContext.getContextualProperty(OperationResourceInfo.class); and
> > > > OperationResourceInfo.getAnnotatedMethod will return Method with the
> > > > annotations, you can get to the class-level annotations from there too
> > > > if needed
> > > >  
> > > >  
> > > >  
> > > > > Also I don't have a Response for this exxcpetion when an exception 
> > > > > occur in "JAXRSInInterceptor.handelMessage(Message)" then I might 
> > > > > loose all the proxies information (thread local is cleared).
> > > >  
> > > > JAXRSInInterceptor checks ExceptionMappers if the exception is thrown
> > > > during handleMessage(Message)
> > > > >  
> > > > > So the workaround would be to also have a RequestHandler :
> > > > > - the "ExceptionMapper" will create a Response with an incomplete 
> > > > > entity
> > > > > - the "RequestHandler" in the "handleResponse(Message, 
> > > > > OperationResourceInfo, Response)" might be able create a new Response 
> > > > > from the original and to "enhance" the entity with the information 
> > > > > from the annotations. The annotation will be accessed through : 
> > > > > "message.getExchange().get(OperationResourceInfo.class).getMethodToInvoke().getAnnotation(SomeCustomAnnotation.class)".
> > > > >  
> > > > > In my opinion this approach looks a wrong, but yet again it is a 
> > > > > neophyte workaround.
> > > >  
> > > > This is possible, why not, but hope the above hint re
> > > > OperationResourceInfo can make it a bit simpler
> > > >  
> > > > Cheers, Sergey
> > > >  
> > > > > What do you think ? Would it be possible to achieve a better and 
> > > > > simpler solution than having to split this logic ?
> > > > >  
> > > > >  
> > > > >  
> > > > > Thanks again for your time and consideration :)
> > > > >  
> > > > > --
> > > > > Brice
> > > > >  
> > > >  
> > > >  
> > >  
> > >  
> >  
> >  
>  
>  
>  
> --  
> Sergey Beryozkin
>  
> Talend Community Coders
> http://coders.talend.com/
>  
> Blog: http://sberyozkin.blogspot.com  


--  
Brice

Reply via email to