Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 748
mat_boy Avatar asked Jan 18 '26 07:01

mat_boy


1 Answers

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");
   }
}
like image 145
ekem chitsiga Avatar answered Jan 20 '26 20:01

ekem chitsiga



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!