web-dev-qa-db-ja.com

Spring MVCでは、@ ResponseBodyを使用するときにMIMEタイプヘッダーを設定するにはどうすればよいですか

JSON文字列を返すSpring MVC Controllerがあり、mimetypeをapplication/jsonに設定したいと思います。どうやってやるの?

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

ビジネスオブジェクトはすでにJSON文字列として利用可能であるため、MappingJacksonJsonViewを使用することは私にとって解決策ではありません。 @ResponseBodyは完璧ですが、どのようにmimetypeを設定できますか?

74

JSON文字列ではなくドメインオブジェクトを返すようにサービスをリファクタリングし、Springにシリアル化を処理させることを検討します(作成時にMappingJacksonHttpMessageConverterを使用)。 Spring 3.1現在、実装は非常にきれいに見えます。

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

コメント:

まず、<mvc:annotation-driven />または@EnableWebMvcは、アプリケーション構成に 追加 である必要があります。

次に、@RequestMapping注釈の produces 属性を使用して、応答のコンテンツタイプを指定します。したがって、 MediaType.APPLICATION_JSON_VALUE (または"application/json")に設定する必要があります。

最後に、ジャクソンを追加して、JavaとJSONの間のシリアライゼーションとデシリアライゼーションがSpringによって自動的に処理されるようにします(ジャクソンの依存関係はSpringによって検出され、MappingJacksonHttpMessageConverterボンネットの下にあります)。

39
matsev

ResponseEntityの代わりにResponseBodyを使用します。これにより、応答ヘッダーにアクセスでき、適切なコンテンツタイプを設定できます。 Spring docs によると:

HttpEntity@RequestBodyおよび@ResponseBodyに似ています。リクエストとレスポンスの本文へのアクセスに加えて、HttpEntity(およびレスポンス固有のサブクラスResponseEntity)もリクエストとレスポンスのヘッダーへのアクセスを許可します

コードは次のようになります。

@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);
}
118
Javier Ferrero

@ResponseBodyで実行できない場合がありますが、次のように機能します。

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();
  }
}
7
GriffeyDog

これが可能だとは思わない。オープンなJiraが存在するようです:

SPR-6702:@ResponseBodyの応答Content-Typeを明示的に設定

4
dogbane

org.springframework.http.converter.json.MappingJacksonHttpMessageConverterをメッセージコンバーターとして登録し、メソッドから直接オブジェクトを返します。

<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>

およびコントローラー:

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

これには、依存関係org.springframework:spring-webmvcが必要です。

3
OrangeDog

response.setContentType(..)を除いて、できるとは思わない

1
Bozho