如何更改Spring-WS的“SOAP-ENV”默认前缀(How to change “SOAP-ENV” default prefix of Spring-WS)

我使用Spring-WS创建了一个Web服务。 为了保持与旧系统的兼容性,我需要将名称空间前缀从SOAP-ENV更改为soap

我知道SOAP-ENVsoap只是命名空间前缀。 只要他们引用了正确的名称空间( "http://schemas.xmlsoap.org/soap/envelope/" ),它应该没问题。

但旧系统对解析器代码进行了硬编码,只期望soap名称空间前缀。

当前的回应:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
   ...
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

预期回应:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Header/>
   <soap:Body>
   ...
   </soap:Body>
</soap:Envelope>

这是迄今为止我尝试过的

  1. 创建EndpointInterceptorAdapter子类。 这将拦截SOAP响应/错误并更改SOAP信封。 这有效,但在性能方面并不理想。

    public class CustomEndpointInterceptor extends EndpointInterceptorAdapter {
    
      private static final String DEFAULT_NS = "xmlns:SOAP-ENV";
      private static final String SOAP_ENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
      private static final String PREFERRED_PREFIX = "soap";
      private static final String HEADER_LOCAL_NAME = "Header";
      private static final String BODY_LOCAL_NAME = "Body";
      private static final String FAULT_LOCAL_NAME = "Fault";
    
      @Override
      public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapResponse);
        return super.handleResponse(messageContext, endpoint);
      }
    
      @Override
      public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapResponse);
        return super.handleFault(messageContext, endpoint);
      }
    
      private void alterSoapEnvelope(SaajSoapMessage soapResponse) {
        Document doc = soapResponse.getDocument();
        Element rootElement = doc.getDocumentElement();
        rootElement.setPrefix(PREFERRED_PREFIX);
        // Remove default SOAP namespace
        rootElement.removeAttribute(DEFAULT_NS);
        NodeList headerNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, HEADER_LOCAL_NAME);
        NodeList bodyNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, BODY_LOCAL_NAME);
        NodeList faultNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, FAULT_LOCAL_NAME);
        // Remove Header node.
        if (headerNodes.getLength() != 0) {
          rootElement.removeChild(headerNodes.item(0));
        }
        // Change Body's SOAP namespace prefix.
        if (bodyNodes.getLength() != 0) {
          Element bodyElement = (Element) bodyNodes.item(0);
          bodyElement.setPrefix(PREFERRED_PREFIX);
        }
        if (faultNodes.getLength() != 0) {
          Element faultElement = (Element) faultNodes.item(0);
          faultElement.setPrefix(PREFERRED_PREFIX);
        }
      }
    }
    
  2. 在包含WSDL生成的类的包中更改package-info.java 。 我用我公司的名称空间前缀成功完成了这项工作,但它不适用于SOAP-ENV前缀。

    @javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.com/ns/2008/02/02/webservices/blah",
    xmlns = {
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://www.example.com/ns/2008/02/02/webservices/blah", prefix = ""),
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.example.com/ns/2007/10/blah", prefix = "ns2"),
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://example.com/ns/2007/23/05/blah/fundamental", prefix = "ns3"),
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap") // doesn't work
    },
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
    package com.thomsonreuters.ts.ets.interdayws.soap.webservice;
    

有没有一种理想的方法可以在Spring-WS中将SOAP-ENV更改为soap

顺便说一句,这是设置这个前缀的代码。 StroapElement.java


I've created a web service using Spring-WS. To maintain compatibility with the old system, I need to change namespace prefix from SOAP-ENV to soap.

I know that SOAP-ENV and soap are just namespace prefixes. As long as they refer to the correct namespace ("http://schemas.xmlsoap.org/soap/envelope/"), it should be fine.

But the old system hard coded the parser code to expect only soap namespace prefix.

Current response:

<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
   <SOAP-ENV:Header/>
   <SOAP-ENV:Body>
   ...
   </SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Expected response:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
   <soap:Header/>
   <soap:Body>
   ...
   </soap:Body>
</soap:Envelope>

