Registering a Jackson module for Spring Data REST - jackson

I have a working project based on the Spring Data REST example project, and I'm trying to do custom serialization using a Jackson module based on this wiki page.
Here's my Jackson module:
public class CustomModule extends SimpleModule {
public static Logger logger = LoggerFactory.getLogger(CustomModule.class);
public CustomModule() {
super("CustomModule", new Version(1, 0, 0, null));
}
#Override
public void setupModule(SetupContext context) {
logger.debug("CustomModule.setupModule");
SimpleSerializers simpleSerializers = new SimpleSerializers();
simpleSerializers.addSerializer(new CustomDateTimeSerializer());
context.addSerializers(simpleSerializers);
}
}
The wiki page says:
Any Module bean declared within the scope of your ApplicationContext will be picked up by the exporter and registered with its ObjectMapper.
I'm still pretty new to Spring, so I might just be putting my module bean definition in the wrong place; currently it's in src/main/resources/META-INF/spring-data-rest/shared.xml, which is imported from repositories-export.xml:
<bean id="customModule" class="org.hierax.wpa.schema.mapping.CustomModule" />
I don't see the log statement in setupModule, but I do see log output for other classes in the same package.
I'm using Spring Data REST 1.0.0.RC2.

Currently, it's possible to customize a module in Spring Boot like this:
#Bean
public Module customModule() {
return new CustomModule();
}
Reference: Latest Jackson integration improvements in Spring

I've had success using the solution outlined in the wiki entry that you have linked to (although perhaps it has changed since this stack overflow post)
In my instance I was using spring-data-rest-webmvc#1.0.0.RELEASE
Your code seems to be correct and provided that your application context is being loaded correctly I don't see any reason for it not to be working.
I've attached my simpler Module which exemplifies the use of a date formatter:
#Component
public class JsonMarshallingConfigModule extends SimpleModule {
public JsonMarshallingConfigModule() {
super("JsonMarshallingConfigModule", new Version(1, 0, 0, "SNAPSHOT"));
}
#Override public void setupModule(SetupContext context) {
context.getSerializationConfig().setDateFormat(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm'Z'"));
}
}
Perhaps it can be used to outline if it is infact the jackson module that is the problem or spring-data-rest-mvcweb.

Related

Interceptor on super method in CDI 1.0/JEE6

In the following case,
public class Base {
#Transactional
public void doSave() {
// ...
}
}
public class Inherited extends Base {
public void someMethod() {
super.doSave();
}
#Override
public void doSave() {
super.doSave();
}
}
If I add the #Transactional annotation to Inherited.someMethod, the interceptor gets called without issue.
However, without the annotation on the inherited class, the interceptor does not get involved in the call to the super class from Inherited.someMethod().
Furthermore, calling Inherited.doSave() does not seem to get the interceptor invoked either. I would have expected the annotation on the superclass to be also valid on the subclass. Is this not the expected behaviour?
I am using Apache DeltaSpike for the #Transactional annotation and this is being deployed as a war in an ear (technically as a jar in a war in an ear). However, this may not be relevant as trying with a custom interceptor shows the same behaviour.
This is JBoss EAP 6.3.0 Alpha in case its relevant.
This is expected. Interceptors are only applied if the object is managed. When you you write it this way with inheritence, it's not applied as it's not part of a call stack that CDI is aware of. You would need to inject Base into your class and call Base.doSave

Unrecognized field "_links" since the 2.0.0.RC1 of Spring Data REST

On one side, I have just update the version of spring-data-rest-webmc to the latest 2.0.0.RC1 version of my server. In this version, the json format change to an HAL format.
On the other side, I have a client which use the spring-hateoas library with the 0.9.0.RELEASE version.
In this client, I use RestTemplate to get a resource from my server like this :
AuthorResource authorResource = restTemplate.getForObject(BASE_URL+"authors/"+ authorId, AuthorResource.class);
The AuthorResource class extends ResourceSupport.
Now, I have this error :
Nested exception is com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: Unrecognized field "_links" (class org.example.hateoas.AuthorResource)
How can i configure my client to support this new format ?
I try
#EnableHypermediaSupport(type =
EnableHypermediaSupport.HypermediaType.HAL)
But it does not work.
thx for your help.
Problem is that halMapperObject is not setted because of context is not spring web.
You have to create your own RestTemplate class like this
#Component
public class EraRestTemplate extends RestTemplate implements InitializingBean {
#Autowired
#Qualifier("_halObjectMapper")
ObjectMapper halObjectMapper;
static class HALMessageConverter extends MappingJackson2HttpMessageConverter {
}
#Override
public void afterPropertiesSet() throws Exception {
halObjectMapper.registerModule(new Jackson2HalModule());
HALMessageConverter converter = new HALMessageConverter();
converter.setObjectMapper(halObjectMapper);
this.getMessageConverters().clear();
this.getMessageConverters().add(converter);
}
}
It works fine now for me thanks a friend who knows Spring very well.

