Le mardi 20 décembre 2011 à 13:36, Sergey Beryozkin a écrit : > By the way, I asked about getting Locale supported at the spec level > >
Ok cool :) About the date and stuff, the spec could take a look a the JSR-310, when this one goes out. > > Sergey > On 20/12/11 12:33, Sergey Beryozkin wrote: > > On 20/12/11 10:21, Brice wrote: > > > > > > > > > > > > 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. > > > > > > > > > For now I've added a Locale check; > > > > > > 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. > > > > > > > I guess ParameterHandlers can do the validation on its own, but IMHO a > > filter will do much better, say get UriInfo injected into RequestHandler > > filter and check all the path and query parameters, etc. > > > > ParameterBeans (those annotated with PathParam("") etc) can do the > > validation. > > > > > OK, I didn't thought about that. Does CXF do field injection ? That would be handy and better for immutability. > > > > JAX-RS 2.0 will require some support for the bean validation, it will be > > very annotation-centric, so, but that will be another option > > > > > OK, that might be welcome. Especially for the above point if field injection is not yet supported. > > > > > > > > > > > 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); > > > > > > > > > > > > > > I've fixed > > messageContext.getContextualProperty(OperationResourceInfo.class) too > > > > > > > > > > > > > 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? > > > > > > > Yes - if it does not work as expected in the current CXF you work with > > then please upgrade - it has to work > > > > Sergey > > > > > > > > > > > > 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 > > > > > > > > > > > -- > Sergey Beryozkin > > Talend Community Coders > http://coders.talend.com/ > > Blog: http://sberyozkin.blogspot.com Thanks a lot Sergey, your help is really appreciated :) Best regards, -- Brice
