【问题标题】:Spring MVC, Serving RESTFul request (json) and JSP (content negotiation)Spring MVC、Serving RESTFul request (json) 和 JSP(内容协商)
【发布时间】:2017-01-16 09:49:54
【问题描述】:

我正在尝试创建一个 Spring MVC 4 Web 项目(Maven 项目)以处理 REST 请求。 如果 HTTP 接受是 text/html,系统应使用网页进行回答 如果它是 application/json,则在 json 中(如果它是 application/xml,可能还有其他格式,如 XML)。

我已经设置了一个控制器和 JSP(我还使用了@RestController)。问题是我不能让它一起工作。如果系统使用 JSP 正确应答,则 json 服务不工作,反之亦然。 我是否必须为每个表示设置一个处理程序,以及如何设置?

提前谢谢你。

【问题讨论】:

  • 您是尝试处理 REST 请求还是只是尝试发出 ajax 请求?您可以使用返回 jsp 的方法和一些由 @ResponseBody 注释的返回 JSON 或 XML 内容的方法创建特定的控制器
  • 我想要一个休息请求(例如 example.com/get/resourceID)并获得不同格式的响应(web jsp、json xml ...)。如何根据内容协商设置不同的处理程序?

标签: rest spring-mvc content-negotiation


【解决方案1】:

要确定用户请求的格式依赖于 ContentNegotationStrategy,有现成可用的默认实现,但如果您愿意,您也可以实现自己的

使用 HTTP 消息转换器 配置和使用 Spring 的内容协商:

你必须在 Spring MVC 中启用内容协商:

<bean id="cnManager"
    class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
    <property name="favorPathExtension" value="true"/>
    <property name="ignoreAcceptHeader" value="true" />
    <property name="defaultContentType" value="application/json" />
    <property name="useJaf" value="false"/>

    <property name="mediaTypes">
        <map>
            <entry key="html" value="text/html" />
            <entry key="json" value="application/json" />
            <entry key="xml" value="application/xml" />
        </map>
    </property>
</bean>

或者使用java配置:

@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {


  @Override
 public void configureContentNegotiation(
            ContentNegotiationConfigurer configurer) {
        configurer.favorPathExtension(true).
            ignoreAcceptHeader(true).
            useJaf(false).
            defaultContentType(MediaType.TEXT_HTML).
            mediaType("html", MediaType.TEXT_HTML).
            mediaType("xml", MediaType.APPLICATION_XML).
            mediaType("json", MediaType.APPLICATION_JSON);
    }
}

【讨论】:

  • 我已经使用 @RestController 注释对此进行了测试,但是当您使用 application/json 标头调用资源时,它会返回 json;当您使用标准文本/html 标头调用时,即使 JSP 在那里,它也无法找到查看器。我必须创建一个特定的处理程序吗?
  • 这是正常的 jsp 页面由 ContentNegotiatingViewResolver 解析:“org.springframework.web.servlet.view.InternalResourceViewResolver”你必须分开你的休息服务!从您应该返回视图的方法中!
  • 你有例子吗?
  • 我添加了一个例子:你的页面应该在这个文件夹中
【解决方案2】:

这是一个例子: 第一种方法将为 url end .../client 的每个 get 返回 client.jsp 页面,第二个方法将为每个 get end .../clients/id 返回一个 client json 对象

@RequestMapping(value = "/client", method = RequestMethod.GET)
public ModelAndView getClientPage(final HttpServletRequest request,
        final Model model,final HttpSession session) {
      // traitement 

    return new ModelAndView("client");
}

@RequestMapping(value = "/clients/{id}", method = RequestMethod.GET)
public @ResponseBody Client getClient(@pathVariable("id") long id) {

    Client client =  YourService.getClient(id);

    return client;
}

Contentnegotiatingviewresolver java 配置:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.yourbasepackage")
public class AppConfig extends WebMvcConfigurerAdapter {


    @Bean
    public ViewResolver jspViewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        viewResolver.setViewClass(JstlView.class);
        viewResolver.setPrefix("/WEB-INF/views/");
        viewResolver.setSuffix(".jsp");
        return viewResolver;
    }

}

【讨论】:

  • 谢谢你的例子,但我已经在那个时候了......问题是我的应用程序应该以不同的格式回答基于 HTTP 接受标头的相同 URL。示例 -> URL:/clients/123 接受:text/html 返回 JSP; URL:/clients/123 接受:application/json 返回 json
猜你喜欢
  • 1970-01-01
  • 2014-06-15
  • 2011-04-06
  • 2010-11-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
相关资源
最近更新 更多