Trouble in posting data as form data in Angular JS to Java REST web-service

馋奶兔 提交于 2019-12-11 02:23:56

问题


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


回答1:


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.



来源:https://stackoverflow.com/questions/29297197/trouble-in-posting-data-as-form-data-in-angular-js-to-java-rest-web-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!