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