2

我有一个使用 Spring 公开一些 RestServices 的服务器。我有大约 20 种服务,它们几乎总是做同样的事情:获取、列出、保存......

在所有这些服务中,我有一个与其他服务不同的请求:

@RequestMapping(value = {"/{id}"}, method = RequestMethod.GET)
@ResponseBody
public Line get(@PathVariable(value = "id") int id) {
  return lineService.getById(id);
}

问题 :

  • 当我重新启动服务器并第一次调用此特定请求时,我收到 406 错误代码。

  • 之后,所有其他调用都以成功结束,返回格式良好的 JSON 和 HTTP 200 代码等。

请求的 Accept Headers 包含“application/json”。

我试图在 requestMapping 上添加这个:

produces="application/json"

似乎在某个地方,服务器在第一次失败后调整了响应的内容/类型,但我绝对不明白在哪里。

我尝试使用 tomcat 和 jetty 作为后端服务器,但两者都有错误。

有任何想法吗?

编辑 :

经过进一步调查,我在 tomcat 日志中检测到了这种差异。在第一次调用(HTTP 406)时,我可以看到:

09:33:58.637 [http-bio-9090-exec-3] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
09:33:58.637 [http-bio-9090-exec-3] DEBUG o.s.w.a.FixedContentNegotiationStrategy - Requested media types is application/json (based on default MediaType)
09:33:58.654 [http-bio-9090-exec-3] DEBUG o.s.w.s.m.m.a.ExceptionHandlerExceptionResolver - Resolving exception from handler [public com.mycompany.myproject.dto.MyClass com.mycompany.myproject.controller.patrimoine.LigneMobileController.get(int)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
09:33:58.657 [http-bio-9090-exec-3] DEBUG o.s.w.s.m.a.ResponseStatusExceptionResolver - Resolving exception from handler [public com.mycompany.myproject.dto.MyClass com.mycompany.myproject.controller.patrimoine.LigneMobileController.get(int)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
09:33:58.657 [http-bio-9090-exec-3] DEBUG o.s.w.s.m.s.DefaultHandlerExceptionResolver - Resolving exception from handler [public com.mycompany.myproject.dto.MyClass com.mycompany.myproject.controller.patrimoine.LigneMobileController.get(int)]: org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation
09:33:58.657 [http-bio-9090-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'springServlet': assuming HandlerAdapter completed request handling
09:33:58.657 [http-bio-9090-exec-3] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
09:33:58.657 [http-bio-9090-exec-3] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
09:33:58.657 [http-bio-9090-exec-3] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

在第二次通话中,我可以看到这一点(差异从第 2 行开始):

09:50:52.384 [http-bio-9090-exec-7] DEBUG o.s.o.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
09:50:52.385 [http-bio-9090-exec-7] DEBUG o.s.w.s.m.m.a.RequestResponseBodyMethodProcessor - Written [com.mycompany.myproject.dto.patrimoine.mobile.ligne.LigneMobile@18949ad1] as "application/json;charset=UTF-8" using [org.springframework.http.converter.json.MappingJacksonHttpMessageConverter@32a64bcd]
09:50:52.385 [http-bio-9090-exec-7] DEBUG o.s.web.servlet.DispatcherServlet - Null ModelAndView returned to DispatcherServlet with name 'springServlet': assuming HandlerAdapter completed request handling
09:50:52.385 [http-bio-9090-exec-7] DEBUG o.s.web.servlet.DispatcherServlet - Successfully completed request
09:50:52.385 [http-bio-9090-exec-7] DEBUG o.s.s.w.a.ExceptionTranslationFilter - Chain processed normally
09:50:52.385 [http-bio-9090-exec-7] DEBUG o.s.s.w.c.SecurityContextPersistenceFilter - SecurityContextHolder now cleared, as request processing completed

因此,在第一种情况下,我在尝试将对象转换为 JSON 时收到一些 HttpMediaTypeNotAcceptableException。

4

4 回答 4

1

我会首先启动Fiddler之类的东西,以查看实际通过网络传输的位。

于 2013-06-14T19:28:48.390 回答
1

你说,Accept Headers 包含application/json. 我会通过发送请求而不指定接受的内容类型来开始调查。当服务器响应不受特定内容类型的限制时,应该有一些相关的线索。如果 Web 服务器在处理请求期间遇到任何错误,它们通常倾向于返回格式为 HTML 的错误页面。在这种情况下,内容类型当然是 text/html,因此真正的问题被 406 错误混淆了。

于 2013-06-20T07:37:03.657 回答
0

鉴于您仅在重新启动服务器后才看到此错误,这让我认为这可能与延迟类加载有关。

尝试使用在服务器启动时初始化的 servlet(即load-on-startup值为 1),在其init方法中,它指的是所有涉及渲染com.mycompany.myproject.dto.datagrid.LoadResult到 json 的类?

请记住,您试图确保所有涉及的类都在请求进入之前由 ClassLoader 加载。

于 2013-06-20T06:23:38.453 回答
0

您是否尝试在控制器方法的第一行设置断点,即return lineService.getById(id);

我怀疑你会碰到那条线,但是如果你尝试使用调试器“进入”该方法,将会出现一些初始错误。如果我的假设是正确的,那么会在某个地方抛出异常,从而产生一个带有堆栈跟踪的 html 页面。接下来,您将看到 406 发生,因为 html 页面具有 media typeapplication/html或类似的无法转换为application/json.

于 2013-06-18T09:13:20.760 回答