Hoe kan ik in Spring MVC de header van het mime-type instellen bij gebruik van @ResponseBody

Ik heb een Spring MVC-controller die een JSON-string retourneert en ik wil het mimetype instellen op application/json. Hoe kan ik dat doen?

@RequestMapping(method=RequestMethod.GET, value="foo/bar")
@ResponseBody
public String fooBar(){
    return myService.getJson();
}

De bedrijfsobjecten zijn al beschikbaar als JSON-strings, dus het gebruik van MappingJacksonJsonViewis niet de oplossing voor mij. @ResponseBodyis perfect, maar hoe kan ik het mimetype instellen?


Antwoord 1, autoriteit 100%

Gebruik ResponseEntityin plaats van ResponseBody. Zo heb je toegang tot de responsheaders en kun je het juiste contenttype instellen. Volgens de Lentedocumenten:

De HttpEntityis vergelijkbaar met
@RequestBodyen @ResponseBody.
Naast het verkrijgen van toegang tot het verzoek
en antwoordtekst, HttpEntity(en de
responsspecifieke subklasse
ResponseEntity) geeft ook toegang tot
de verzoek- en antwoordheaders

De code ziet er als volgt uit:

@RequestMapping(method=RequestMethod.GET, value="/fooBar")
public ResponseEntity<String> fooBar2() {
    String json = "jsonResponse";
    HttpHeaders responseHeaders = new HttpHeaders();
    responseHeaders.setContentType(MediaType.APPLICATION_JSON);
    return new ResponseEntity<String>(json, responseHeaders, HttpStatus.CREATED);
}

Antwoord 2, autoriteit 33%

Ik zou overwegen om de service te refactoren om uw domeinobject te retourneren in plaats van JSON-strings en Spring de serialisatie te laten afhandelen (via de MappingJacksonHttpMessageConverterterwijl u schrijft). Vanaf Spring 3.1 ziet de implementatie er heel netjes uit:

@RequestMapping(produces = MediaType.APPLICATION_JSON_VALUE, 
    method = RequestMethod.GET
    value = "/foo/bar")
@ResponseBody
public Bar fooBar(){
    return myService.getBar();
}

Opmerkingen:

Ten eerste moet de <mvc:annotation-driven />of de @EnableWebMvctoegevoegdaan uw toepassingsconfiguratie.

Vervolgens de produceertattribuut van de @RequestMappingannotatie wordt gebruikt om het inhoudstype van het antwoord te specificeren. Daarom moet het worden ingesteld op MediaType.APPLICATION_JSON_VALUE(of "application/json").

Ten slotte moet Jackson worden toegevoegd zodat elke serialisatie en de-serialisatie tussen Java en JSON automatisch wordt afgehandeld door Spring (de Jackson-afhankelijkheid wordt gedetecteerd door Spring en de MappingJacksonHttpMessageConverterzal onder de motorkap zitten ).


Antwoord 3, autoriteit 6%

Misschien lukt het je niet met @ResponseBody, maar zoiets zou moeten werken:

package xxx;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@Controller
public class FooBar {
  @RequestMapping(value="foo/bar", method = RequestMethod.GET)
  public void fooBar(HttpServletResponse response) throws IOException {
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    out.write(myService.getJson().getBytes());
    response.setContentType("application/json");
    response.setContentLength(out.size());
    response.getOutputStream().write(out.toByteArray());
    response.getOutputStream().flush();
  }
}

Antwoord 4, autoriteit 3%

Ik denk niet dat dit mogelijk is. Er lijkt een open Jira voor te zijn:

SPR-6702: stel expliciet het inhoudstype voor reactie in @ResponseBody


Antwoord 5, autoriteit 2%

Registreer org.springframework.http.converter.json.MappingJacksonHttpMessageConverterals de berichtenconverter en retourneer het object rechtstreeks vanuit de methode.

<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
  <property name="webBindingInitializer">
    <bean class="org.springframework.web.bind.support.ConfigurableWebBindingInitializer"/>
  </property>
  <property name="messageConverters">
    <list>
      <bean class="org.springframework.http.converter.json.MappingJacksonHttpMessageConverter"/>
    </list>
  </property>
</bean>

en de controller:

@RequestMapping(method=RequestMethod.GET, value="foo/bar")
public @ResponseBody Object fooBar(){
    return myService.getActualObject();
}

Dit vereist de afhankelijkheid org.springframework:spring-webmvc.


Antwoord 6

Ik denk niet dat je dat kunt, behalve response.setContentType(..)


Antwoord 7

Mijn versie van de werkelijkheid. Een HTML-bestand laden en naar de browser streamen.

@Controller
@RequestMapping("/")
public class UIController {
    @RequestMapping(value="index", method=RequestMethod.GET, produces = "text/html")
    public @ResponseBody String GetBootupFile() throws IOException  {
        Resource resource = new ClassPathResource("MainPage.html");
        String fileContents = FileUtils.readFileToString(resource.getFile());
        return fileContents;
    }
}

Other episodes