【问题标题】:restful webservice public constructor not found未找到宁静的 Web 服务公共构造函数
【发布时间】:2013-02-21 01:01:19
【问题描述】:

我正在尝试使用客户端 Web 应用程序调用 RESTful Web 服务(来自 JSF MB 的简单客户端请求)。我需要为 web 服务创建一个接口,然后调用其中的方法。但是如果我在接口上使用@Path,它会给出一个错误——在 Jboss 部署期间找不到公共构造函数。但是如果我在实现类给@Path。它调用服务很好并且工作正常。我需要在 Rest 客户端和 Restful webservice impl 类之间有一个 Java 接口。任何人都可以帮忙吗?我们可以有 Rest 接口吗?

客户端:

ClientRequest request = new ClientRequest("localhost:8080/RESTfulExample/json/...../"); 
ClientResponse<String> response = request.get(String.class);

休息接口:

package com.nee.interfaces; 
import javax.ws.rs.Path; 
import javax.ws.rs.GET; 

@Path("/OrderManagementService") 
public interface OrderManagementServiceInterface { 
    @GET
    @Path("/GetListOfOrders") 
    void getListOfOrders(); 
}

实施:

package com.nee.implementations;
import com.nee.interfaces.OrderManagementServiceInterface;


public class OrderManagementServiceImpl implements OrderManagementServiceInterface {
    public void getListOfOrders() {
        System.out.println("am here");
    }
}

web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>
        com.nee.interfaces.OrderManagementServiceInterface
    </param-value>
</context-param>

<!-- this has to match with resteasy-servlet url-pattern -->

<context-param>
    <param-name>resteasy.servlet.mapping.prefix</param-name>
    <param-value>/rest</param-value>
</context-param>

<!-- to return data according to extension -->

<context-param>
    <param-name>resteasy.media.type.mappings</param-name>
    <param-value>json : application/json, xml : application/xml</param-value>
</context-param>

<listener>
    <listener-class>
        org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap
    </listener-class>
</listener>

<servlet>
    <servlet-name>resteasy-servlet</servlet-name>
    <servlet-class>
        org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher
    </servlet-class>
</servlet>

<servlet-mapping>
    <servlet-name>resteasy-servlet</servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>
</web-app>

日志:

[org.apache.catalina.core.ContainerBase.[jboss.web].[default-host].[/web]]
(MSC service thread 1-2) Exception sending context initialized event to listener instance of class
org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap: java.lang.RuntimeException: Unable to find a public constructor for class com.seagate.interfaces.OrderManagementServiceInterface
at org.jboss.resteasy.plugins.server.resourcefactory.POJOResourceFactory.registered(POJOResourceFactory.java:35) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:120) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:106) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.ResourceMethodRegistry.addResourceFactory(ResourceMethodRegistry.java:83) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.core.ResourceMethodRegistry.addPerRequestResource(ResourceMethodRegistry.java:72) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.spi.ResteasyDeployment.registration(ResteasyDeployment.java:383) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.spi.ResteasyDeployment.start(ResteasyDeployment.java:225) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.jboss.resteasy.plugins.server.servlet.ResteasyBootstrap.contextInitialized(ResteasyBootstrap.java:28) [resteasy-jaxrs-2.3.3.Final-redhat-1.jar:2.3.3.Final-redhat-1]
at org.apache.catalina.core.StandardContext.contextListenerStart(StandardContext.java:3392) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.apache.catalina.core.StandardContext.start(StandardContext.java:3850) [jbossweb-7.0.16.Final-redhat-1.jar:]
at org.jboss.as.web.deployment.WebDeploymentService.start(WebDeploymentService.java:90) [jboss-as-web-7.1.2.Final-redhat-1.jar:7.1.2.Final-redhat-1]
at org.jboss.msc.service.ServiceControllerImpl$StartTask.startService(ServiceControllerImpl.java:1811)
at org.jboss.msc.service.ServiceControllerImpl$StartTask.run(ServiceControllerImpl.java:1746)
at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)[rt.jar:1.7.0_09]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) [rt.jar:1.7.0_09]
at java.lang.Thread.run(Unknown Source) [rt.jar:1.7.0_09]

