How do I create hypermedia links in custom serializer with Spring Data Rest - serialization

I have a abstract class and two implementations:
public abstract class Attribute {
// some properties
}
public class CustomAttribute extends Attribute{
private String property1;
}
public class DefaultAttribute extends Attribute{
private String property2;
}
There's another class, which includes these attributes:
public class Step{
private List<Attribute> attributes;
}
Now when Step gets serialized, the self link is missing. I need the self reference, since I want to update the attributes. According to the documentation, jackson needs a little help deciding which class to use. But that does not help, because I need to use both classes. So I build a custom serializer (and registered with a module) for Step and now I wonder how I can construct the link myself. I couldn't find anything in the Spring Data Rest docs regarding this. Since Spring Data Rest adds these links automatically, I think there might be a way to have the protocol/hostname/port information available in the JsonSerializer. How do I get the information in my custom serializer?

Ok, now I use the linkTo() function to get the hostname and port and I manually set the rest of the resource URL in my custom serializer.
final Link attributeLink = linkTo(CustomAttributeRepository.class)
.slash("/api")
.slash("customAttributes")
.slash(attribute.getIdentifier()).withSelfRel();
//#formatter:off
jsonGenerator.writeFieldName("_links");
jsonGenerator.writeStartObject();
jsonGenerator.writeFieldName("self");
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("href", attributeLink.getHref());
jsonGenerator.writeEndObject();
jsonGenerator.writeEndObject();
//#formatter:on

Related

how to transform interface to abstract by using javassist

I am using javassist library for modify class files.
I want to modify interface to abstract class
for example,
original :
public interface javax.servlet.Servlet {
public void init(ServletConfig config) throws ServletException;
}
modified :
public abstract javax.servlet.Servlet {
public void init(ServletConfig config) throws ServletException {
System.out.println(config.getServletContext().getServerInfo());
callMethod(); // this is implemented original method
}
}
How can i apply this solution like aop(before, after)?
I think the first problem with your approach is that when you try to modify your interface using Javassist you are attempting to redefine an interface that has been already loaded by the class loader.
One option might be to do a bit of classloader tricks: create a new classloader that doesn't have your existing interface loaded (parent is the system classloader) and have Javassist load through that (use aCtClass.toClass() method that takes a ClassLoader argument). However is not really something I would do since to manage properly more than one ClassLoader is not that easy.
There might be a better way to achieve your goal, and creating new classes might be a better design. You could create a new class that implements everything you need and then extends the required interface.
Moreover I suggest you to take also a look at dynamic proxies that could be an option as well. Their biggest advantage is that you don't need any 3rd party libraries to create them.

Spring data REST content negotiation

