【问题标题】:how to correctly render a response on an gsp from on the same page as the request (REST call) in grails如何从与 grails 中的请求(REST 调用)相同的页面上正确呈现 gsp 上的响应
【发布时间】:2017-03-17 09:17:45
【问题描述】:

我是 grails 和 groovy 的新手。 我试图找出如何在相同的 gsp 中呈现来自 grails 控制器中的操作的响应 - 但在 gsp 的不同部分 - 作为接受请求的 gsp(在本例中为 web 表单 gsp 页面)?

欢迎任何链接或教程或直接“这样做”的回复。

========= background with my code attempt) =========

这是我正在使用的代码。这是一个 Grails 应用程序,我在其中使用引导模板(当然可以在 Internet 上免费获得)。

现在功能的实际代码本身可以工作。我遇到的问题是:

我有一个使用 css 模板和另一个 gsp 模板进行布局的 gsp 页面(这是来自引导程序主题)。我可以在我的 gsp 页面中使用此代码 (sn-p) 以 gsp+css 模板启动页面:

<g:layoutBody/>

这允许我在这个 gsp 文件中调用我的调用控制器代码来请求:

<body>
<g:form name="form" controller="apiStart" id="form">
    <div><g:select name="protocolType" value="restCall" from="${["-select-", "GET", "POST", "PUT", "DELETE"]}"/> &nbsp <label>URL: </label><g:textField name="url" value="${url}" />
    &nbsp <label>username: </label><g:textField name="userName" value="${userName}" />  &nbsp <label>password: </label><g:textField name="passWord" value="${passWord}" /></div>

    %{--<div class="text-field"><label>URL: </label><g:textField name="url" value="${url}" /></div>--}%
    %{--<div class="text-field"><label>username: </label><g:textField name="userName" value="${userName}" /></div>
    <div class="text-field"><label>password: </label><g:textField name="passWord" value="${passWord}" /></div>--}%
    <br>
    <div><label>Use Advanced Parameters?</label><g:checkBox name="useAdvParms" value="${false}" /></div>
    <div class="text-field"><label>Header1: </label><g:textField name="header1" value="${header1}" /> &nbsp <label>Value1: </label><g:textField name="value1" value="${header2}" /></div>
    %{--<div class="text-field"><label>Value1: </label><g:textField name="value1" value="${header2}" /></div>--}%
    <div class="text-field"><label>Header2: </label><g:textField name="header2" value="${header3}" /> &nbsp <label>Value2: </label><g:textField name="value2" value="${header4}" /></div>
    %{--<div class="text-field"><label>Value2: </label><g:textField name="value2" value="${header4}" /></div>--}%
    <br>
    <div class="submit"><g:actionSubmit value="Submit" action="save"/></div>
</g:form>
</body>

然后是响应的这个 gsp 代码:

<body>
<h3>API Test Results</h3>
API Tested: ${apiStart.url}, Response: ${apiStart.response3}
<br>
%{--<g:textArea name="myField" value="myValue" rows="20" cols="100"/>--}%
<div class="textarea"><label>Output</label><br><g:textArea name="myField" value="${apiStart.result3}"  />
</div>
%{--Responce Code: ${apiStart.response3}<br>--}%
%{--Response: <br> ${apiStart.result3} <br>--}%

</body>

我的问题是:它可以作为单独的页面正常工作我想在与调用请求相同的页面上呈现请求的结果。

在附加的屏幕截图中:我想将结果放在显示“输出显示在此处...”的文本框中

我认为 grails 中的模板是解决问题的方法;但是当我尝试将模板插入代码的那部分时,我得到了一个 Java Null 指针异常。

这里是模板 gsp 代码:

<div>
    API Tested: ${apiStart.url}, Response: ${apiStart.response3}
    <br>
    %{--<g:textArea name="myField" value="myValue" rows="20" cols="100"/>--}%
    <div class="textarea"><label>Output</label><br><g:textArea name="myField" value="${apiStart.result3}"  />
    </div>
    %{--Responce Code: ${apiStart.response3}<br>--}%
    %{--Response: <br> ${apiStart.result3} <br>--}%
</div>

