在Angular JS中将数据作为表单数据发布到Java REST web服务时遇到问题
我试图在在Angular JS中将数据作为表单数据发布到Java REST web服务时遇到问题,java,angularjs,http-post,jax-rs,Java,Angularjs,Http Post,Jax Rs,我试图在Java中创建一个web服务,它接受两个列表作为FormData参数 我使用了中提到的Angualr JShttp服务 我的对象myList1 var myList1=[]; var obj={}; obj["val1"]=1 obj["val2"]=2 myList1.push(obj); 我的对象myList2 var myList2=[]; var obj={}; obj["val11"]=3 obj["val12"]=4 myList2.push(obj); var obj
Java
中创建一个web服务,它接受两个列表作为FormData
参数
我使用了中提到的Angualr JShttp
服务
我的对象myList1
var myList1=[];
var obj={};
obj["val1"]=1
obj["val2"]=2
myList1.push(obj);
我的对象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);
我将javax.ws.rs.*
用于rest服务
我的Java服务器端点(接受数据)如下所示:
@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);
}
我的班级“B型”
private Integer val11;
private Integer val12;
//getters and setters, and default constructor
端点命中正确,但我在两个列表中都得到了null
。请求结构是:
请求类型
表单数据
这似乎是正确的,我认为错误在服务器部分。如何解决这个问题
谢谢
注意:这只是模拟数据,格式完全相同是的,所以我认为使用表单编码数据是行不通的。原因是它主要用于键值对,形式为
key1=value7&key2=value2&key3=value3...
您只需使用两个键,listA
和listB
。想象一下,要发送整个列表,这些值应该是什么样子。它不漂亮。对于复杂数据,以JSON格式发送数据更可行。对于您的特定用例来说,这个问题在于有两个不相关的对象(或数组)需要发送。为此,解决方案是使用多部分。你很幸运,因为我昨天刚刚发布了一篇文章,关于如何使用Angular处理这个问题
我不会在这里解释代码。所有内容都在该链接中解释。在你回答这个问题时,请通读一遍。我将使用Jersey as may JAX-RS实现(链接中的示例也是如此,但它也提供了其他替代实现)
资源
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();
}
}
这是预期的,因为我刚刚从toString()
方法构建了一个字符串,我在TypeA
和TypeB
类中实现了这个字符串
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 + '}';
}
}
希望这有帮助。表单数据或来自数据???@roxid更改为
表单数据
,[val1]
等Javascript对象的属性?这就是数据实际发送的方式,即listA[0][val1]=value1
?能否显示myList1
和myList2
的实际Javascript对象。还可以显示TypeA
和TypeB
类。好的,我现在就去查看。我没有看到您的完整更新。它显示了我认为可用的对象。我只是想看看实际的请求,看看数据是如何被发送的。我也尝试过这样做,但我得到的结果是找不到媒体错误的边界
,这个边界是用来做什么的?它是规范的一部分。很可能您没有正确发送请求,可能是允许浏览器创建请求。即使您使用中建议的FormData
将内容类型设置为false/undefined,数据仍将以纯文本形式发送,您仍需要在服务器端对其进行解析。使用JSON方法,您可以让框架解析它。在上面的解决方案中,我们自己创建了请求主体,而且我没有您从org.glassfish.jersey.media.multipart.FormDataParam导入的@FormDataParam
注释代码>我使用的是javax.ws.rs.FormParam代码>。在SpringWeb中是否有其他替代方案。我也在使用这个org.springframework.web.bind.annotation.RequestBody
你在使用Jersey吗?如果是这样,请转到链接,它将具有您需要添加的Maven依赖项。然后您还需要注册该功能。该链接显示该功能的Java配置。如果您使用的是web.xml,那么可以为jersey servletjersey.config.server.provider.classnames
-value-org.glassfish.jersey.media.multipart.MultiPartFeature
设置init参数,我没有使用jersey
,我使用的是javax.ws.rs
API,还有Spring。例如,RequestBody
是Spring注释,QueryParam
是javax
注释FormDataParam
不存在。我怎样才能补充呢
listA[0][val1]:1
listA[0][val2]:2
listB[0][val11]:3
listB[0][val12]:4
listB[1][val11]:5
listB[1][val12]:6
key1=value7&key2=value2&key3=value3...
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();
}
}
<!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>
TypeA{val1=value1, val2=value2};
TypeB{val1=value11, val2=value12};
TypeB{val1=value211, val2=value212};
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 + '}';
}
}