麻烦发布数据作为JS角到Java REST Web服务表单数据 [英] Trouble in posting data as form data in Angular JS to Java REST web-service

查看:170
本文介绍了麻烦发布数据作为JS角到Java REST Web服务表单数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建的Java 接受两个列为 FORMDATA 参数的Web服务。

我已经使用了Angualr JS HTTP 服务作为<一提到href=\"http://stackoverflow.com/questions/11442632/how-can-i-post-data-as-form-data-instead-of-a-request-payload/11443066#11443066\">this回答。

  VAR queryRequest = $ HTTP({
    方法:POST,
    网址:服务/测试/ testPath',
    数据:$参数({listA的:myList1,数组listB:myList2}),
    标题:{内容类型:应用程序/ x-WWW的形式urlen codeD;字符集= UTF-8'}
});

我的对象 myList1

  VAR myList1 = [];
变种物镜= {};
OBJ [VAL1] = 1
OBJ [val2的] = 2
myList1.push(OBJ);

我的对象 myList2

  VAR myList2 = [];变种物镜= {};
OBJ [VAl11难] = 3
OBJ [val12] = 4
myList2.push(OBJ);变种物镜= {};
OBJ [VAl11难] = 5
OBJ [val12] = 6
myList2.push(OBJ);

我使用 javax.ws.rs。* 为休息服务

和我的Java服务器端点,它接受的数据,是AS-

  @Path(testPath)
@POST
@Consumes(应用程序/ x-WWW的形式urlen codeD;字符集= UTF-8)
@Produces(应用/ JSON)
公共DataDTO addIssuancesForFP(@FormParam(为listA)列表&LT;&类型A GT; list1的,@FormParam(数组listB)列表&LT;&的TypeB GT;列表2){    的System.out.println(服务正确调用);
    返回service.getDTO(list1的,列表2);
}

我CLASSE类型A

 私人整数VAL1;
 私人整数val2的;
 // getter和setter方法​​,以及默认的构造函数

我CLASSE的TypeB

 私人整数VAl11难;
 私人整数val12;
 // getter和setter方法​​,以及默认的构造函数

端点被正确地打,但我在这两个列表中获得。请求结构是:


  

请求类型


 接受:应用/ JSON,纯文本/ * / *
    内容类型:应用程序/ x-WWW的形式urlen codeD;字符集= UTF-8


  

表单数据


 为listA [0] [VAL1]:1
    listA的[0] [val2的]:2    数组listB [0] [VAl11难]:3
    数组listB [0] [val12]:4
    数组listB [1] [VAl11难]:5
    数组listB [1] [val12]:6

这似乎是正确的,我认为错误是在服务器的一部分。如何解决此问题?

感谢

注意:这只是模拟数据,这是完全一样的格式


解决方案

呀,所以我不认为使用形式连接codeD数据是去工作。的原因是,它主要是为关键值对的形式

 键1 = value7&放大器;键2 =值&安培; KEY3 =值3 ...

您只使用两个密钥,做什么为listA 数组listB 。所以,想象一下值,需要的样子,将整个清单。它不是pretty。为复杂的数据时,它是更可行的像的JSON格式发送数据。与此对特定的用例的问题在于,有两个不相关的对象(或阵列),以需要发。对于这一点,一个解决方案是使用多部分。你很幸运,因为我只是一个晚答案昨日公布,对究竟如何这可以用角处理。

我将无法通过解释去这里了解code。一切都在那个链接解释。请阅读它,因为你通过这个答案。我将使用作为新泽西州可能JAX-RS实现(一样在链接的例子 - 但它也提供其他替代实现)

资源

 进口的java.util.List;
进口javax.ws.rs.Consumes;
进口javax.ws.rs.POST;
进口javax.ws.rs.Path;
进口javax.ws.rs.Produces;
进口org.glassfish.jersey.media.multipart.FormDataParam;@Path(/表)
公共类FormResource {    @POST
    @Consumes(多部分/表单数据)
    @Produces(text / plain的)
    公共字符串addIssuancesForFP(@FormDataParam(为listA)列表&LT;&类型A GT; list1的,
                                     @FormDataParam(数组listB)列表&LT;&的TypeB GT;列表2){        StringBuilder的响应=新的StringBuilder();
        对于(类型A一:list1的){
            response.append(a.toString())附加(;​​)。
        }        对于(的TypeB乙:列表2){
            。response.append(b.toString())附加(;​​);
        }        的System.out.println(服务正确调用);
        返回response.toString();
    }
}

 &LT;!DOCTYPE HTML&GT;
&LT; HTML NG-应用=formApp&GT;
    &LT; HEAD&GT;
        &LT;标题&GT; TODO提供标题&LT; /标题&GT;
        &LT;间的charset =UTF-8&GT;
        &LT; META NAME =视口CONTENT =WIDTH =设备宽度,初始规模= 1.0&GT;
        &LT;脚本SRC =JS /库/ jQuery的/ jquery.js和&GT;&LT; / SCRIPT&GT;
        &LT;脚本SRC =JS /库/ angular.js / angular.js&GT;&LT; / SCRIPT&GT;
        &LT;脚本&GT;
            angular.module(formApp,[])
            .controller(defaultCtrl功能($范围,$ HTTP){
                $ scope.sendData =功能(){
                    变种myList1 = [];
                    变种物镜= {};
                    OBJ [VAL1] =值1;
                    OBJ [val2的] =值2;
                    myList1.push(OBJ);                    变种myList2 = [];                    变种物镜= {};
                    OBJ [VAl11难] =value11;
                    OBJ [val12] =value12;
                    myList2.push(OBJ);                    变种物镜= {};
                    OBJ [VAl11难] =value211;
                    OBJ [val12] =value212;
                    myList2.push(OBJ);                    VAR list1的= JSON.stringify(myList1);
                    VAR列表2 = JSON.stringify(myList2);                    。VAR边界=的Math.random()的toString()SUBSTR(2);
                    VAR标题=的multipart / form-data的;字符集= UTF-8;边界=+边界;                    $ HTTP({
                        网址:/ API /表,
                        标题:{内容类型:头},
                        数据:的createRequest(list1的,列表2,边界)
                        方法:POST
                    })。然后(功能(响应){
                        $ scope.result = response.data;
                    });                    功能的createRequest(list1的,列表2,边界){
                        变种的multipart =;
                        多部分+ = - +边界
                            +\\ r \\ nContent处置:表格数据;名称=为listA
                            +\\ r \\ nContent类型:应用程序/ JSON
                            +\\ r \\ n \\ r \\ n+ list1的+\\ r \\ n;
                        多部分+ = - +边界
                            +\\ r \\ nContent处置:表格数据;名称=数组listB
                            +\\ r \\ nContent类型:应用程序/ JSON
                            +\\ r \\ n \\ r \\ n+列表2 +\\ r \\ n;
                            多部分+ = - +边界+ - \\ r \\ n;
                        返回多部分;
                    }
                };
             });
        &LT; / SCRIPT&GT;
    &LT; /头&GT;
    &LT;身体GT;
        &LT; D​​IV NG控制器=defaultCtrl&GT;
            &LT;按钮NG点击=送出数据()&GT;发送和LT; /按钮&GT;
            &所述p为H.; {{结果}}
        &LT; / DIV&GT;
    &LT; /身体GT;
&LT; / HTML&GT;

结果

 类型A {VAL1 =值,将val2 =值2};
{的TypeB VAL1 = value11,将val2 = value12};
{的TypeB VAL1 = value211,将val2 = value212};

这是意料之中的,因为我刚刚建立从的toString一个字符串()方法,这是我在类型A 的TypeB 类。

 公共类类型A {
    公共字符串VAL1;
    公共字符串val2的;
    @覆盖
    公共字符串的toString(){
        回归类型A {+VAL1 =+ VAL1 +,将val2 =+ val2的+'};
    }
}公共类的TypeB {
    公共字符串VAl11难;
    公共字符串val12;
    @覆盖
    公共字符串的toString(){
        回归的TypeB {+VAL1 =+ VAl11难+,将val2 =+ val12 +'};
    }
}

希望这有助于。

I am trying to create a web service in Java that accepts two lists as FormData parameter.

I have used the Angualr JS http service as mentioned in this answer.

var queryRequest = $http({
    method:'POST',
    url:'services/test/testPath',
    data:$.param({"listA":myList1,"listB":myList2}),
    headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'}
});

My object myList1

var myList1=[];
var obj={};
obj["val1"]=1
obj["val2"]=2
myList1.push(obj);

My object myList2

var myList2=[];

var obj={};
obj["val11"]=3
obj["val12"]=4
myList2.push(obj);

var obj={};
obj["val11"]=5
obj["val12"]=6
myList2.push(obj);

I am using javax.ws.rs.* for the rest service

And my Java server endpoint, which accepts the data, is as-

@Path("testPath")
@POST
@Consumes("application/x-www-form-urlencoded;charset=UTF-8")
@Produces("application/json")
public DataDTO addIssuancesForFP(@FormParam("listA") List<TypeA> list1, @FormParam("listB") List<TypeB> list2) {

    System.out.println("Service is called correctly");
    return service.getDTO(list1,list2);
}

My classe 'TypeA'

 private Integer val1;
 private Integer val2;
 //getters and setters, and default constructor

My classe 'TypeB'

 private Integer val11;
 private Integer val12;
 //getters and setters, and default constructor

Endpoint is hitting correctly, but I am getting null in both the list. The request structure is:

Request Type

    Accept:application/json, text/plain, */*
    Content-Type:application/x-www-form-urlencoded;charset=UTF-8

Form Data

    listA[0][val1]:1
    listA[0][val2]:2

    listB[0][val11]:3
    listB[0][val12]:4
    listB[1][val11]:5
    listB[1][val12]:6

It seems to be correct, I think mistake is in server part. How to resolve this?

Thanks

Note: This is just the mock data, which is in exact same format

解决方案

Yeah so I don't think using form encoded data is going to work. The reason is that it is mainly for key value pairs, in the form

key1=value7&key2=value2&key3=value3...

What you are doing is using only two keys, listA and listB. So imagine what the values would need to look like, to send the entire list. It isn't pretty. For complex data, it is more viable to send the data in a format like JSON. The problem with this for your particular use case is that there are two unrelated objects (or arrays) to needs to send. For this, a solution would be to use multipart. You're in luck, because I just posted a late answer yesterday, on exactly how this can be handled with Angular.

I won't go through an explanation here about the code. Everything is explained in that link. Please read through it, as you go through this answer. I will be using Jersey as may JAX-RS implementation (as does the example in the link - but it also offers other alternative implementations)

Resource

import java.util.List;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import org.glassfish.jersey.media.multipart.FormDataParam;

@Path("/form")
public class FormResource {

    @POST
    @Consumes("multipart/form-data")
    @Produces("text/plain")
    public String addIssuancesForFP(@FormDataParam("listA") List<TypeA> list1, 
                                     @FormDataParam("listB") List<TypeB> list2) {

        StringBuilder response = new StringBuilder();
        for(TypeA a: list1) {
            response.append(a.toString()).append("; ");
        }

        for (TypeB b: list2) {
            response.append(b.toString()).append("; ");
        }

        System.out.println("Service is called correctly");
        return response.toString();
    }
}

Angular

<!DOCTYPE html>
<html ng-app="formApp">
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <script src="js/libs/jquery/jquery.js"></script>
        <script src="js/libs/angular.js/angular.js"></script>
        <script>
            angular.module("formApp", [])
            .controller("defaultCtrl", function($scope, $http) {
                $scope.sendData = function() {
                    var myList1 = [];
                    var obj = {};
                    obj["val1"] = "value1";
                    obj["val2"] = "value2";
                    myList1.push(obj);

                    var myList2 = [];

                    var obj = {};
                    obj["val11"] = "value11";
                    obj["val12"] = "value12";
                    myList2.push(obj);

                    var obj = {};
                    obj["val11"] = "value211";
                    obj["val12"] = "value212";
                    myList2.push(obj);

                    var list1 = JSON.stringify(myList1);
                    var list2 = JSON.stringify(myList2);

                    var boundary = Math.random().toString().substr(2);
                    var header = "multipart/form-data; charset=utf-8; boundary=" + boundary;

                    $http({
                        url: "/api/form",
                        headers: {"Content-Type": header},
                        data: createRequest(list1, list2, boundary),
                        method: "POST"
                    }).then(function(response) {
                        $scope.result = response.data;
                    });

                    function createRequest(list1, list2, boundary) {
                        var multipart = "";
                        multipart += "--" + boundary
                            + "\r\nContent-Disposition: form-data; name=listA"
                            + "\r\nContent-type: application/json"
                            + "\r\n\r\n" + list1 + "\r\n";
                        multipart += "--" + boundary
                            + "\r\nContent-Disposition: form-data; name=listB"
                            + "\r\nContent-type: application/json"
                            + "\r\n\r\n" + list2 + "\r\n";
                            multipart += "--" + boundary + "--\r\n";
                        return multipart;
                    }
                };
             });
        </script>
    </head>
    <body>
        <div ng-controller="defaultCtrl">
            <button ng-click="sendData()">Send</button>
            <p>{{result}}
        </div>
    </body>
</html>

Result

TypeA{val1=value1, val2=value2}; 
TypeB{val1=value11, val2=value12}; 
TypeB{val1=value211, val2=value212};

Which is expected, as I just built a string from the toString() methods, which I implemented in the TypeA and TypeB classes.

public class TypeA {
    public String val1;
    public String val2;
    @Override
    public String toString() {
        return "TypeA{" + "val1=" + val1 + ", val2=" + val2 + '}';
    }
}

public class TypeB {
    public String val11;
    public String val12;
    @Override
    public String toString() {
        return "TypeB{" + "val1=" + val11 + ", val2=" + val12 + '}';
    } 
}

Hope this helps.

这篇关于麻烦发布数据作为JS角到Java REST Web服务表单数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