简体   繁体   English

如何禁用从控制器返回的对象上的弹簧销毁回调

[英]How to disable spring destruction callback on object returned from controller

EDIT: This turned out to be something else in my configuration 编辑:原来这是我配置中的其他内容

Whenever I return an object with an inferable destruction method from a rest controller, the returned object gets closed, is it possible to disable this? 每当我从rest控制器返回具有可推断破坏方法的对象时,返回的对象都会关闭,是否可以禁用此功能?

For example if I have an object like this: 例如,如果我有一个这样的对象:

public class MyObject implements AutoCloseable {

  // Some json
  private @JsonValue String foo = "hello world";

  public void close () throws Exception {
    System.out.println ("close()");
    new Throwable ("STACK TRACE").printStackTrace (System.out);
  }
}

And a controller like this: 像这样的控制器:

@Controller
public class MyController {

  private Map<String, MyObject> objects = new HashMap<> ();

  @PostConstruct
  private void populate () {
    objects.put ("one", new MyObject ());
    objects.put ("two", new MyObject ());
  }

  @RequestMapping ("/hello/{id}")
  @ResponseBody
  public MyObject test (@PathVariable ("id") String id) {
    return objects.get (id);
  }
}

Spring will call MyObject.close() after it is returned from the controller method. 从控制器方法返回后,Spring将调用MyObject.close()。 This is clearly not a spring managed object and I'd like to disable closing it, syntactically at the controller method site, is that possible? 显然,这不是spring管理的对象,我想在控制器方法站点上从语法上禁用关闭它,这可能吗?

This is with Spring 3.2 and 4.0, from googling around I believe it doesn't happen in 3.1. 这是在Spring 3.2和4.0中进行的,我认为在3.1中不会发生这种情况。

EDIT: Posting the stack trace, the final cleanup() method has a @PreDestroy annotation on it, but same thing happens if I implement AutoCloseable. 编辑:发布堆栈跟踪,最终cleanup()方法上面有一个@PreDestroy批注,但是如果我实现AutoCloseable,也会发生同样的事情。 Objects of SimpleDataset class are not managed by Spring. Spring不管理SimpleDataset类的对象。

java.lang.Throwable: STACK TRACE
    at edu.dfci.cccb.mev.dataset.domain.simple.SimpleDataset.cleanup(SimpleDataset.java:106)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:601)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleElement.invoke(InitDestroyAnnotationBeanPostProcessor.java:349)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor$LifecycleMetadata.invokeDestroyMethods(InitDestroyAnnotationBeanPostProcessor.java:314)
    at org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor.postProcessBeforeDestruction(InitDestroyAnnotationBeanPostProcessor.java:153)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.destroy(DisposableBeanAdapter.java:238)
    at org.springframework.beans.factory.support.DisposableBeanAdapter.run(DisposableBeanAdapter.java:231)
    at org.springframework.web.context.request.AbstractRequestAttributes.executeRequestDestructionCallbacks(AbstractRequestAttributes.java:91)
    at org.springframework.web.context.request.AbstractRequestAttributes.requestCompleted(AbstractRequestAttributes.java:47)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:949)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:822)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:735)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:807)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:848)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:686)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:501)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:137)
    at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:557)
    at org.eclipse.jetty.server.session.SessionHandler.doHandle(SessionHandler.java:231)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:428)
    at org.eclipse.jetty.server.session.SessionHandler.doScope(SessionHandler.java:193)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:154)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:370)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:489)
    at org.eclipse.jetty.server.AbstractHttpConnection.headerComplete(AbstractHttpConnection.java:949)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.headerComplete(AbstractHttpConnection.java:1011)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:644)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:235)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:668)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:52)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:722)

When you have @ResponseBody annotated handler method, Spring uses a RequestResponseBodyMethodProcessor to handle the value returned. 当您使用@ResponseBody注释的处理程序方法时,Spring使用RequestResponseBodyMethodProcessor来处理返回的值。

This is done in ServletInvocableHandlerMethod#invokeAndHandler(..) which is implemented as such 这是在ServletInvocableHandlerMethod#invokeAndHandler(..) ,该实现是这样实现的

public final void invokeAndHandle(ServletWebRequest webRequest,
        ModelAndViewContainer mavContainer, Object... providedArgs) throws Exception {

    Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);

    setResponseStatus(webRequest);

    if (returnValue == null) {
        if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
            mavContainer.setRequestHandled(true);
            return;
        }
    }
    else if (StringUtils.hasText(this.responseReason)) {
        mavContainer.setRequestHandled(true);
        return;
    }

    mavContainer.setRequestHandled(false);

    try {
        this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
    }
    catch (Exception ex) {
        if (logger.isTraceEnabled()) {
            logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
        }
        throw ex;
    }
}

where 哪里

this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);

delegates to the RequestResponseBodyMethodProcessor . 委托给RequestResponseBodyMethodProcessor Nothing in here calls close() on your return value. 这里的任何内容都不会对您的返回值调用close()

What you are describing is not possible by default. 默认情况下,您所描述的内容是不可能的。 You must have something else in your configuration. 您的配置中还必须包含其他内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 获取从spring控制器返回的模型对象,并将其分配给全局变量? - Get model object returned from spring controller and assign it to global variable? 如何从控制器发送返回的布尔结果以在Spring MVC中查看 - How to send the returned boolean result from controller to view in spring mvc Retrofit (Android) - 获取从回调返回的对象 - Retrofit (Android) - Getting An Object Returned From Callback 如何将对象从angularjs传递到spring控制器 - How to pass an object from angularjs to spring controller 如何在JSP中使用从Spring MVC返回的模型对象 - How to use Model object returned from spring mvc in jsp 如何使用Spring Security将对象从AJAX传递到Spring Controller - How to pass an Object from AJAX to a Spring Controller with Spring Security How to pass JSON Object and return Object from Spring rest controller - How to pass JSON Object and return Object from Spring rest controller 使用Spring控制器返回的jQuery和GSON解析JSON对象 - Parsing JSON object using jQuery and GSON returned by Spring controller 如何在java弹簧框架中的modelAndView.getModel()返回的spring控制器本身内部的modelMap对象中获取所有键值对 - How to get all the key value pairs in modelMap object , inside spring controller itself , returned by modelAndView.getModel() in java spring framework 如何禁用基本 spring controller 端点 - How to disable basic spring controller endpoints
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM