使用JQuery和Java在Play框架中构建Autosave函数,但遇到400错误请求或404未找到错误

使用JQuery和Java在Play框架中构建Autosave函数,但遇到400错误请求或404未找到错误,java,jquery,json,playframework,url-encoding,Java,Jquery,Json,Playframework,Url Encoding,我正在使用模型中的JQuery在我的Play应用程序中构建自动保存功能,并在控制器中处理请求 我最初发布(帖子1)如下: 但这被标记为可能的重复(帖子2): 我在我原来的帖子(帖子1)上没有收到任何答案,所以我被要求重新发布我的问题 我遵循Post 2,删除了我传递的参数,因为根据Post 2,我的请求可能存在问题。第2篇文章中引用的文档是Scala(对于Play的旧版本,我使用的是2.5),而我的应用程序是Java,所以它并没有真正帮助我。我在播放文档中发现了这一点: 我阅读并遵循该文档

我正在使用模型中的JQuery在我的Play应用程序中构建自动保存功能,并在控制器中处理请求

我最初发布(帖子1)如下:

但这被标记为可能的重复(帖子2):

我在我原来的帖子(帖子1)上没有收到任何答案,所以我被要求重新发布我的问题

我遵循Post 2,删除了我传递的参数,因为根据Post 2,我的请求可能存在问题。第2篇文章中引用的文档是Scala(对于Play的旧版本,我使用的是2.5),而我的应用程序是Java,所以它并没有真正帮助我。我在播放文档中发现了这一点:

我阅读并遵循该文档并更新了代码

但是,我仍然收到错误请求(400)或未找到(404)错误。我没有收到任何详细的信息,所以我不确定我在哪里犯了错误

以下是Chrome控制台中返回的内容:

addptp:414 POST http://localhost:9000/autosave 404 (Not Found)
send    @   jquery-3.2.1.min.js:4
ajax    @   jquery-3.2.1.min.js:4
(anonymous) @   addptp:414
each    @   jquery-3.2.1.min.js:2
each    @   jquery-3.2.1.min.js:2
autosave    @   addptp:413
(anonymous) @   addptp:185
以下是视图中的JQuery:

var timer;
var restURL = window.location.protocol + "//" + window.location.hostname + (window.location.port == "" ? "" : (":" + window.location.port));

$(document).ready(function() {
    // JSON REST Autosave...
    timer = setInterval(function() {
        autosave();
    }, 6000);
});

    function autosave() {
        alert("Autosave");
        $('form').each(function() {
            $.ajax({
                type: "POST",
                url: restURL + "/autosave",
                data: $(this).serialize(),
                dataType: "json",
                contentType: "application/x-www-form-urlencoded; charset=utf-8",
                success: function(data) {
                    alert("Success!");
                },
                error: function(data) {
                    alert("Error!");
                }
            });
        });
    }
以下是我的Java控制器代码:

@BodyParser.Of(BodyParser.FormUrlEncoded.class)
public Result restAutosaveAdultPTP() {
    // Let's get the current request in JSON and parse...
    Map<String, String[]> json = request().body().asFormUrlEncoded();
    if (json == null) {
        return badRequest("Expecting Json data");
    } else {
        return ok("json: " + json);
    }
}
这是请求和响应信息

概述:

Request URL:http://localhost:9000/autosave
Request Method:POST
Status Code:404 Not Found
Remote Address:[::1]:9000
Referrer Policy:no-referrer-when-downgrade
响应标题:

HTTP/1.1 404 Not Found
Content-Length: 26917
Content-Type: text/html; charset=utf-8
Date: Thu, 25 Jan 2018 18:34:15 GMT
请求标头:

