2015-10-19 79 views
1

我想使用springboot運行一個基本的異步服務。
我在調用請求時收到異常。不知道爲什麼會發生這種情況,我使用了oracle網站和澤西網站上的所有說明和代碼片段。有什麼我在這裏失蹤? 請問我是否需要更多信息,我會相應地更新問題。謝謝。與Spring啓動異步服務

org.springframework.beans.BeanInstantiationException: Failed to instantiate [javax.ws.rs.container.AsyncResponse]: Specified class is an interface 
at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:101) 
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.createAttribute(ModelAttributeMethodProcessor.java:137) 
at org.springframework.web.servlet.mvc.method.annotation.ServletModelAttributeMethodProcessor.createAttribute(ServletModelAttributeMethodProcessor.java:80) 
at org.springframework.web.method.annotation.ModelAttributeMethodProcessor.resolveArgument(ModelAttributeMethodProcessor.java:106) 
at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:78) 
at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:162) 
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:129) 
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:110) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:775) 
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:705) 
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) 
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959) 
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893) 
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:967) 
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:858) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:622) 
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:843) 
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85) 
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) 
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239) 
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206) 
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:217) 
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106) 
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502) 
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142) 
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) 
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88) 
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518) 
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091) 
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:673) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1500) 
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1456) 
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) 
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) 
at java.lang.Thread.run(Thread.java:745) 

依賴於POM

<dependencies> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>info.cukes</groupId> 
     <artifactId>cucumber-junit</artifactId> 
     <version>1.1.7</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.bundles.repackaged</groupId> 
     <artifactId>jersey-guava</artifactId> 
     <version>2.22.1</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-common</artifactId> 
     <version>2.22.1</version> 
    </dependency> 
    <dependency> 
     <groupId>org.glassfish.jersey.core</groupId> 
     <artifactId>jersey-client</artifactId> 
     <version>2.22.1</version> 
    </dependency> 
    <dependency> 
     <groupId>info.cukes</groupId> 
     <artifactId>cucumber-picocontainer</artifactId> 
     <version>1.1.7</version> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>info.cukes</groupId> 
     <artifactId>cucumber-spring</artifactId> 
     <version>1.2.4</version> 
    </dependency> 
    <dependency> 
     <groupId>org.seleniumhq.selenium</groupId> 
     <artifactId>selenium-chrome-driver</artifactId> 
     <version>2.42.2</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-test</artifactId> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>commons-dbcp</groupId> 
     <artifactId>commons-dbcp</artifactId> 
     <version>1.4</version> 
    </dependency> 
    <dependency> 
     <groupId>org.postgresql</groupId> 
     <artifactId>postgresql</artifactId> 
     <version>9.3-1100-jdbc41</version> 
    </dependency> 
    <dependency> 
     <groupId>org.dbunit</groupId> 
     <artifactId>dbunit</artifactId> 
     <version>2.4.8</version> 
     <type>jar</type> 
     <scope>test</scope> 
    </dependency> 
    <dependency> 
     <groupId>com.github.springtestdbunit</groupId> 
     <artifactId>spring-test-dbunit</artifactId> 
     <version>1.1.0</version> 
    </dependency> 
    <dependency> 
     <groupId>org.codehaus.jackson</groupId> 
     <artifactId>jackson-core-asl</artifactId> 
     <version>1.9.13</version> 
    </dependency> 
    <dependency> 
     <groupId>org.springframework.boot</groupId> 
     <artifactId>spring-boot-starter-web</artifactId> 
    </dependency> 
    <dependency> 
     <groupId>javax.ws.rs</groupId> 
     <artifactId>javax.ws.rs-api</artifactId> 
     <version>2.0</version> 
    </dependency> 

控制器類

@RestController 
@RequestMapping(value = "backend-service") 
public class AsynchronousController { 

private static int timeout = 50; 

public static void setTimeout(int seconds) { 
    timeout = seconds; 
} 

private static int numberOfSuccessResponses = 0; 
private static int numberOfFailures = 0; 
private static Throwable lastException = null; 

@RequestMapping(method = GET, value = "method") 
public void asyncGet(@Suspended final AsyncResponse asyncResponse) { 
    asyncResponse.setTimeoutHandler(asyncResponse1 -> asyncResponse1.resume(status(SERVICE_UNAVAILABLE) 
      .entity("Operation time out.").build())); 
    asyncResponse.setTimeout(timeout, SECONDS); 

    asyncResponse.register((CompletionCallback) throwable -> { 
     if (throwable == null) { 
      // (response already written to the client) 
      numberOfSuccessResponses++; 
     } else { 
      numberOfFailures++; 
      lastException = throwable; 
     } 
    }); 

    new Thread(new Runnable() { 
     @Override 
     public void run() { 
      String result = veryExpensiveOperation(); 
      asyncResponse.resume(result); 
     } 

     private String veryExpensiveOperation() { 
      JSONObject json = new JSONObject(); 
      try { 
       json.put("timestamp", new Date(System.currentTimeMillis())); 
       json.put("response", newHashMap()); 
       Thread.sleep(10000); 
      } catch (InterruptedException e) { 
       e.printStackTrace(); 
      } catch (JSONException e) { 
       e.printStackTrace(); 
      } 
      // todo check if json is returned 
      return json.toString(); 
     } 
    }).start(); 
    } 
} 
+3

你說你想使用JAX-RS,但你和春天有註釋的春天RestController。您必須選擇是否要爲您的REST端點使用Spring MVC或JAX-RS。 – dunni

回答

4

春天開機默認使用用SpringMVC的服務(你被配置爲使用),但你想在混合因爲這種混淆,Jax-RS我只是想回答如何以Spring MVC的方式做到這一點。

我從記憶寫這個,所以讓我知道,如果我胖手指什麼

你的配置類應該有@EnableAsync

@SpringBootApplication 
@EnableAsync 
public class Application { 
    public static void main(String[] args) { 
     SpringApplication.run(Application.class, args); 
    } 
} 

這是你的控制器

@RestController 
public class MyController { 
    @Autowired 
    MyService myService; 

    //DeferredResult does not send a response until .setResult or setErrorResult is called 
    public DeferredResult<String> myService() { 
     DeferredResult<String> result = new DeferredResult<>(); 
     //I'm using Java8 lambda for brevity use an anonymous class instead if using less than java8 
     myService.asyncLongOperation((operationResult) -> result.setResult(operationResult)) 
     return result; 
    } 
} 

我認爲@Async需要在不同的類中才能正常工作,但可以隨意挑戰我的假設,並在MyController中保留此方法

@Service 
public class MyService { 
    @Async //This annotation replaces building your own thread 
    public void asyncLongOperation(Consumer<String> consumer) { 
     String pie = calculatePieWhichIsShorterThanPi(); 
     consumer.accept(pie); 
    } 
} 

參考 異步 - https://spring.io/guides/gs/async-method/

DeferredResult - https://spring.io/blog/2012/05/07/spring-mvc-3-2-preview-introducing-servlet-3-async-support