2
\$\begingroup\$

I am creating a shopping cart application to learn Spring MVC. I want to display a list of all categories and subcategories in more than one page. i.e; Home Page, Products page, and Category page.

In the Home Page controller I am retrieving the list of categories, subcategories and featured products and passing them to the home page:

@Controller
public class CatalogController {

    @Autowired
    private CategoryConfigService categoryConfigurationService;
    @Autowired
    private ProductConfigService productConfigurationService;
    private static final Logger logger = LoggerFactory
            .getLogger(CatalogController.class);

    /**
     * Catalog Controller method which retrieves the information required in the
     * application home page(Categories,SubCategories)
     * 
     * @return Home Page View
     */
    @RequestMapping(value = "/home", method = RequestMethod.GET)
    public String returnHomePage(Model model) {
        logger.info("Processing information for home page");
        List<Category> categoriesList = categoryConfigurationService
                .getAllCategories();
        Map<Category, List<SubCategory>> categoryMap = new HashMap<Category, List<SubCategory>>();
        for (Category category : categoriesList) {
            List<SubCategory> subCategoryList = categoryConfigurationService
                    .getAllSubCategoriesByCategoryId(category.getId());
            categoryMap.put(category, subCategoryList);
        }
        model.addAttribute("categoryMap", categoryMap);
        model.addAttribute("featProd",
                productConfigurationService.getFeaturedProducts());

        return "home";
    }


}

What is the best way to store the object categoryMap in Spring to access it in the header page?

The header page is common for all the JSPs in my web application. So I have used the application context scope to store and retrieve the categoryMap.

What are the drawbacks of this approach? And are there any better ways of doing it?

I want to display the header page as shown in this image:

enter image description here

\$\endgroup\$
3
\$\begingroup\$

I think you need different approach to this. It's good practice when you don't have much of business logic in your controller. Maybe you should try creating a different class that will fill pages with content, based on something, like a template.

Now answering to your question:

You can create method with annotation @PostConstruct, which Spring will execute after done with his setup. In this method initialize field that you need, or in your case set application scope attribute with data that you need.

Also, I don't know if you knew it, you can create jpsf - jsp parts, that you can include in any of your jsp. As an example, you can create part with menu, CSS link or other parts, that share all pages, and just include it in your pages - makes jps look much more cleaner.

Here how u can bind objects to any response of your controller:

@ModelAttribute(value = "foo") 
public String addAttribute(){
return "string";
}

Or:

@ModelAttribute()
public void addAttribute(Model model){
   model.addAttribute("roo", "one");
   model.addAttribute("loo", "two");
   model.addAttribute("moo", "some");
}

this how you bind for every response of your application:

@ControllerAdvice
public final class GlobalController {
    @ModelAttribute
    public void addAttributes(Model model) {
       model.addAttribute("msg", "Welcome to My Country");
    }
} 
\$\endgroup\$
  • \$\begingroup\$ Yes I am using seperate header.jsp page and including it in all necessary pages as you mentioned. I had doubt that whether in this context,the usage of application scope is a good idea or not.. I feel that it is the only viable option, or else I need to add this data in request scope in every Controller to display the data in the header pages. \$\endgroup\$ – Sai Upadhyayula Aug 2 '15 at 19:07
  • \$\begingroup\$ I still think that if you just add service layout it will solve ur problem. But u also can use ModelAttribute method, that u declare in ur controller. It will bind return value of such method to every response of your controller. ModelAttribute(value = "modelAttributeName') - this how it's may look. Or u can leave it withou value and do like this: ModelAttribute public void addAtribute(Model model) and just add as many attributes as u want. \$\endgroup\$ – Yaroslav Aug 3 '15 at 21:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.