POST /autosave HTTP/1.1
Host: localhost:9000
Connection: keep-alive
Content-Length: 2739
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:9000
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:9000/addptp
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: PLAY_SESSION=a37c3087c9d5d3f4129057c964ca9a90eef80fe5-SESSION_ID=kfs7q8vohk3ammlfcnfka0j1p9&email=dzeller44%40gmail.com&userTimeout=1516880046558
Accept: application/json, text/javascript, */*; q=0.01
有效载荷

legacy_Provider_Id=&new_Provider_Id=&provider_Name=&alternate_Name_DBA=&setting_Type=&waivers_Served=&total_Number_Served=&total_Number_on_Waivers=&street_Address=&apartment=&city=&state=&zip=&phone=&email1=&email2=&contact_Person=&updates=&main_PTP_Address=&duplicate_docs=&other_Rights_NonCompliance_Description=&other_Remedy_for_Rights_Description=&details_for_Rights_Action_Plan=&remedy_Rights_Incurred_Cost_Description=&remedy_Rights_One_Time_Costs=&remedy_Rights_Recurring_Annual_Costs=&person_for_Rights_Action_Plan=&status_Rights_Action_Plan=---+Select+Status+---&other_Choice_NonCompliance_Description=&other_Remedy_for_Choice_Description=&detail_for_Choice_Action_Plan=&remedy_Choice_Incurred_Cost_Description=&remedy_Choice_One_Time_Costs=&remedy_Choice_Recurring_Annual_Costs=&person_for_Choice_Action_Plan=&status_of_Choice_Action_Plan=---+Select+Status+---&other_Integration_NonCompliance_Description=&other_Remedy_for_Integration_Description=&detail_for_Integration_Action_Plan=&remedy_Integration_Incurred_Cost_Description=&remedy_Integration_One_Time_Costs=&remedy_Integration_Recurring_Annual_Costs=&person_for_Integration_Action_Plan=&status_for_Integration_Action_Plan=---+Select+Status+---&other_Remedy_for_Institutional_Factors_Description=&detail_for_Institutional_Action_Plan=&remedy_Institutional_Incurred_Cost_Description=&remedy_Institutional_One_Time_Costs=&remedy_Institutional_Recurring_Annual_Costs=&person_for_Institutional_Action_Plan=&status_of_Institutional_Action_Plan=---+Select+Status+---&ptp_Edited_Date=&ptp_Status_Notes=&update_Due=&compliance_Status=---+Select+Status+---&ensures_Rights=---+Select+Status+---&optimizes_Autonomy=---+Select+Status+---&selected_by_Person=---+Select+Status+---&options_in_PC_Plan=---+Select+Status+---&facilitates_Choice=---+Select+Status+---&integrated_in_Community=---+Select+Status+---&enforceable_Lease=---+Select+Status+---&eviction_Protections=---+Select+Status+---&bedroom_Privacy=---+Select+Status+---&bedroom_Locks=---+Select+Status+---&choice_of_Roommates=---+Select+Status+---&freedom_to_Decorate=---+Select+Status+---&free_Schedule_Access_to_Food=---+Select+Status+---&visitors_any_Time=---+Select+Status+---&physically_Accessible=---+Select+Status+---&modifications_PC_Plan=---+Select+Status+---&setting_NonInstitutional=---+Select+Status+---&heightened_Scrutiny_Description=&cdphe_Lead=&site_Visit_Status=---+Select+Status+---&site_Visit_Date=&site_Visit_Team=&documents_Detail=&findings_from_Documents=&summary_of_Findings=&promising_Practices=&additional_Notes=&follow_up_Visit_Status=---+Select+Status+---&additional_Notes_2=&follow_up_Date=&follow_up_Team=&documents_Detail_2=&findings_from_Documents_2=&summary_of_Findings_2=&promising_Practices_2=
如下面的注释所述,为什么它要查找json而不是请求头中编码的表单url:

POST /autosave HTTP/1.1
Host: localhost:9000
Connection: keep-alive
Content-Length: 2739
Accept: application/json, text/javascript, */*; q=0.01
Origin: http://localhost:9000
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36
Content-Type: application/x-www-form-urlencoded; charset=UTF-8
Referer: http://localhost:9000/addptp
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Cookie: PLAY_SESSION=a37c3087c9d5d3f4129057c964ca9a90eef80fe5-SESSION_ID=kfs7q8vohk3ammlfcnfka0j1p9&email=dzeller44%40gmail.com&userTimeout=1516880046558
Accept: application/json, text/javascript, */*; q=0.01

我非常感谢您提供的任何指导或帮助。

问题是,
$(this).serialize()
使用URL编码符号对数据进行编码,但控制器中的
@BodyParser.Of(BodyParser.Json.class)
注释和
请求().body().asJson()
代码表明您需要Json编码

序列化的文档

.serialize()
方法以标准URL编码表示法创建文本字符串

与使用JSON的
serialize
方法不同,您可能希望使用类似JavaScript的
stringify

stringify()方法将JavaScript值转换为JSON字符串

或者,您可以更改播放代码以期望URL编码的值。请参见此处有关
FormUrlEncoded
的文档:

:将主体解析为表单


如果您更改播放行为,请记住也要更改您发送的
contentType
,因此它是
application/x-www-form-urlencoded
而不是
application/json

您能提供发送和接收的完整请求和响应(标题+正文)吗?我的直觉是,
$(this).serialize()
没有生成有效的JSON,但我需要查看请求正文来确认这一点,并且我希望能够查看响应正文,以了解行
是否为badRequest(“预期JSON数据”)
正在访问。@RichDougherty-我更新了我的帖子,包括请求和响应标题以及正文信息。如果您还需要什么,请告诉我。谢谢你的帮助!我将
serialize()
更改为这个
数据:JSON.stringify($(this.serializeArray())
,现在收到了一个
400未找到
错误。你有没有关于如何字符串化表单的例子?我也试图更改BodyParser,但得到了相同的错误-400未找到。我更改为
@BodyParser.Of(BodyParser.FormUrlEncoded.class)
并将JQuery设置回
数据:$(this).serialize()
,并将内容类型更改为
应用程序/x-www-form-urlencoded
。我猜我遗漏了什么…你能显示新的请求/响应标题和正文吗?仅供参考如果你改为使用URL编码的正文,你就不能使用
request().body().asJson()
。我将我的控制器函数改为
Map json=request().body().asFormUrlEncoded()但仍然获取400未找到错误。新的标题和正文在我上面的主要帖子中发布。