質問

I was doing some practice programming with spring mvc and I decided to do an example regarding content negotiation.

I started with a uri "/products":

  • When I ask for /products.json it returns me json, which I am happy about
  • When I ask for /products.xml it returns the proper xml, again I am happy about that
  • When I ask for the html view (/products), at the moment I only display a simple html table for the products, but what if I want to include extra dynamic content for the html page like a tag cloud or similar products (things unrelated to products)?

Below is my code for the controller method.

    @RequestMapping(method = RequestMethod.GET)
    public ModelAndView getAllProducts(){
        ModelAndView result = new ModelAndView("index");
        GenericListElementWrapper<Product> products = new GenericListElementWrapper<Product>();

        products.setList(productDao.getAll());
        ModelMap modelMap = new ModelMap();
        modelMap.addAttribute("products",products);
        result.addAllObjects(modelMap);

        return result;
    }

What I would like to achieve is the following:

  • A way to have keep my single controller method but the html view would have extra content

The ideas that I had was:

  • Perhaps use servlet filters to enrich the ModelAndView just for the text/html mimetype only? But then you are doing this for all html requests which may be undesirable?

  • Currently the way I am explaining myself feels like I want a completely rendered html view to be sent to the client. Perhaps I am looking at this problem incorrectly and I should be thinking along the lines of retrieving the extra content after the page has been loaded via javascript?

So is it possible to achieve my intended solution? The other part is whether my intended solution is actually desirable in practice :P

役に立ちましたか?

解決

A possibility is to add an interceptor and map it to your the path of your choice. The interceptor.postHandle provides access the ModelAndView after the handler on your controller is executed. Making it possible to add some extra's.

<mvc:interceptors>
    <mvc:interceptor>
        <mvc:mapping path="/my/path"/>
        <ref bean="enhancedContentInterceptor" />
    </mvc:interceptor>
</mvc:interceptors>

@Component
public class EnhancedContentInterceptor implements HandlerInterceptor {

    public boolean preHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler) throws Exception {

        return true;
    }

    public void postHandle(HttpServletRequest request,
            HttpServletResponse response, Object handler,
            ModelAndView modelAndView) throws Exception {

        if (request.getContentType().equals("text/html")) {
            modelAndView.addObject("tags", tagProvider.getTags());
        }
    }

    public void afterCompletion(HttpServletRequest request,
            HttpServletResponse response, Object handler, Exception ex)
            throws Exception {}

    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top