我有一个网络服务( Spring-WS )。
我有一个包含多个模式的jar(schema1.xsd,schema2.xsd和schema3.xsd),我将其包含在我的Web服务中。
有没有办法在我的网络服务wep app中以某种方式通过servlet公开jar中的模式?
My Spring MessageDispatcherServlet
映射到/ ws /
我希望我的架构能够展示给/schemas/schema1.xsd
/schemas/schema2.xsd
,依此类推。
我知道如何使用servlet来实现它,但它太冗长了,必须有一个更好的方法。
我正在考虑的方式是有一个servlet过滤器和所有命中/ schemas /检查它是否在我允许的资源列表中并显示它。
这必须是与服务器无关的解决方案。 (例如http://tuckey.org/urlrewrite/将不起作用。)
感谢。
答案 0 :(得分:3)
我了!看过你原来问题的评论后,我想我会提供另一种解决方案。
如果我理解你的问题,你似乎有一个WSDL(由Spring-WS生成),它包含对各种模式的引用。当客户端尝试遵循这些模式引用时,它会失败,因为没有这样的资源。
Spring-WS提供了一种很好的方法,在section on WSDL exposure:
中有描述如果要使用多个架构, 无论是通过包含还是进口,你 可能想用 CommonsXsdSchemaCollection,并参考 来自 DefaultWsdl11Definition,如下所示:
<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
<property name="xsds">
<list>
<value>classpath:/path/to/schema1.xsd</value>
<value>classpath:/path/to/schema2.xsd</value>
</list>
</property>
<property name="inline" value="true"/>
</bean>
启用内联属性后, 它遵循所有XSD导入和 包含,并在其中内嵌 WSDL。这大大简化了 处理模式,仍然 可以编辑它们 分开。
所以你得到的是生成的WSDL,其中所有引用的模式都是内联的,因此 没有引用客户端。它非常灵活,意味着您不必单独公开您的模式文件。
答案 1 :(得分:2)
他们过去发现这样做的唯一方法就是拥有一个Spring控制器(或servlet,无论你的毒药),它打开JAR中资源的流(使用Class.getResourceAsStream
,示例),然后将其“管道”到HTTP响应(使用Apache Commons IO的IOUtils.copy()
)。
这不是很好,但它是一个完全通用的解决方案(只需使用资源的类路径对其进行参数化)。
以下是我的来源:
@Controller
public class ResourceController {
private Resource resource;
@Required
public void setResource(Resource resource) {
this.resource = resource;
}
@RequestMapping
public void handleRequest(HttpServletResponse httpResponse) throws IOException {
InputStream resourceStream = resource.getInputStream();
try {
IOUtils.copy(resourceStream, httpResponse.getOutputStream());
} finally {
resourceStream.close();
}
}
}
答案 2 :(得分:0)
只需将XSD包装在名为schemas.war的war中,放入默认的web.xml,然后在您使用的任何Web容器中部署war。它是解决问题的最简单,无代码的方法。
答案 3 :(得分:0)
对不起,这不是一个“答案”,但在发表评论之前还需要4点。我想把它拿出来,也许可以为别人省去很多麻烦。
我发现如果你只有一个xsd,它只会在使用DefaultWsdl11Definition时合并到wsdl中,但如果你使用<sws:dynamic-wsdl>
块来生成wsdl,它只会创建一个对xsd文件的引用,可能是也可能不是你想要的。在尝试使用.NET客户端来访问服务时,它对我没有用。