麻烦发布数据作为JS角到Java REST Web服务表单数据 [英] Trouble in posting data as form data in Angular JS to Java REST web-service
问题描述
我试图创建的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; DIV 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 $ C $实施C>和
的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 asFormData
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 serviceAnd 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
andlistB
. 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 theTypeA
andTypeB
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屋!