【问题讨论】:

  • 发布您的代码。如果您使用的是接口,则应在其上定义所有 JAX-RS 注释。
  • 请使用格式正确的代码更新您的帖子。
  • 您的接口代码不可编译。我们还需要您的实现代码。
  • 如果我在 Impl 类中给出@Path 注释 .. 并在 web.xml 中配置路径... 一切都一样.. 它工作正常..
  • 我没有在接口代码中看到任何编译错误。如果有任何编译错误,请告诉我...正如我现在所说的,在 impl 类中没什么大不了的...我只关心调用接口...在 IMPL 中,我只是在控制台中打印一条消息..我也有更新 impl 代码..

标签: java web-services rest


【解决方案1】:

我猜你的错误是你给 RestEasy 一个 interface 并且框架试图通过反射创建它的一个实例。这样的事情永远不会奏效。而不是接口,您应该只指定实现类作为参数resteasy.resources 的值。如果您想更动态地尝试 OSGi 和 REST 的组合。 this 博客中的示例我没有亲自尝试过,但你可以看看。

更新

由于您还想使用来自第三方类的服务,为什么不使用您的 REST Web 服务包装另一个接口,并且该包装的接口可以在您的第三方类中使用。然后,Web 服务仅用于将请求委托给该接口的特定实现。您可以通过 Spring、Google Juice 等依赖注入框架注入实现。这就是我的意思:

您的接口作为实现的抽象:

interface IExecutionService {
   void executeStuff();
}

然后是你的 REST 服务:

@Path("/OrderManagementService")
class ExectionServiceDelegator {

   private IExecutionService wrappedServiceInterface;

   /**
    * play around with some DI frameworks for injecting your implementation
    */
   public void setIExecutionService(IExecutionService service) {
      wrappedServiceInterface = service;    
   }

   @GET
   @Path("/GetListOfOrders") 
   public void doingSomething() {
      service.executeStuff();
   }
}

您也可以在第三方接口中将接口IExecutionService 与特定的DI 框架结合使用。希望很清楚我想用上面的代码做什么?!

【讨论】:

  • 感谢 christian...所以我们不能在没有 OSGI 的情况下使用 resteasy 界面???.. 真的很伤心。通常对于基于 SOAP 的 Web 服务,我们曾经有一个接口来调用服务。
  • 即使在 OSGi 中,您通常也不使用直接接口来抽象 REST 服务。在我看来,这没有多大意义。为什么?因为在从客户端调用资源时,您实际上并没有使用特定的实现。你只是调用一个 URL 而没有类。只有您的应用程序服务器负责将这些 URL 映射到资源(在您的示例中,您在类中指定的 REST 资源路径)。这意味着 URL 以某种方式是您的“接口”。您只需为类定义相同的路径即可轻松更改实现...
  • ... 只需更改 the resteasy.resources 参数即可将 URL 路径映射到您的新类。希望现在更清楚了,您不必过于依赖 Java 接口 :) 正如您所看到的,所提供博客中的示例也没有使用接口。 ;)
  • 实际上我的 web 服务也会被一些第三方接口使用。我只是不想向他们公开我的实现。那就是我渴望在两者之间有接口。是的,克里斯!如果我直接为 impl 类设置路径,我就可以调用服务......我只是希望 Java Reflection 没有玩过这样的破坏游戏来直接调用接口......我仍然很难过 :(
  • 为什么不将 REST 用作底层实现的桥梁/适配器。我将更新我的答案以澄清我的意思。
【解决方案2】:

上面的问题有一个简单的答案。在 web.xml 中,而不是接口,我只需要配置 IMPL 类而不是接口并继续在接口处设置@Path

<context-param>
    <param-name>resteasy.resources</param-name>
    <param-value>
        com.seagate.implementations.OrderManagementServiceImpl
    </param-value>
</context-param>

它工作了:)...

【讨论】:

  • 这就是我在回答中对你说的!第一部分
猜你喜欢
  • 2011-03-01
  • 1970-01-01
  • 2019-03-17
  • 2020-04-29
  • 1970-01-01
  • 2011-10-23
  • 1970-01-01
  • 2018-04-21
  • 1970-01-01
相关资源
最近更新 更多