I have an annotated RepositoryRestResource for domain objects whose fields also contain binary data (images.) The Spring Rest machinery will create nice RESTful links for these fields, but I would also like to introduce a handler that returns the bare binary when browsers send an "image/*" accept header.
I could overlay a controller on the same paths, but it's brittle and I'd rather write a strategy class for this.
Possible? Any idea where to plug it in the Spring plumbing?
TIA,
Edoardo
Using the #RepositoryRestController annotation "properly", you should be able to restrict the controller override to the "image/*" only.
Say you have a simple domain object model (getters/setters and a some annotations omitted...)
public class Item {
#Id
private String id;
private String name;
}
Let's override the controller for image/* only
#RepositoryRestController
#ResponseBody
public class ItemRepositoryRestController {
#Autowired
private ItemRepository repository;
#RequestMapping(value = "/items/{id}", method = RequestMethod.GET,
produces = "image/*")
public Item getItem(#PathVariable(value = "id") String id)
{
Item item = repository.findOne(id);
/* do some magic with your item */
return item;
}
Obviously, no image/* data is returned here - you'll actually get a 400 error - but you do only get to this controller if asking if accepting image/*, while going through the automagic Spring Rest Controller when not asking for image/* if and only if you use #RequestMapping at the method level.
I haven't been to the point where I return raw binary data, you may have to use the HttpServletResponse directly as shown here. Or perhaps you already have an answer for this since in your comment you mention having added another resource path already (in which case I'm interested in how you return the raw data).

Dozer BeanFactory: How to implement it?

I have looked at the Dozer's FAQs and docs, including the SourceForge forum, but I didn't see any good tutorial or even a simple example on how to implement a custom BeanFactory.
Everyone says, "Just implement a BeanFactory". How exactly do you implement it?
I've Googled and all I see are just jars and sources of jars.
Here is one of my BeanFactories, I hope it helps to explain the common pattern:
public class LineBeanFactory implements BeanFactory {
#Override
public Object createBean(final Object source, final Class<?> sourceClass, final String targetBeanId) {
final LineDto dto = (LineDto) source;
return new Line(dto.getCode(), dto.getElectrified(), dto.getName());
}
}
And the corresponding XML mapping:
<mapping>
<class-a bean-factory="com.floyd.nav.web.ws.mapping.dozer.LineBeanFactory">com.floyd.nav.core.model.Line</class-a>
<class-b>com.floyd.nav.web.contract.dto.LineDto</class-b>
</mapping>
This way I declare that when a new instance of Line is needed then it should create it with my BeanFactory. Here is a unit test, that can explain it:
#Test
public void Line_is_created_with_three_arg_constructor_from_LineDto() {
final LineDto dto = createTransientLineDto();
final Line line = (Line) this.lineBeanFactory.createBean(dto, LineDto.class, null);
assertEquals(dto.getCode(), line.getCode());
assertEquals(dto.getElectrified(), line.isElectrified());
assertEquals(dto.getName(), line.getName());
}
So Object source is the source bean that is mapped, Class sourceClass is the class of the source bean (I'm ignoring it, 'cause it will always be a LineDto instance). String targetBeanId is the ID of the destination bean (too ignored).
A custom bean factory is a class that has a method that creates a bean. There are two "flavours"
a) static create method
SomeBean x = SomeBeanFactory.createSomeBean();
b) instance create method
SomeBeanFactory sbf = new SomeBeanFactory();
SomeBean x = sbf.createSomeBean();
You would create a bean factory if creating and setting up your bean requires some tricky logic, like for example initial value of certain properties depend on external configuration file. A bean factory class allows you to centralize "knowledge" about how to create such a tricky bean. Other classes just call create method without worying how to correctly create such bean.
Here is an actual implementation. Obviously it does not make a lot of sense, since Dozer would do the same without the BeanFactory, but instead of just returning an object, you could initialized it somehow differently.
public class ComponentBeanFactory implements BeanFactory {
#Override
public Object createBean(Object source, Class<?> sourceClass,
String targetBeanId) {
return new ComponentDto();
}
}
Why do you need a BeanFactory anyways? Maybe that would help understanding your question.

Building one object given another

Say I am calling a third-party API which returns a Post, and I want to take that and transfer properties from it into my own Post class. I have in the past had a method like public static my.Post build(their.Post post) which maps the properties how I want.
However, is it better/valid to have a constructor that accepts their.Post and does the property mapping in there? Or should there always be a separate class that does the converting, and leaves my.Post in a more POJO state?
Thanks for your thoughts!
These answers always starts with "it depends."
People generally argue against using public static methods, based on the fact that it is hard to mock them (I don't buy into that bandwagon).
This comes down to design, do you want their post to be part of your class? If you add it as a "copy" constructor then it will now be part of your class and you are dependent on changes to post. If they change their post, your code has to adapt.
The better solution is to decouple it. You would need to find some extenal method to map the two. One way is to use a static builder method (like you mentioned) or if you want to take it a step further, a more complicated solution would be to extract the information you want from their post into some type of generic collection class. Then create a constructor that will accept that constructor class. This way if they change their design your class stays in tact and all you have to do is update the mappings from their post to your generic representation of it.
public class MyPost{
public MyPost(ICollectionOfProperties props){
//copy all properties.
}
}
public static class TheirPostExtensions{
public static ICollectionOfProperties ExtractProperties(this TheirPost thePost){
return new CollectionOfProperties(){
A = thePost.PropA,
B = thePost.PropB
};
}
}
public class Example{
public Example(){
TheirPost tp = new TheirPost();
ICollectionOfProperties props = tp.ExtractProperties();
MyPost mp = new MyPost(props);
}
}

Is it possible to serialize objects without a parameterless constructor in WCF?

I know that a private parameterless constructor works but what about an object with no parameterless constructors?
I would like to expose types from a third party library so I have no control over the type definitions.
If there is a way what is the easiest? E.g. I don't what to have to create a sub type.
Edit:
What I'm looking for is something like the level of customization shown here: http://msdn.microsoft.com/en-us/magazine/cc163902.aspx
although I don't want to have to resort to streams to serialize/deserialize.
You can't really make arbitrary types serializable; in some cases (XmlSerializer, for example) the runtime exposes options to spoof the attributes. But DataContractSerializer doesn't allow this. Feasible options:
hide the classes behind your own types that are serializable (lots of work)
provide binary formatter surrogates (yeuch)
write your own serialization core (a lot of work to get right)
Essentially, if something isn't designed for serialization, very little of the framework will let you serialize it.
I just ran a little test, using a WCF Service that returns an basic object that does not have a default constructor.
//[DataContract]
//[Serializable]
public class MyObject
{
public MyObject(string _name)
{
Name = _name;
}
//[DataMember]
public string Name { get; set; }
//[DataMember]
public string Address { get; set; }
}
Here is what the service looks like:
public class MyService : IMyService
{
#region IMyService Members
public MyObject GetByName(string _name)
{
return new MyObject(_name) { Address = "Test Address" };
}
#endregion
}
This actually works, as long as MyObject is either a [DataContract] or [Serializable]. Interestingly, it doesn't seem to need the default constructor on the client side. There is a related post here:
How does WCF deserialization instantiate objects without calling a constructor?
I am not a WCF expert but it is unlikely that they support serialization on a constructor with arbitrary types. Namely because what would they pass in for values? You could pass null for reference types and empty values for structs. But what good would a type be that could be constructed with completely empty data?
I think you are stuck with 1 of 2 options
Sub class the type in question and pass appropriate default values to the non-parameterless constructor
Create a type that exists soley for serialization. Once completed it can create an instance of the original type that you are interested in. It is a bridge of sorts.
Personally I would go for #2. Make the class a data only structure and optimize it for serialization and factory purposes.