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.


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.

I'm wondering if you can just use String parameter as an alternative and check for '_' in meantime ?


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);

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

Reply via email to