从Loopback Remote Method返回XML

时间:2015-07-01 20:51:30

标签: node.js express loopbackjs

我正在使用Loopback Connector REST(1.9.0)并且有一个返回XML的远程方法:

   Foo.remoteMethod
   (  
      "getXml",
      {
         accepts: [            
            {arg: 'id', type: 'string', required: true }
         ],
         http: {path: '/:id/content', "verb": 'get'},
         returns: {"type": "string", root:true},
         rest: {"after": setContentType("text/xml") }         
      }
   )

响应始终返回转义的JSON字符串:

"<foo xmlns=\"bar\"/>" 

而不是

<foo xmlns="bar"/>

请注意,响应的内容类型设置为text / xml。

如果我将Accept:标题设置为“text / xml”,我总是将“Not Acceptable”作为回复。

如果我设置

"rest": {
  "normalizeHttpPath": false,
  "xml": true
}

在config.json中,我收到500错误:

SyntaxError: Unexpected token <

我认为“xml:true”属性只是导致响应解析器尝试将JSON转换为XML。

如何在不解析响应的情况下让Loopback返回响应中的XML?问题是我将返回类型设置为“string”?如果是这样,Loopback会识别为XML的类型是什么?

2 个答案:

答案 0 :(得分:5)

您需要在响应对象中设置为XML(稍后会详细介绍)。首先,将返回类型设置为'object',如下所示:

Foo.remoteMethod
(  
  "getXml",
  {
     accepts: [            
        {arg: 'id', type: 'string', required: true }
     ],
     http: {path: '/:id/content', "verb": 'get'},
     returns: {"type": "object", root:true},
     rest: {"after": setContentType("text/xml") }         
  }
)

接下来,您将需要返回一个带有toXML的JSON对象作为唯一属性。 toXML应该是一个返回XML的字符串表示的函数。如果将Accept标头设置为“text / xml”,则响应应为XML。见下文:

Foo.getXml = function(cb) {
  cb(null, {
    toXML: function() {
      return '<something></something>';
    }
  });
};

您仍然需要在config.json中启用XML,因为它默认情况下已禁用:

"remoting": {
  "rest": {
    "normalizeHttpPath": false,
    "xml": true
  }
}

有关如何在幕后工作的详细信息,请参阅https://github.com/strongloop/strong-remoting/blob/4b74a612d3c969d15e3dcc4a6d978aa0514cd9e6/lib/http-context.js#L393

答案 1 :(得分:0)

我最近在尝试为Loopback 3.x中的Twilio语音呼叫创建动态响应时遇到了这种情况。在model.remoteMethod调用中,明确指定返回类型和内容类型,如下所示:

model.remoteMethod(
    "voiceResponse", {
        accepts: [{
            arg: 'envelopeId',
            type: 'number',
            required: true
        }],
        http: {
            path: '/speak/:envelopeId',
            "verb": 'post'
        },
        returns: [{
            arg: 'body',
            type: 'file',
            root: true
        }, {
            arg: 'Content-Type',
            type: 'string',
            http: {
                target: 'header'
            }
        }],

    }
)

让您的方法通过回调函数返回xml和内容类型。请注意,如果存在回调,则回调中的第一个参数将返回错误:

model.voiceResponse = function(messageEnvelopeId, callback) {

    app.models.messageEnvelope.findById(messageEnvelopeId, {
        include: ['messages']
    }).then(function(res) {
        let voiceResponse = new VoiceResponse();
        voiceResponse.say({
                voice: 'woman',
                language: 'en'
            },
            "This is a notification alert from your grow system. " + res.toJSON().messages.message
        )

        callback(null,
            voiceResponse.toString(), // returns xml document as a string
            'text/xml'
        );
    });
}