title: spring mvc forward to jsp
body: <p>I currently have my web.xml configured to catch 404s and send them to my spring controller which will perform a search given the original URL request.</p>
  
  <p>The functionality is all there as far as the catch and search go, however the trouble begins to arise when I try to return a view.</p>
  
  <pre><code>&lt;bean class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver" p:order="1"&gt;
      &lt;property name="mediaTypes"&gt;
          &lt;map&gt;
              &lt;entry key="json" value="application/json" /&gt;
              &lt;entry key="jsp" value="text/html" /&gt;
          &lt;/map&gt;
      &lt;/property&gt;
  
      &lt;property name="defaultContentType" value="application/json" /&gt;
      &lt;property name="favorPathExtension" value="true" /&gt;
  
      &lt;property name="viewResolvers"&gt;
          &lt;list&gt;
              &lt;bean class="org.springframework.web.servlet.view.BeanNameViewResolver" /&gt;
              &lt;bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
                  &lt;property name="prefix" value="/WEB-INF/jsp/" /&gt;
                  &lt;property name="suffix" value="" /&gt;
              &lt;/bean&gt;
          &lt;/list&gt;
      &lt;/property&gt;
      &lt;property name="defaultViews"&gt;
          &lt;list&gt;
              &lt;bean class="org.springframework.web.servlet.view.json.MappingJacksonJsonView" /&gt;
          &lt;/list&gt;
      &lt;/property&gt;
      &lt;property name="ignoreAcceptHeader" value="true" /&gt;
  &lt;/bean&gt;
  </code></pre>
  
  <p>This is a snippet from my MVC config file.</p>
  
  <p>The problem lies in resolving the view's path to the <code>/WEB-INF/jsp/</code> directory. Using a logger in my JBoss setup, I can see that when I test this search controller by going to a non-existent page, the following occurs:</p>
  
  <ol>
  <li><p>Server can't find the request</p></li>
  <li><p>Request is sent to 404 error page (in this case my search controller)</p></li>
  <li><p>Search controller performs search</p></li>
  <li><p>Search controller returns view name (for this illustration, we'll assume <code>test.jsp</code> is returned)</p></li>
  <li><p>Based off of server logger, I can see that <code>org.springframework.web.servlet.view.JstlView</code> is initialized once my search controller returns the view name (so I can assume it is being picked up correctly by the <code>InternalResourceViewResolver</code>)</p></li>
  <li><p>Server attempts to return content to browser resulting in a 404!</p></li>
  </ol>
  
  <p>A couple things confuse me about this:</p>
  
  <ol>
  <li><p>I'm not 100% sure why this isn't resolving when <code>test.jsp</code> clearly exists under the <code>/WEB-INF/jsp/</code> directory.</p></li>
  <li><p>Even if there was some other problem, why would this result in a 404? Shouldn't a 404 error page that results in another 404 theoretically create an infinite loop?</p></li>
  </ol>
  
  <p>Thanks for any help or pointers!</p>
  
  <p>Controller class [incomplete]:</p>
  
  <pre><code>@Controller
  public class SiteMapController {
  
  //--------------------------------------------------------------------------------------        
  @Autowired(required=true)   
  private SearchService search;
  
  @Autowired(required=true)
  private CatalogService catalog; 
  //--------------------------------------------------------------------------------------
  
  @RequestMapping(value = "/sitemap", method = RequestMethod.GET)
  public String sitemap (HttpServletRequest request, HttpServletResponse response) {  
      String forwardPath = "";
      try {
          long startTime = System.nanoTime() / 1000000;
          String pathQuery = (String) request.getAttribute("javax.servlet.error.request_uri");
  
          Scanner pathScanner = new Scanner(pathQuery).useDelimiter("\\/");
          String context = pathScanner.next();
          List&lt;ProductLightDTO&gt; results = new ArrayList&lt;ProductLightDTO&gt;();
          StringBuilder query = new StringBuilder();
          String currentValue;
          while (pathScanner.hasNext()) {
              currentValue = pathScanner.next().toLowerCase();
              System.out.println(currentValue);
              if (query.length() &gt; 0)
                  query.append(" AND ");
              if (currentValue.contains("-")) {
                  query.append("\"");
                  query.append(currentValue.replace("-", " "));
                  query.append("\"");
              }
              else {
                  query.append(currentValue + "*");
              }
          }       
  
          //results.addAll(this.doSearch(query.toString()));
  
          System.out.println("Request: " + pathQuery);
          System.out.println("Built Query:" + query.toString());
          //System.out.println("Result size: " + results.size());     
          long totalTime = (System.nanoTime() / 1000000) - startTime;
          System.out.println("Total TTP: " + totalTime + "ms");
  
          if (results == null || results.size() == 0) {
              forwardPath = "home.jsp";
          }
          else if (results.size() == 1) {
              forwardPath = "product.jsp";
          }
          else {
              forwardPath = "category.jsp";
          }
  
      }
      catch (Exception ex) {
          System.err.println(ex);
      }
  
      System.out.println("Returning view: " + forwardPath);
      return forwardPath;
  }
  }
  </code></pre>