Here's what I've tried so far

  1. Create EndpointInterceptorAdapter subclass. This will intercept SOAP response/fault and alter the SOAP envelope. This works, but it's not ideal in terms of performance.

    public class CustomEndpointInterceptor extends EndpointInterceptorAdapter {
    
      private static final String DEFAULT_NS = "xmlns:SOAP-ENV";
      private static final String SOAP_ENV_NAMESPACE = "http://schemas.xmlsoap.org/soap/envelope/";
      private static final String PREFERRED_PREFIX = "soap";
      private static final String HEADER_LOCAL_NAME = "Header";
      private static final String BODY_LOCAL_NAME = "Body";
      private static final String FAULT_LOCAL_NAME = "Fault";
    
      @Override
      public boolean handleResponse(MessageContext messageContext, Object endpoint) throws Exception {
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapResponse);
        return super.handleResponse(messageContext, endpoint);
      }
    
      @Override
      public boolean handleFault(MessageContext messageContext, Object endpoint) throws Exception {
        SaajSoapMessage soapResponse = (SaajSoapMessage) messageContext.getResponse();
        alterSoapEnvelope(soapResponse);
        return super.handleFault(messageContext, endpoint);
      }
    
      private void alterSoapEnvelope(SaajSoapMessage soapResponse) {
        Document doc = soapResponse.getDocument();
        Element rootElement = doc.getDocumentElement();
        rootElement.setPrefix(PREFERRED_PREFIX);
        // Remove default SOAP namespace
        rootElement.removeAttribute(DEFAULT_NS);
        NodeList headerNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, HEADER_LOCAL_NAME);
        NodeList bodyNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, BODY_LOCAL_NAME);
        NodeList faultNodes = doc.getElementsByTagNameNS(SOAP_ENV_NAMESPACE, FAULT_LOCAL_NAME);
        // Remove Header node.
        if (headerNodes.getLength() != 0) {
          rootElement.removeChild(headerNodes.item(0));
        }
        // Change Body's SOAP namespace prefix.
        if (bodyNodes.getLength() != 0) {
          Element bodyElement = (Element) bodyNodes.item(0);
          bodyElement.setPrefix(PREFERRED_PREFIX);
        }
        if (faultNodes.getLength() != 0) {
          Element faultElement = (Element) faultNodes.item(0);
          faultElement.setPrefix(PREFERRED_PREFIX);
        }
      }
    }
    
  2. Change package-info.java in the package that contain WSDL generated classes. I've successfully done this with my company's namespace prefix, but it doesn't work for SOAP-ENV prefix.

    @javax.xml.bind.annotation.XmlSchema(namespace = "http://www.example.com/ns/2008/02/02/webservices/blah",
    xmlns = {
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://www.example.com/ns/2008/02/02/webservices/blah", prefix = ""),
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.example.com/ns/2007/10/blah", prefix = "ns2"),
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://example.com/ns/2007/23/05/blah/fundamental", prefix = "ns3"),
      @javax.xml.bind.annotation.XmlNs(namespaceURI = "http://schemas.xmlsoap.org/soap/envelope/", prefix = "soap") // doesn't work
    },
    elementFormDefault = javax.xml.bind.annotation.XmlNsForm.QUALIFIED)
    package com.thomsonreuters.ts.ets.interdayws.soap.webservice;
    

Is there an ideal way to change SOAP-ENV to soap in Spring-WS?

By the way, here's the code that set this prefix. StroapElement.java


原文:https://stackoverflow.com/questions/39242197
2023-07-12 15:07

满意答案

INSERT INTO co_names 
(
id, English, Spanish, French, German, Italian, Portugues, Turkish
)
SELECT CONVERT(country_numeric_code, UNSIGNED), 
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'ENGLISH'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'SPANISH'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'FRENCH'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'GERMAN'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'ITALIAN'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'PORTUGUESE'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'TURKISH'), 'Unknown')
FROM ulkeler u
GROUP BY country_numeric_code;

请注意co_names表中拼写错误的“葡萄牙语”列(缺少最后“e”)。


INSERT INTO co_names 
(
id, English, Spanish, French, German, Italian, Portugues, Turkish
)
SELECT CONVERT(country_numeric_code, UNSIGNED), 
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'ENGLISH'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'SPANISH'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'FRENCH'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'GERMAN'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'ITALIAN'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'PORTUGUESE'), 'Unknown'),
IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'TURKISH'), 'Unknown')
FROM ulkeler u
GROUP BY country_numeric_code;

Note misspelling of the 'Portuguese' column (missing last 'e') in your co_names table.

相关问答

更多

原子上复制一个MySQL表的另一个?(Atomically copying one MySQL table over another?)

使用重命名表 RENAME TABLE old_table TO backup_table, new_table TO old_table; 它是原子的,适用于所有存储引擎,并且不必重建索引。 Use rename table RENAME TABLE old_table TO backup_table, new_table TO old_table; It's atomic, works on all storage engines, and doesn't have to rebuild ...

INSERT INTO从表复制到另一个(INSERT INTO copying from table to another)

