In http://blog.bdoughan.com/2013/06/moxy-is-new-default-json-binding.html about halfway down there's a heading "Customizing the JSON-Binding". How do you similarly customize the XML binding?
There seem to be fundamental differences between the way Jersey handles Moxy JSON binding and the XML equivalent. If I follow the instructions in the Jersey documentation for creating a custom JAXBContext resolver to configure Moxy's mapping file, that resolver fires in the JSON case but not in the XML case. See https://bitbucket.org/jmetcher/resttest/ for a very small project demonstrating this.
I have the correct jaxb.properties file in place, and I'm building with the jersey-media-moxy module. I can get the identical Moxy JAXB setup working in standalone mode, I just can't get Jersey to take any notice of it.
The debugging I've done indicates that the only way to get this to work is to create a custom MessageBodyWriter. The jersey-media-moxy module registers a JSON MessageBodyWriter which will then invoke any registered ContextResolvers. It does not register an equivalent MessageBodyWriter for XML, and Jersey's default MBW's seem to completely ignore registered ContextResolvers.
Howver, the fact that the need to create a custom MessageBodyWriter is completely missing from the docs and nearly every example seems to indicate that I'm missing something fundamental.
I'd provide links to more info but I don't seem to have the rep to do much at all on SO.
EDIT: More info in response to comments:
Moxy is certainly being picked up as the JAXB provider. I can see this in the debugger.
Jersey version is 2.9, EclipseLink version is 2.5. Java 7.
The ContextResolver approach works fine for JSON. So does the approach of registering MoxyXMLFeature in an Application class. In both cases, the correct context configured with the right mapping file is used. In the XML case, it seems that Jersey never even attempts to create a context.
IF, however, I add an #XmlRootElement annotation to the class I'm trying to marshal, it all works. Even with no other annotations, the class can be marshaled to both XML and JSON according to the oxm mapping file. I've updated the bitbucket project to show this.
So, I can work around the issue either by creating a custom MBW or providing an annotated root class. I guess at this point I'm to work out what the best or recommended approach would be so I can log a documentation patch.
To have Jersey pick up MOXy as the JAXB provider, you simply need to add the jaxb.properties file with the correct entry (see: http://blog.bdoughan.com/2011/05/specifying-eclipselink-moxy-as-your.html) in the same package as your domain model. In the case of JAX-RS if a ContextResolver is not specified this package needs to be the one that corresponds to the parameter to, or return type from from the method in your service mapped with JAX-RS annotations.
http://blog.bdoughan.com/2010/08/creating-restful-web-service-part-35.html
Note:
There was a bug in an earlier version of Jersey that prevented MOXy from being picked up as the default JAXB provider, in that case you could:
Upgrade to a newer version of Jersey.
Create a ContextResolver to return an instance of a MOXy JAXBContext (see: http://blog.bdoughan.com/2011/04/moxys-xml-metadata-in-jax-rs-service.html)
In the case of the ContextResolver you could use code to directly create the MOXy JAXBContext instead of leveraging a jaxb.properites file. Refer to option #2 in the answer I linked to below:
How do I get EclipseLink JAXB (MOXy) to not display namespaces in XML output
It is indeed the case that the only way to marshal an unannotated domain model to XML using Jersey + Moxy is to register your own provider (aka MessageBodyWriter/MessageBodyReader).
Marshalling an unannotated model is supported Moxy functionality. However, Jersey's default JAXB providers mask this functionality by requiring that the model is annotated before they will pass off control to Moxy. The JSON case is implemented differently and does not have this restriction.
See http://lagod.id.au/blog/?p=472 for a fully worked example.
Doc bug reported: https://java.net/jira/browse/JERSEY-2552
Related
From what I understand, from SAP Commerce Cloud 2005 onward the way to customize the REST-endpoints within SAP Commerce Cloud for Spartacus is to use commercewebservices (non-template) and then add own occ-extensions with your REST-endpoints.
That works fine for new endpoints, but what if I want to customize an existing controller from within commercewebservices? Since I am not using the template anymore commercewebservices cannot be modified anymore. I don't see a way how I could for example customize de.hybris.platform.commercewebservices.core.v2.controller.CartsController.
Swapping out commercewebservices with your own extension generated from the template does not work since multiple OOTB (e.g. cmsocc) extensions depend on commercewebservices hence it will always be loaded and clash with our own extension derived from commercewebservices.
Customizing commercewebservices with an addOn also does not solve the problem since, as I understand, it is not possible to add your own controller and bind it to the a url-pattern already used from a controller within commercewebservices
If you want to override an existing API endpoint (CartsController in our case), you can do so with the #RequestMappingOverride annotation.
Using this annotation, you can "shadow" the existing request mapping of the out-of-the-box controller with your custom controller in your own OCC extension.
You can find more details and an example here:
Overriding the REST API [help.sap.com]
EDIT
And let's not forget:
All of the action happens in the facades anyway, and you can also extend the API responses without overriding the Controller using the WsDTO concept plus additional converters. (see Extending Data Objects[help.sap.com] for more details)
Thanks for the response.
The annotation RequestMappingOverride works fine. There is one problem with this approach, lets assume I do following:
Introduce an new called MyController extending the CartsController
Override a single method and annotated this method with RequestMappingOverride
Starting up the system I do get now ambiguous mappings on all mappings of CartsController which I did not override
The reason is, I have now two Controllers registered with the same mappings. The CartsController and MyController which inherits all the methods which are not overriden from CartsController. The only solution I found is to override every single method of the CartsController, annotate all methods with RequestMappingOverride and then just do a super call. That is a bit clumsy and leads to a lot of boilerplate code. I wish the annoation RequestMappingOverride would work on class-level rather than only on method level
I come from Grails background and have recently started a project in Micronaut using GORM.
I tried to find required information in documentation but its not clear how we retrieve post data in controller, validate it similar to Command Objects offered in Grails and save it into database using interface service provided in documentation
PS : I know I can map every field to action argument in controller, and also declare a interface method specifying each argument as property but that does not seems right thing to do as my domain class has so many properties.
Making the action #Transactional or any method would work for saving data as far as I know but I want to know the proper way in Micronaut.
My requirement is simple, save post data in database using GORM in Micronaut.
If I were you I would look back at the documentation, sections 6.4 to 6.11:
https://docs.micronaut.io/snapshot/guide/index.html#binding
https://docs.micronaut.io/snapshot/guide/index.html#datavalidation
http://hibernate.org/validator/
Micronaut is very annotation based, unlike Grails which uses convention over configuration. However in Grails 4, Micronaut will toke over the application context, giving you some of the benefits of Micronaut, but still maintaining the convention over configuration.
We're trying to write a ServiceStack Rest method to received data from the NLOG WebService Target.
https://github.com/NLog/NLog/wiki/WebService-target
It appears that Nlog will send a WCF formatted Json POST based on the class NlogEvents
http://sourcebrowser.io/Browse/nlog/nlog/src/NLog/LogReceiverService/NLogEvents.cs
We can resolve this object as an argument to a post method. But how do we specify the ROUTE as we cant decorate it with an ROUTE attribute?
Also, it appears that this object already has a several attributes that were added from the WCF support. Is there another way to specify the Poco recieve object?
Also, The Nlog webservice has flags to format the data as Rfc3986 or Rfc2396 but im nor sure if that does anything for us.
Any suggestions would be appreciated.
Have a look at ServiceStack's routing docs, you can register routes on DTOs you don't own using the Fluent API, or dynamically attach attributes to Types.
You don't need to use NLog's exact Types in Services, i.e. you can just use a copy of the DTOs for your Service contract and annotate them freely. If needed you can use Auto Mapping to easily copy data from DTOs to NLog Types.
I have a project built on top OSGi and Karaf server. For dependency injection we are using Aries Blueprint.
The main part of the project is a Apache Camel routes and integration things, but now I need to create some maintenance web interface.
So I give a try to JSF - PrimeFaces implementation. I was able to create some demo, which works in OSGi under Karaf, that's ok.
Now I'd like to know if it's possible to use Blueprint here, to reference some already existing OSGi services we have and inject the service into JSF Bean, so we can benefit from already written code.
Can you help me, please?
We solved this in the following way:
We created a listener that:
Creates a ServiceTracker that tracks the BlueprintContainer service attached to the same bundle
Puts the servicetracker into the ServletContext attributes
We created an ELResolver that uses this ServiceTracker and if there is a BlueprintContainer available it uses the getComponentInstance of that to get the value
The listener opens the servicetracer during application initialization and closes it during application destroy
Our listener class: https://source.everit.biz/svn/everit-util/trunk/core/src/main/java/org/everit/util/core/servlet/ServiceLoaderListener.java
Our EL resolver class: https://source.everit.biz/svn/everit-util/trunk/core/src/main/java/org/everit/util/core/el/OsgiELResolver.java
User/pass: guest/guest
After you registered your custom el-resolver all el-expressions will be evaluated in the way that id-s of component instances will be searched inside the blueprint container. In case you say that you have a bean-property in your faces-config.xml with the value #{myComponent} it will be searched inside the BlueprintContainer.
I'm reading the tutorial about configuring JSON for RESTful web services:
https://blogs.oracle.com/enterprisetechtips/entry/configuring_json_for_restful_web
JAXB defines how Java objects are converted from and to XML.
However I don't understand why we have to JAXB bean model when creating RESTful web services that return JSON response? After all it is JSON not XML, right?
However I don't understand why we have to JAXB bean model when
creating RESTful web services that return JSON response?
Short Answer
You don't have to use JAXB to create a RESTful service using a JAX-RS framework. JAX-RS provides the MessageBodyReader/MessageBodyWriter mechanism to plug-in whatever binding you want. JSON binding providers often include an implementation of these classes that you can use directly. Below is an example of how to do this with EclipseLink MOXy (I'm the tech lead):
http://blog.bdoughan.com/2012/05/moxy-as-your-jax-rs-json-provider.html
Advantage of Using JAXB
Applying a JAXB mapping provides an easy mechanism to provide one set of mappings to get both an XML and JSON representation of your data.