首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >HTTP状态码的处理

HTTP状态码的处理
EN

Stack Overflow用户
提问于 2022-05-18 09:19:08
回答 2查看 61关注 0票数 1

我正在Orbeon2021.1.2PE中创建表单,并且在处理错误调用时遇到了问题。我正在通过表单生成器创建HTTP服务和操作。我希望能解决这个问题,并能和Builder呆在一起。我将API称为类似于Twitter的API,因此它还会返回用于业务错误的Error状态代码(请参见Doc.HTTP和https://developer.twitter.com/ja/docs/basics/response-codes )。最简单的例子是:如果我试图在数据库中找到一个如果不在数据库中的东西,我会得到代码404,在响应体中有一个详细的错误。

我需要一个状态代码+完整的正文(标题也会很好)到表单。我不想使用模式窗口(在Orbeon中是默认的)来处理这个调用。它干扰用户+调用经常更改整个工作流(可见的内容,等等)。有些调用甚至是异步的。

在Orbeon,解决这个问题的最佳方法是什么?我试了几样东西,在几个地方找了块东西。

(1)通过属性oxf.fr.detail.process.action-service-error.*.*解决

这里是设置默认错误模式窗口。我删除了它,发现我可以获得一些值并将它们写在表单中,例如:

代码语言:javascript
复制
xf:setvalue(ref="//control-1", value="event('response-status-code')")

具体来说,这些价值观是:

代码语言:javascript
复制
event('error-type')
event('response-status-code')
event('resource-uri')
event('response-headers') - get specific via event('response-headers')[lower-case(name) = 'content-lenght']/value 
event('response-body') - This not working, it is still supported?

因为它是一个全局配置,所以我开始在哪里放置这些值。我试图创建自己的实例,但最终得到了fr:insert()函数。

我想为每个提交创建一个新实例,然后输入单独的值(event ('response-status-code'),.)。但是,使用fr:insert()的进程不起作用,而且文档中有糟糕的示例(https://doc.orbeon.com/form-runner/advanced/buttons-and-processes/actions-xforms#xf-insert)。

这做我想做的,但在形式上:

代码语言:javascript
复制
<xf:insert context="xxf:instance('HTTP-ERROR-RESULT')" ref="responses" origin="xxf:instance('HTTP-ERROR-TEMPLATE')"/>

我试着把它转换成进程,但没有运气:

代码语言:javascript
复制
xf:insert(into="xxf:instance('HTTP-ERROR-RESULT')/reponses", origin="xxf:instance('HTTP-ERROR-TEMPLATE')")

如果这是正确的方法?如何修复xf:insert()中的语义错误以及如何获得响应体(event ('response-body')不工作.)?并且是在过程中获取提交或操作名称的某种方法(例如,我需要一些id来查找)。

2]我尝试过的另一种方法是通过xforms-submit-error在submit中提交,但它也不起作用。在构建者创建的结构下:

代码语言:javascript
复制
        <xf:action event="xforms-submit-done" ev:observer="echo-submission">
            <xf:action class="fr-set-control-value-action">
                <xf:var name="control-name" value="'control-2'"/>
                <xf:var name="control-value" value="/*"/>
            </xf:action>
        </xf:action>

我试着插入类似的东西,但是用xforms-submit-error

代码语言:javascript
复制
        <xf:action event="xforms-submit-error" ev:observer="echo-submission">
            <xf:action class="fr-set-control-value-action">
                <xf:var name="control-name" value="'control-2'"/>
                <xf:var name="control-value" value="/*"/>
            </xf:action>
        </xf:action>

我发现在提交中使用class="fr-service"时,我无法捕获xforms-submit-error。因此,在构建器之外编写整个提交并使用xforms-submit-error是正确的解决方案。

或者,在Orbeon还有另一个优雅的解决方案吗?谢谢您的回复!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-05-18 18:50:40

编写自己的XForms将为您提供最大的灵活性。您可以直接将该XForms放在表单定义中,使用表单生成器中的Edit Source,也可以放在自定义模型中,它是服务器上磁盘上的文件,我建议您参阅文档

你似乎找到了所有的片段(你做了一些很好的研究!),但这是一个总结。如果您有一个服务my-service,您可以侦听xforms-submit-error,并将事件属性值存储在您自己的实例中。如果使用自定义模型,该文件将具有以下内容,您还可以通过表单生成器中的Edit将<xf:model>的内容直接放在表单定义的<xf:model>中。在这里,逻辑只是将状态代码保存在实例my-error-instance中,然后使用<xf:message>来显示是否用于调试。

代码语言:javascript
复制
<xf:model xmlns:xf="http://www.w3.org/2002/xforms">

    <xf:instance id="my-error-instance">
        <_>
            <status-code/>
        </_>
    </xf:instance>

    <xf:action observer="my-service-submission" event="xforms-submit-error">
        <xf:setvalue
            ref="instance('my-error-instance')/status-code"
            value="event('response-status-code')"/>
        <xf:message value="instance('my-error-instance')/status-code"/>
    </xf:action>

</xf:model>

您还需要通过设置以下属性来禁用错误的默认对话框。

代码语言:javascript
复制
<property as="xs:string" name="oxf.fr.detail.process.action-service-error.*.*"/>

最后,我将表单定义的完整源代码放在下面,您可以使用my-service HTTP服务对http://httpbin.org/status/404进行测试,并调用表单加载,用于测试上述自定义模型逻辑。

代码语言:javascript
复制
<xh:html xmlns:xh="http://www.w3.org/1999/xhtml" xmlns:xf="http://www.w3.org/2002/xforms"
         xmlns:xs="http://www.w3.org/2001/XMLSchema"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns:ev="http://www.w3.org/2001/xml-events"
         xmlns:xi="http://www.w3.org/2001/XInclude"
         xmlns:xxi="http://orbeon.org/oxf/xml/xinclude"
         xmlns:xxf="http://orbeon.org/oxf/xml/xforms"
         xmlns:map="http://www.w3.org/2005/xpath-functions/map"
         xmlns:array="http://www.w3.org/2005/xpath-functions/array"
         xmlns:math="http://www.w3.org/2005/xpath-functions/math"
         xmlns:exf="http://www.exforms.org/exf/1-0"
         xmlns:fr="http://orbeon.org/oxf/xml/form-runner"
         xmlns:saxon="http://saxon.sf.net/"
         xmlns:sql="http://orbeon.org/oxf/xml/sql"
         xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"
         xmlns:fb="http://orbeon.org/oxf/xml/form-builder">
    <xh:head>
        <xh:title>Calling service returning a 404 on form load</xh:title>
        <xf:model id="fr-form-model" xxf:expose-xpath-types="true" xxf:analysis.calculate="true">

            <!-- Main instance -->
            <xf:instance id="fr-form-instance" xxf:exclude-result-prefixes="#all" xxf:index="id">
                <form>
                    <section-1>
                        <grid-1>
                            <control-1/>
                        </grid-1>
                        
                    </section-1>
                </form>
            </xf:instance>

            <!-- Bindings -->
            <xf:bind id="fr-form-binds" ref="instance('fr-form-instance')">
                <xf:bind id="section-1-bind" name="section-1" ref="section-1">
                    <xf:bind id="grid-1-bind" ref="grid-1" name="grid-1">
                        <xf:bind id="control-1-bind" name="control-1" ref="control-1" xxf:whitespace="trim"/>
                    </xf:bind>
                    
                </xf:bind>
            </xf:bind>

            <!-- Metadata -->
            <xf:instance id="fr-form-metadata" xxf:readonly="true" xxf:exclude-result-prefixes="#all">
                <metadata>
                    <application-name>a</application-name>
                    <form-name>a</form-name>
                    <title xml:lang="en">Calling service returning a 404 on form load</title>
                    <description xml:lang="en"/>
                    <created-with-version>2021.1-SNAPSHOT PE</created-with-version>
                    <library-versions>
                        <app>4</app>
                    </library-versions>
                </metadata>
            </xf:instance>

            <!-- Attachments -->
            <xf:instance id="fr-form-attachments" xxf:exclude-result-prefixes="#all">
                <attachments/>
            </xf:instance>

            <!-- All form resources -->
            <xf:instance xxf:readonly="true" id="fr-form-resources" xxf:exclude-result-prefixes="#all">
                <resources>
                    <resource xml:lang="en">
                        <section-1>
                            <label>Untitled Section</label>
                        </section-1>
                        <control-1>
                            <label/>
                            <hint/>
                            <alert/>
                        </control-1>
                    </resource>
                </resources>
            </xf:instance>

            <xf:instance id="my-service-instance" class="fr-service" xxf:exclude-result-prefixes="#all">
                        <body xmlns:xxbl="http://orbeon.org/oxf/xml/xbl"
                      xmlns:fbf="java:org.orbeon.oxf.fb.FormBuilderXPathApi">&lt;params/&gt;</body>
                    </xf:instance>
            <xf:submission id="my-service-submission" class="fr-service"
                           resource="http://httpbin.org/status/404"
                           method="get"
                           serialization="none"
                           mediatype=""/>
            <xf:action id="my-action-binding">
                <xf:action event="fr-run-form-load-action-after-controls" ev:observer="fr-form-model"
                           if="true()">
                    <xf:send submission="my-service-submission"/>
                </xf:action>
                <xf:action event="xforms-submit" ev:observer="my-service-submission">
                    <xf:var name="request-instance-name" value="'my-service-instance'"/>
                    <xf:action/>
                </xf:action>
                <xf:action event="xforms-submit-done" ev:observer="my-service-submission"/>
            </xf:action>
        </xf:model>
    </xh:head>
    <xh:body>
        <fr:view>
            <fr:body xmlns:p="http://www.orbeon.com/oxf/pipeline" xmlns:xbl="http://www.w3.org/ns/xbl"
                     xmlns:oxf="http://www.orbeon.com/oxf/processors">
                <fr:section id="section-1-section" bind="section-1-bind">
                    <xf:label ref="$form-resources/section-1/label"/>
                    <fr:grid id="grid-1-grid" bind="grid-1-bind">
                        <fr:c y="1" x="1" w="6">
                                <xf:input id="control-1-control" bind="control-1-bind">
                                    <xf:label ref="$form-resources/control-1/label"/>
                                    <xf:hint ref="$form-resources/control-1/hint"/>
                                    <xf:alert ref="$fr-resources/detail/labels/alert"/>
                                </xf:input>
                            </fr:c>
                        <fr:c y="1" x="7" w="6"/>
                    </fr:grid>
                </fr:section>
            </fr:body>
        </fr:view>
    </xh:body>
</xh:html>
票数 2
EN

Stack Overflow用户

发布于 2022-06-20 16:16:13

基于@avernet的答案,我为xforms-submit-error创建了通用处理程序。首先,如前所述,我通过设置此属性禁用默认对话框。

代码语言:javascript
复制
<property as="xs:string" name="oxf.fr.detail.process.action-service-error.*.*"/>

然后,我将自己的自定义模型放到WEB-INF/resources/forms/resources中。整个看起来是这样的:

代码语言:javascript
复制
<xf:model  xmlns:xf="http://www.w3.org/2002/xforms" id="my-model">
    <xf:instance id="my-error-instance">
        <reponseList>
        </reponseList>
    </xf:instance>

    <xf:instance id="my-error-template-instance">
        <submission name="">
            <status-code/>
            <uri/>
            <date/>
        </submission>
    </xf:instance>

    <xf:action observer="fr-form-model" event="xforms-submit-error">
        <xf:insert if="not(exists(xxf:instance('my-error-instance')//submission[@name=event('target')]))" context="xxf:instance('my-error-instance')" ref="reponseList" origin="xxf:instance('my-error-template-instance')"/>
        <xf:setvalue if="not(exists(xxf:instance('my-error-instance')//submission[@name=event('target')]))" ref="xxf:instance('my-error-instance')//submission[1]/@name" value="event('target')"/>
        <xf:setvalue ref="xxf:instance('my-error-instance')//submission[@name=event('target')]/status-code" value="event('response-status-code')"/>
        <xf:setvalue ref="xxf:instance('my-error-instance')//submission[@name=event('target')]/uri" value="event('resource-uri')"/>
        <xf:setvalue ref="instance('my-error-instance')//submission[@name=event('target')]/date" value="event('response-headers')[lower-case(name) = 'date']/value"/>
    </xf:action>
</xf:model>

注意两个条件(插入和第一个设置值)。因为它们,模型只保存一个提交的最后一个错误。如果出于某种原因,您可以删除它们。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/72286412

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档