Most new web developers fall into this trap so pay attention to this rule:  Handlers for requests are singletons, designed to be created once and then called by many threads at once – effectively a static instance that is used by everybody.  Therefore, it does not make sense to define private member variables in the class unless they are static and can handle multi-threaded access.

public class ViewMediaController extends BaseController
{
    private String userAgent = null;
    private String mediaId = null;
    private Media media = null;

    public ModelAndView handleRequest(HttpServletRequest request,
                                     HttpServletResponse response)
        throws ServletException
    {
        userAgent = request.getHeader("user-agent");
        mediaId = request.getParameter("mediaId");
        media = DataUtil.getMediaById(mediaId);
        processMedia();
        :
        :
        request.setAttribute("media",media);
        return new RedirectingModelAndView("viewMedia");
    }

    private void processMedia()
    {
        :
        media.registerAccess();
        DataUtil.save(media);
    }
    :

Only one instance of ViewMediaController is shared by all threads.  Of course it all works beautifully during testing but the moment more than one user hits the URL simultaneously when the site is delivered, there is a problem – users request to view one media record but receive another.

public class ViewMediaController extends BaseController
{
    public ModelAndView handleRequest(HttpServletRequest request,
                                     HttpServletResponse response)
        throws ServletException
    {
        String userAgent = request.getHeader("user-agent");
        String mediaId = request.getParameter("mediaId");
        Media media = DataUtil.getMediaById(mediaId);
        processMedia(media);
        :
        :
        request.setAttribute("media",media);
        return new RedirectingModelAndView("viewMedia");
    }

    private void processMedia(Media media)
    {
        :
        media.registerAccess();
        DataUtil.save(media);
    }
    :
blog comments powered by Disqus