title: Prioritizing text/html over other content types when client sends Accept: */*
body: <p>I am trying to write a controller with Spring MVC 3.2 that consumes/produces both JSON and HTML. I have two handler methods that produce different content types:</p>
  
  <pre><code>@Controller
  public class FooController {
      @RequestMapping(value="/foo", produces="text/html")
      public String fooHTML() {
          // ...
      }
  
      @RequestMapping(value="/foo", produces="application/json")
      public String fooJSON() {
          // ...
      }
  }
  </code></pre>
  
  <p>This works splendidly if the <code>Accept</code> header from the client contains either <code>text/html</code> or <code>application/json</code>,</p>
  
  <p>...but then there was Internet Explorer. As noted <a href="http://www.gethifi.com/blog/browser-rest-http-accept-headers" rel="nofollow">here</a>, IE's <code>Accept</code> header varies, but it never contains <code>text/html</code> and always has <code>*/*</code> at the end. When Spring receives a request from IE, it sees no content types directly equal to the ones produced by my controller, but, latching on to the <code>*/*</code> wildcard, it (correctly) decides that both mappings would apply.</p>
  
  <p>Faced with multiple matching handler mappings, Spring (in the RequestMappingHandlerMapping bean) sorts the mappings by what essentially amounts to lexicographic order, picks the first one, and moves on. The problem, from my perspective, is that this process prioritizes <code>application/json</code> over <code>text/html</code>. <strong>I would much rather return <code>text/html</code> unless the client specifically requests <code>application/json</code></strong> — that way, I can serve HTML to dumb clients like IE, and JSON to content-type-savvy clients like users of my API.</p>
  
  <p>Does anyone know of a way to do this that doesn't require extending RequestMappingHandlerMapping to sort the handlers differently? Do you have any simple workarounds?</p>
  
  <p><em>NOTE: I've tried setting a default content type in the ContentNegotiationManager as described <a href="http://blog.springsource.org/2013/05/11/content-negotiation-using-spring-mvc/" rel="nofollow">on the Spring blog</a>. It doesn't solve my problem, because that setting only goes into effect when no Accept header is specified.</em></p>