EntityFramework.dll DbContext conflicting with Microsoft.data.Entity.CTP DbContext

Grabbed this from a sample:
protected override ObjectContext CreateDataSource()
{
NorthwindContext nw = new NorthwindContext();
// Configure DbContext before we provide it to the
// data services runtime.
nw.Configuration.ValidateOnSaveEnabled = false;
// Get the underlying ObjectContext for the DbContext.
var context = ((IObjectContextAdapter)nw).ObjectContext;
// Return the underlying context.
return context;
}
Modified it to use the DbContext class that I have in my project.
EDIT: Clarifying that I am casting from a DbContext class just as the sample does:
public class NorthwindContext : DbContext
{
// Use the constructor to target a specific named connection string
public NorthwindContext()
: base("name=NorthwindEntities")
{
// Disable proxy creation as this messes up the data service.
this.Configuration.ProxyCreationEnabled = false;
// Create Northwind if it doesn't already exist.
this.Database.CreateIfNotExists();
}
Running the code gives me an error on the line casting the DbContext:
Unable to cast object of type 'MyProject.MyDbContext' to type 'System.Data.Entity.Infrastructure.IObjectContextAdapter'.
Despite the fact that DbContext implements IObjectContextAdapter:
public class DbContext : IDisposable, IObjectContextAdapter
I've found several questions here on SO and other googled sources, but no solutions I have found work.
I'm using Entity Framework 4.2, attempted to update to the 4.3 beta and I'm not sure if that stuck.
Overall goal is to serve data in WCF as a DataService.
Update: Digging deeper I find that there is an ambiguity issue between what my DbContext was (From EntityFramework.dll ) and the type in the WCF project (from Microsoft.data.Entity.CTP)
Not sure how to get what I want from both here....
Just a reminder, the issue here was that an ambiguity between EntityFramework.dll and Microsoft.Data.Entity.CTP was causing the DataInitializer I had for my DbContext to lose functionality.
I solved this issue by replacing my Initializer here:
public class MyDataInitializer : RecreateDatabaseIfModelChanges<MyData>
{
public void Seed(MyData context)
To:
public class MyDataInitializer : IDatabaseInitializer<MyData>
{
public void InitializeDatabase(MyData context)
And I can now access my DataService.
Just one

Can you apply aspects in PostSharp without using attributes?

I know with Castle Windsor, you can register aspects (when using method interception in Windsor as AOP) using code instead of applying attributes to classes. Is the same possible in Postsharp? It's a preference things, but prefer to have aspects matched to interfaces/objects in one place, as opposed to attributes all over.
Update:
Curious if I can assign aspects to interfaces/objects similiar to this:
container.Register(
Component
.For<IService>()
.ImplementedBy<Service>()
.Interceptors(InterceptorReference.ForType<LoggingAspect>()).Anywhere
);
If you could do this, you would have the option of NOT having to place attributes on assemblies/class/methods to apply aspects. I can then have one code file/class that contains which aspects are applied to which class/methods/etc.
Yes. You can either use multicasting (http://www.sharpcrafters.com/blog/post/Day-2-Applying-Aspects-with-Multicasting-Part-1.aspx , http://www.sharpcrafters.com/blog/post/Day-3-Applying-Aspects-with-Multicasting-Part-2.aspx) or you can use aspect providers (http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-12-e28093-Aspect-Providers-e28093-Part-1.aspx , http://www.sharpcrafters.com/blog/post/PostSharp-Principals-Day-13-e28093-Aspect-Providers-e28093-Part-2.aspx).
Example:
using System;
using PostSharp.Aspects;
using PostSharp.Extensibility;
[assembly: PostSharpInterfaceTest.MyAspect(AttributeTargetTypes = "PostSharpInterfaceTest.Interface1", AttributeInheritance = MulticastInheritance.Multicast)]
namespace PostSharpInterfaceTest
{
class Program
{
static void Main(string[] args)
{
Example e = new Example();
Example2 e2 = new Example2();
e.DoSomething();
e2.DoSomething();
Console.ReadKey();
}
}
class Example : Interface1
{
public void DoSomething()
{
Console.WriteLine("Doing something");
}
}
class Example2 : Interface1
{
public void DoSomething()
{
Console.WriteLine("Doing something else");
}
}
interface Interface1
{
void DoSomething();
}
[Serializable]
class MyAspect : OnMethodBoundaryAspect
{
public override void OnEntry(MethodExecutionArgs args)
{
Console.WriteLine("Entered " + args.Method.Name);
}
}
}
I recommend that if you have complex requirements for determining which types get certain aspects that you consider creating an aspect provider instead.
Have a look at LOOM.NET, there you have a post compiler and a runtime weaver. With the later one you are able to archive exactly what you want.
It should be possible to use the PostSharp XML configuration. The XML configuration is the unification of the Plug-in and Project models in the project loader.
Description of .psproj could be found at http://www.sharpcrafters.com/blog/post/Configuring-PostSharp-Diagnostics-Toolkits.aspx.
Note, that I've only seen examples how PostSharp Toolkits use this XML configuration.
But it should work for custom aspects the same way.
Warning: I've noticed that installation of a PostSharp Toolkit from Nuget overwrites existing psproj file. So do not forget to back up it.

wicket and AtUnit

I've started playing with Wicket and I've chosen Guice as dependency injection framework. Now I'm trying to learn how to write a unit test for a WebPage object.
I googled a bit and I've found this post but it mentioned AtUnit so I decided to give it a try.
My WebPage class looks like this
public class MyWebPage extends WebPage
{
#Inject MyService service;
public MyWebPage()
{
//here I build my components and use injected object.
service.get(id);
....
}
}
I created mock to replace any production MyServiceImpl with it and I guess that Guice in hand with AtUnit should inject it.
Now the problems are:
AtUnit expects that I mark target object with #Unit - that is all right as I can pass already created object to WicketTester
#Unit MyWebPage page = new MyWebPage();
wicketTester.startPage(page);
but usually I would call startPage with class name.
I think AtUnit expects as well that a target object is market with #Inject so AtUnit can create and manage it - but I get an org.apache.wicket.WicketRuntimeException: There is no application attached to current thread main. Can I instruct AtUnit to use application from wicketTester?
Because I don't use #Inject at MyWebPage (I think) all object that should be injected by Guice are null (in my example the service reference is null)
I really can't find anything about AtUnit inside Wicket environment. Am I doing something wrong, am I missing something?
I don't know AtUnit but I use wicket with guice and TestNG. I imagine that AtUnit should work the same way. The important point is the creation of the web application with the use of guice.
Here how I bind all this stuff together for my tests.
I have an abstract base class for all my tests:
public abstract class TesterWicket<T extends Component> {
#BeforeClass
public void buildMockedTester() {
System.out.println("TesterWww.buildMockedTester");
injector = Guice.createInjector(buildModules());
CoachWebApplicationFactory instance =
injector.getInstance(CoachWebApplicationFactory.class);
WebApplication application = instance.buildWebApplication();
tester = new WicketTester(application);
}
protected abstract List<Module> buildModules();
The initialization is done for every test class. The subclass defines the necessary modules for the test in the buildModules method.
In my IWebApplicationFactory I add the GuiceComponentInjector. That way, after all component instantiation, the fields annotated with #Inject are filled by Guice:
public class CoachWebApplicationFactory implements IWebApplicationFactory {
private static Logger LOG = LoggerFactory.getLogger(CoachWebApplicationFactory.class);
private final Injector injector;
#Inject
public CoachWebApplicationFactory(Injector injector) {
this.injector = injector;
}
public WebApplication createApplication(WicketFilter filter) {
WebApplication app = injector.getInstance(WebApplication.class);
Application.set(app);
app.addComponentInstantiationListener(new GuiceComponentInjector(app, injector));
return app;
}
}