mat_boy
mat_boy

Reputation: 13666

Spring, MVC and strategy to reuse parts of the model

I'm struggling to understand what would be the best strategy to reuse some code. Normally, I my have controllers in Spring as:

@Controller
public class PageX1{
  @Autowired
  HeaderService header;

  @Autowired
  CatalogService catalog;

  @RequestMapping("/test1")
  public String controller(Map<String, Object> model)  {             

    setHeaderObjectsIntoModel(model, "a param");
    setCatalogObjectsInyoModel(model, "another param", 1212, "more params");
  }

   private setHeaderObjectsIntoModel(Map<String, Object> model, String aParam){
     Object value = header.getObjectWithParam(aParam);
     model.put("key", value);  
   }

   ....
}

I may need to reuse the part related to service S1 in another controller, e.g.

@Controller
public class PageX2{
  @Autowired
  HeaderService s;

  @RequestMapping("/test2")
  public String controller(Map<String, Object> model)  {
    setHeaderObjectsIntoModel(model, "a new param");
  }
}

and the same for S2, and again and again. I don't want to duplicate code. I had some idea in my mind, but nothing good I think (like having a class annotated with @Component that implements an interface aimed to handle the model, but I should make the parameters generic and I would like to have it specific to minimize mistakes).

What should be the right approach? Any example is more than welcome

Upvotes: 3

Views: 1349

Answers (1)

ekem chitsiga
ekem chitsiga

Reputation: 5753

You have two options. First option you can have a base controller which provides the common functionality which will be inherited by your controllers

public abstract class AbstractPage{

   @Autowired
   private HeaderService s;

   protected Object retrieveObjectWithParam(String param){
      return s.getObjectWithParam(param);
   }
}

@Controller
public class PageX1 extends AbstractPage{

  @RequestMapping("/test1")
  public String controller(Map<String, Object> model)  { 
    Object headerParam = retrieveObjectWithParam("a param");
    model.put("key" , headerParam);
  }
}

Second option is to use @ControllerAdvice annotated class that provides common model attributes for your controllers

@ControllerAdvice
public class PageAdvice{

    @Autowired
    private HeaderService s;

   @ModelAttribute("headerParam")
   public Object retriveHeaderParm(){
      return s.getObjectWithParam("a param");
   }
}

Upvotes: 1

Related Questions