======== 更新:添加控制器代码 =========== 控制器:

package hellograils

import org.springframework.http.HttpMethod
import org.springframework.web.client.RestTemplate

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;

import org.springframework.stereotype.Component;
import java.util.Base64;
import java.util.Map;

import static javax.xml.bind.DatatypeConverter.parseString;

class ApiStartController {

    def index() {

    }

    def save() {
        def apiStart = new ApiStart(params)
        apiStart.save()
        render (view: "apiStart", model: [apiStart: apiStart])

        System.out.println(apiStart.url);
        System.out.println(apiStart.passWord);
        System.out.println(apiStart.userName);

        RestTemplate restTemplate = new RestTemplate();

        System.out.println ("URI under Test is: " + String.valueOf(apiStart.url) + ". \n" + "Please stand by for results ... \n \n ");

        //String linkUT = apiStart.url;


//        apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getBody();
//        apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getStatusCode();



        if (apiStart.protocolType == "GET") {

            apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getBody();
            apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.GET, null, String.class).getStatusCode();
            render(view: "apiStart", model:[apiStart: apiStart])

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

        else if (apiStart.protocolType == "POST") {

            //apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, request, String.class).getBody();
            apiStart.result3 = restTemplate.execute(apiStart.url, HttpMethod.POST, null, String.class).getBody();
            apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, null, Map.class).getStatusCode();
//            apiStart.result3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, null, String.class).getBody();
//            apiStart.response3 = restTemplate.exchange(apiStart.url, HttpMethod.POST, null, String.class).getStatusCode();
            render(view: "apiStart", model:[apiStart: apiStart])

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

        else if (apiStart.protocolType == "PUT") {

            render(view: "apiStart", "coming soon ....")

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

        else if (apiStart.protocolType == "DELETE") {

            render(view: "apiStart", "coming soon ....")

            System.out.println(apiStart.protocolType);
            System.out.println(apiStart.result3);
            System.out.println(apiStart.response3);

        }

    }
}

=================== 控制器代码结束 ==================

这是域控制器代码:

================领域模型代码=========================

域名:

package hellograils

class ApiStart {

    String url
    String userName
    String passWord
    String result3
    String response3
    String header1
    String header2
    String value1
    String value2
    String protocolType

//    static constraints = {
//    }
}

======================= 域结束================

有人可以建议并告诉我最好的方法吗?

谢谢。

铁螳螂7x

【问题讨论】:

    标签: css twitter-bootstrap grails groovy


    【解决方案1】:

    在您的 gsp 中包含结果窗格,但使用 g:if 标记对其进行包装。提供一个标志变量,用于确定 grails 是否呈现该部分输出。

    <g:if test="${apiStart != null}"> 
      <div class="textarea">
        <label>Output</label><br>
        <g:textArea name="myField" value="${apiStart.result3}"  />
      </div>
    </g:if>
    

    在edit方法中,定义apiStart为:

    def apiStart = params.apiStart
    

    最初呈现编辑视图时,结果窗格不应出现。

    在 save 方法中,做任何你正在做的事情,定义 apiStart 映射,填充它,然后重定向到 edit 方法,传递 apiStart 作为参数。

    redirect(view:'edit', params:[apiStart:apiStart])
    

    或者类似的东西。还没有看到你的控制器代码...

    【讨论】:

    • 看起来像您的索引方法 == 我的编辑方法。无论哪种方法启动您尝试完成的工作流程。保存后,重定向到索引,但传入结果(apiStart)并填充结果。
    • 刚刚使页面空白。在输出文本区域中没有发布结果。
    • 调试会话告诉您发生了什么 - 空白页通常意味着 gsp 代码中的某些内容不太正确。我会在 index 方法中添加一个渲染调用,并确保将预期的数据传递给视图。
    • 是的,你是对的。让我澄清一下我的评论。我的意思是:当我按照你上面提到的那样做时,我仍然没有得到任何输出。在控制台中,我可以看到输出(我正在打印输出)。在我发出请求后,gsp 会成功呈现页面。只是没有显示rest调用的输出
    • 我想我可能无法正确理解您发布的解决方案。你能帮我看看这个吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多