Search code examples
javadojojacksondgridjava-custom-serialization

How to implement Jackson custom serialization outside a domain bean?


I have a Spring managed bean...

@Component("Foobean")
@Scope("prototype")
public class foobean {

    private String bar1;
    private String bar2;

    public String getBar1() {
        return bar1;
    }
    public void setBar1(String bar1) {
    this.bar1 = bar1;
    }
    public String getBar2() {
    return bar2;
    }
    public void setBar2(String bar2) {
    this.bar2 = bar2;
    }
}

...and because I am using Dojo Dgrid to display an ArrayList of this bean, I am returning it into the controller as a JSON string:

@Controller
@RequestMapping("/bo")
public class FooController {
     @Autowired
     private FooService fooService

     @RequestMapping("action=getListOfFoos*")
     @ResponseBody 
     public String clickDisplayFoos(
        Map<String, Object> model) {

    List<Foobean> foobeans = fooService.getFoobeans();

    ObjectMapper objMapper = new ObjectMapper();
    String FooJson = null;
    try {
        FooJson = objMapper.writeValueAsString(foobeans);
    } catch (JsonGenerationException e) {

              etc.
}

However, my grid needs an additional column which will contain a valid action for each Foo; that action is not really dependent on any data in individual Foos -- they'll all have the same valid action -- repeated on each line of the resulting DGrid -- but that value is actually dependent upon security roles on the session...which can't be sent to the front end in a Json. So, my solution is twofold:

  1. First I need to add a "virtual" Json property to the bean... which I can do in the bean with @JsonProperty on a method...

    @JsonProperty("validActions")
    public String writeValidActions {
         return "placeHolderForSerializerToChange";
    }
    
  2. ...but it just generates a placeholder. To really generate a valid value, I need to reference the security role of the session, which I am very reluctant to code in the above method. (A service call in the domain bean itself? Seems very wrong.) I think I should create a custom serializer and put the logic -- and the reference to the Session.Security role in there. Are my instincts right, not to inject session info into a domain bean method? And if so, what would such a
    custom serializer look like?


Solution

  • Yes, I wouldn't put Session Info in to the domain or access session directly in my domain.

    Unless there is a specific reason, you could simply add the logic in your action class.

    public String clickDisplayFoos(){
        List<Foo> foos =  service.getFoos();
        for(iterate through foos){
            foo.setValidAction(session.hasSecurityRole())
        }
        String json = objMapper.writeValueAsString(foobeans);
        return json;
    }
    

    I don't like the idea of setting new values as part of the serialization process. I feel custom serializers are meant to transform the representation of a particular property rather than add new values to a property.