INSERT INTO co_names ( id, English, Spanish, French, German, Italian, Portugues, Turkish ) SELECT CONVERT(country_numeric_code, UNSIGNED), IFNULL((SELECT MAX(country_name) FROM ulkeler WHERE u.lang_name = 'ENGLISH'), 'Unknown'), IFNULL((SELECT MAX(c...

将数据从一个表复制到另一个表的存储过程(Stored Procedure for copying data from one table to another)

SQL不是那么长......但是如果你喜欢一个过程,这里是: create or replace procedure table_copy( p_tab_from varchar2, p_tab_to varchar2) is begin execute immediate 'insert into '||p_tab_to||' (select * from '||p_tab_from||')'; end; SQL is not so long... But if you pre...

我无法使用SQL Ce将日期时间复制到另一个日期时间表(I cant copying datetime to another datetime table with SQL Ce)

您的插入列的列顺序似乎是向后的: INSERT RESUMEN (FECHA,ARTICULO,METROS) SELECT ARTICULO,FECHA, Sum(METROS) as Cant FROM HISTORIC WHERE FECHA BETWEEN '07/08/2016' AND '07/12/2016' GROUP BY ARTICULO,FECHA 您正在FECHA列中插入ARTICULO 。 切换这两个字段: INSERT RESUMEN (FECHA,ARTIC...

使用perl和DBI将一个非常大的表从一个DB2复制到另一个(copying a very large table from one DB2 to another, using perl and DBI)

如果你把它包装到一个事务中,它应该工作得更快。 使用这样的东西: $sth1 = $udb1->prepare($read_query); $sth1->execute(); $sth1->bind_columns(\(@row{@{$sth1->{NAME_1c}}})); $udb2->begin_work(); $sth2 = $udb2->prepare($write_query); while ($sth1->fetchrow_arrayref()) { $sth2->exec...

将日期从一个表复制到另一个表并更改mysql中的格式(Copying date from one table to another and change format in mysql)

首先,你的代码有几个问题。 一个体面的IDE会在编辑中向你显示。 代码问题 mysqli_set_charset($con1, 'utf8'); 在确认连接建立之前,您正尝试使用连接来设置字符集。 if (!$con1) { die(mysqli_connect_error($con1)); } mysqli_connect_error()不带任何参数,无论如何$con1都是false的。 $id_product = $row[prod_id]; 没有不变的prod_id 。...

SQL Server使用STUFF和GROUP BY将数据复制到另一个表(SQL Server copying data to another table using STUFF and GROUP BY)

给出max(product_id)的别名 INSERT INTO [ProductsImported] (image_url, product_id, item_size) SELECT image_url, MAX(product_id) As product_id, STUFF((SELECT ',' + item_size AS [text()] FROM (SELEC...

如何在其他表中复制数据时插入数据(How to Insert data while Copying data in other Table)

参数化查询有两个主要优点: 安全性:这是避免SQL注入漏洞的好方法 性能:如果您仅使用不同的参数定期调用相同的查询,则参数化查询可能允许数据库缓存您的查询,这是性能增益的重要来源。 额外:您不必担心数据库代码中的日期和时间格式问题。 同样,如果您的代码将在具有非英语语言环境的计算机上运行,则不会出现小数点/小数点逗号的问题。 试试这样吧 Dim sqlquery As String= "INSERT INTO Table2 (ToolName,Descrption) SELECT ToolName...

将行从一个表复制到另一个表?(Copying row from one table to another?)

INSERT INTO servico_executado SELECT id, data_abertura, id_solicitacao, id_profissional FROM servico WHERE id = NEW.id_servico; 不要使用'VALUES'。 如果表中有更多列,则可以在select语句中为缺少的列使用null。 INSERT INTO servico_executado SELECT id, data_ab...

Oracle - 将表数据从一个模式复制到另一个模式(Oracle - Copying table data from one schema to another schema)

您不需要存储过程,也不需要光标。 使用单个语句执行此操作会更有效。 编辑为ARCHIVE_ID列生成唯一值,您应该创建一个序列: CREATE SEQUENCE SEQ_ARCHIVE_ID; 然后在insert语句中使用它: INSERT INTO DEV_ARCHIVE.BRIC_ARCHV (ARCHIVE_ID, SUSPENSE_CD, RECORD_ID, SUSPENSE_DATE, PEND_DATE, PEND_NOTE) select seq_archive_id...

相关文章

更多

Spring MVC 3 深入总结

一、前言: 大家好,Spring3 MVC是非常优秀的MVC框架,由其是在3.0版本发布后,现在有越来 ...

eclipse的默认(打开)编辑器的更改

eclipse / MyEclipse JSP默认打开方式是 MyEclipse Visual JSP ...

最新问答

更多

获取MVC 4使用的DisplayMode后缀(Get the DisplayMode Suffix being used by MVC 4)

我用Google搜索了一个解决方案。 “EnumDisplayModeProvider”是我自己设置网站的各种模式的枚举。 public EnumDisplayModeProvider GetDisplayModeId() { foreach (var mode in DisplayModeProvider.Instance.Modes) if (mode.CanHandleContext(HttpContext)) {

如何通过引用返回对象?(How is returning an object by reference possible?)

这相对简单:在类的构造函数中,您可以分配内存,例如使用new 。 如果你制作一个对象的副本,你不是每次都分配新的内存,而是只复制指向原始内存块的指针,同时递增一个也存储在内存中的引用计数器,使得每个副本都是对象可以访问它。 如果引用计数降至零,则销毁对象将减少引用计数并仅释放分配的内存。 您只需要一个自定义复制构造函数和赋值运算符。 这基本上是共享指针的工作方式。 This is relatively easy: In the class' constructor, you allocate m

矩阵如何存储在内存中?(How are matrices stored in memory?)

正如它在“熵编码”中所说的那样,使用Z字形图案,与RLE一起使用,在许多情况下,RLE已经减小了尺寸。 但是,据我所知,DCT本身并没有给出稀疏矩阵。 但它通常会增强矩阵的熵。 这是compressen变得有损的点:输入矩阵用DCT传输,然后量化量化然后使用霍夫曼编码。 As it says in "Entropy coding" a zig-zag pattern is used, together with RLE which will already reduce size for man

每个请求的Java新会话?(Java New Session For Each Request?)

你是如何进行重定向的? 您是否事先调用了HttpServletResponse.encodeRedirectURL()? 在这里阅读javadoc 您可以使用它像response.sendRedirect(response.encodeRedirectURL(path)); The issue was with the path in the JSESSIONID cookie. I still can't figure out why it was being set to the tomca

css:浮动div中重叠的标题h1(css: overlapping headlines h1 in floated divs)

我认为word-break ,如果你想在一个单词中打破行,你可以指定它,这样做可以解决问题: .column { word-break:break-all; } jsFiddle演示。 您可以在此处阅读有关word-break属性的更多信息。 I think word-break, with which you can specify if you want to break line within a word, will do the trick: .column { word-break

无论图像如何,Caffe预测同一类(Caffe predicts same class regardless of image)

我认为您忘记在分类时间内缩放输入图像,如train_test.prototxt文件的第11行所示。 您可能应该在C ++代码中的某个位置乘以该因子,或者使用Caffe图层来缩放输入(请查看ELTWISE或POWER图层)。 编辑: 在评论中进行了一次对话之后,结果发现在classification.cpp文件中错误地删除了图像均值,而在原始训练/测试管道中没有减去图像均值。 I think you have forgotten to scale the input image during cl

xcode语法颜色编码解释?(xcode syntax color coding explained?)

转到: Xcode => Preferences => Fonts & Colors 您将看到每个语法高亮颜色旁边都有一个简短的解释。 Go to: Xcode => Preferences => Fonts & Colors You'll see that each syntax highlighting colour has a brief explanation next to it.

在Access 2010 Runtime中使用Office 2000校对工具(Use Office 2000 proofing tools in Access 2010 Runtime)

你考虑过第三方拼写检查吗? 您可以将在C#中开发的自定义WinForms控件插入访问数据库吗? VB6控件怎么样? 如果你能找到一个使用第三方库进行拼写检查的控件,那可能会有效。 Have you considered a third party spell checker? Can you insert a custom WinForms controls developed in C# into an access database? What about a VB6 control? If

从单独的Web主机将图像传输到服务器上(Getting images onto server from separate web host)

我有同样的问题,因为我在远程服务器上有两个图像,我需要在每天的预定义时间复制到我的本地服务器,这是我能够提出的代码... try { if(@copy('url/to/source/image.ext', 'local/absolute/path/on/server/' . date("d-m-Y") . ".gif")) { } else { $errors = error_get_last(); throw new Exception($err

从旧版本复制文件并保留它们(旧/新版本)(Copy a file from old revision and keep both of them (old / new revision))

我不确定我完全明白你在说什么。 你能编辑你的帖子并包含你正在做的Subversion命令/操作的特定顺序吗? 最好使用命令行svn客户端,以便容易为其他人重现问题。 如果您只是想获取文件的旧副本(即使该文件不再存在),您可以使用如下命令: svn copy ${repo}/trunk/moduleA/file1@${rev} ${repo}/trunk/moduleB/file1 其中${repo}是您的存储库的URL, ${rev}是您想要的文件的版本。 这将恢复该文件的旧版本,包括最高版本