Rectangle 27 82

Sending a simple form

Sending a POST request is easy in vanilla Java. Starting with a URL, we need t convert it to a URLConnection using url.openConnection();. After that, we need to cast it to a HttpURLConnection, so we can access its setRequestMethod() method to set our method. We finally say that we are going to send data over the connection.

URL url = new URL("https://www.example.com/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);

A normal POST coming from a http form has a well defined format. We need to convert our input to this format:

Map<String,String> arguments = new HashMap<>();
arguments.put("username", "root");
arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
    sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" 
         + URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;

We can then attach our form contents to the http request with proper headers and send it.

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

We can also send json using java, this is also easy:

byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
int length = out.length;

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

Sending files can be considered more challenging to handle as the format is more complex. We are also going to add support for sending the files as a string, since we don't want to buffer the file fully into the memory.

private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
    String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8") 
             + "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    byte[] buffer = new byte[2048];
    for (int n = 0; n >= 0; n = in.read(buffer))
        out.write(buffer, 0, n);
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

private void sendField(OutputStream out, String name, String field) {
    String o = "Content-Disposition: form-data; name=\"" 
             + URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

We can then use these methods to create a multipart post request as follows:

String boundary = UUID.randomUUID().toString();
byte[] boundaryBytes = 
           ("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
byte[] finishBoundaryBytes = 
           ("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
http.setRequestProperty("Content-Type", 
           "multipart/form-data; charset=UTF-8; boundary=" + boundary);

// Enable streaming mode with default settings
http.setChunkedStreamingMode(0); 

// Send our fields:
try(OutputStream out = http.getOutputStream()) {
    // Send our header (thx Algoman)
    out.write(boundaryBytes);

    // Send our first field
    sendField(out, "username", "root");

    // Send a seperator
    out.write(boundaryBytes);

    // Send our second field
    sendField(out, "password", "toor");

    // Send another seperator
    out.write(boundaryBytes);

    // Send our file
    try(InputStream file = new FileInputStream("test.txt")) {
        sendFile(out, "identification", file, "text.txt");
    }

    // Finish the request
    out.write(finishBoundaryBytes);
}


// Do something with http.getInputStream()

Nice answer Ferrybig. I like the spirit of giving so many angles on it.

This post is useful, but quite flawed. It took me 2 days to get it working. So to get it working you have to replace StandartCharsets.UTF8 with StandardCharsets.UTF_8 . boundaryBytes and finishBoundaryBytes need to get two additional hyphens which are NOT transmitted in the Content-Type, so boundaryBytes = ("--" + boundary + "\r\n").get... You also need to transmit the boundaryBytes once BEFORE the first field or the first field will be ignored!

out.write(finishBoundaryBytes);
http.connect();

Sending HTTP POST Request In Java - Stack Overflow

java http post
Rectangle 27 82

Sending a simple form

Sending a POST request is easy in vanilla Java. Starting with a URL, we need t convert it to a URLConnection using url.openConnection();. After that, we need to cast it to a HttpURLConnection, so we can access its setRequestMethod() method to set our method. We finally say that we are going to send data over the connection.

URL url = new URL("https://www.example.com/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);

A normal POST coming from a http form has a well defined format. We need to convert our input to this format:

Map<String,String> arguments = new HashMap<>();
arguments.put("username", "root");
arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
    sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" 
         + URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;

We can then attach our form contents to the http request with proper headers and send it.

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

We can also send json using java, this is also easy:

byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
int length = out.length;

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

Sending files can be considered more challenging to handle as the format is more complex. We are also going to add support for sending the files as a string, since we don't want to buffer the file fully into the memory.

private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
    String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8") 
             + "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    byte[] buffer = new byte[2048];
    for (int n = 0; n >= 0; n = in.read(buffer))
        out.write(buffer, 0, n);
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

private void sendField(OutputStream out, String name, String field) {
    String o = "Content-Disposition: form-data; name=\"" 
             + URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

We can then use these methods to create a multipart post request as follows:

String boundary = UUID.randomUUID().toString();
byte[] boundaryBytes = 
           ("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
byte[] finishBoundaryBytes = 
           ("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
http.setRequestProperty("Content-Type", 
           "multipart/form-data; charset=UTF-8; boundary=" + boundary);

// Enable streaming mode with default settings
http.setChunkedStreamingMode(0); 

// Send our fields:
try(OutputStream out = http.getOutputStream()) {
    // Send our header (thx Algoman)
    out.write(boundaryBytes);

    // Send our first field
    sendField(out, "username", "root");

    // Send a seperator
    out.write(boundaryBytes);

    // Send our second field
    sendField(out, "password", "toor");

    // Send another seperator
    out.write(boundaryBytes);

    // Send our file
    try(InputStream file = new FileInputStream("test.txt")) {
        sendFile(out, "identification", file, "text.txt");
    }

    // Finish the request
    out.write(finishBoundaryBytes);
}


// Do something with http.getInputStream()

Nice answer Ferrybig. I like the spirit of giving so many angles on it.

This post is useful, but quite flawed. It took me 2 days to get it working. So to get it working you have to replace StandartCharsets.UTF8 with StandardCharsets.UTF_8 . boundaryBytes and finishBoundaryBytes need to get two additional hyphens which are NOT transmitted in the Content-Type, so boundaryBytes = ("--" + boundary + "\r\n").get... You also need to transmit the boundaryBytes once BEFORE the first field or the first field will be ignored!

out.write(finishBoundaryBytes);
http.connect();

Sending HTTP POST Request In Java - Stack Overflow

java http post
Rectangle 27 78

Sending a simple form

Sending a POST request is easy in vanilla Java. Starting with a URL, we need t convert it to a URLConnection using url.openConnection();. After that, we need to cast it to a HttpURLConnection, so we can access its setRequestMethod() method to set our method. We finally say that we are going to send data over the connection.

URL url = new URL("https://www.example.com/login");
URLConnection con = url.openConnection();
HttpURLConnection http = (HttpURLConnection)con;
http.setRequestMethod("POST"); // PUT is another valid option
http.setDoOutput(true);

A normal POST coming from a http form has a well defined format. We need to convert our input to this format:

Map<String,String> arguments = new HashMap<>();
arguments.put("username", "root");
arguments.put("password", "sjh76HSn!"); // This is a fake password obviously
StringJoiner sj = new StringJoiner("&");
for(Map.Entry<String,String> entry : arguments.entrySet())
    sj.add(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" 
         + URLEncoder.encode(entry.getValue(), "UTF-8"));
byte[] out = sj.toString().getBytes(StandardCharsets.UTF_8);
int length = out.length;

We can then attach our form contents to the http request with proper headers and send it.

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

We can also send json using java, this is also easy:

byte[] out = "{\"username\":\"root\",\"password\":\"password\"}" .getBytes(StandardCharsets.UTF_8);
int length = out.length;

http.setFixedLengthStreamingMode(length);
http.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
http.connect();
try(OutputStream os = http.getOutputStream()) {
    os.write(out);
}
// Do something with http.getInputStream()

Sending files can be considered more challenging to handle as the format is more complex. We are also going to add support for sending the files as a string, since we don't want to buffer the file fully into the memory.

private void sendFile(OutputStream out, String name, InputStream in, String fileName) {
    String o = "Content-Disposition: form-data; name=\"" + URLEncoder.encode(name,"UTF-8") 
             + "\"; filename=\"" + URLEncoder.encode(filename,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    byte[] buffer = new byte[2048];
    for (int n = 0; n >= 0; n = in.read(buffer))
        out.write(buffer, 0, n);
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

private void sendField(OutputStream out, String name, String field) {
    String o = "Content-Disposition: form-data; name=\"" 
             + URLEncoder.encode(name,"UTF-8") + "\"\r\n\r\n";
    out.write(o.getBytes(StandardCharsets.UTF_8));
    out.write(URLEncoder.encode(field,"UTF-8").getBytes(StandardCharsets.UTF_8));
    out.write("\r\n".getBytes(StandardCharsets.UTF_8));
}

We can then use these methods to create a multipart post request as follows:

String boundary = UUID.randomUUID().toString();
byte[] boundaryBytes = 
           ("--" + boundary + "\r\n").getBytes(StandardCharsets.UTF_8);
byte[] finishBoundaryBytes = 
           ("--" + boundary + "--").getBytes(StandardCharsets.UTF_8);
http.setRequestProperty("Content-Type", 
           "multipart/form-data; charset=UTF-8; boundary=" + boundary);

// Enable streaming mode with default settings
http.setChunkedStreamingMode(0); 

// Send our fields:
try(OutputStream out = http.getOutputStream()) {
    // Send our header (thx Algoman)
    out.write(boundaryBytes);

    // Send our first field
    sendField(out, "username", "root");

    // Send a seperator
    out.write(boundaryBytes);

    // Send our second field
    sendField(out, "password", "toor");

    // Send another seperator
    out.write(boundaryBytes);

    // Send our file
    try(InputStream file = new FileInputStream("test.txt")) {
        sendFile(out, "identification", file, "text.txt");
    }

    // Finish the request
    out.write(finishBoundaryBytes);
}


// Do something with http.getInputStream()

Nice answer Ferrybig. I like the spirit of giving so many angles on it.

This post is useful, but quite flawed. It took me 2 days to get it working. So to get it working you have to replace StandartCharsets.UTF8 with StandardCharsets.UTF_8 . boundaryBytes and finishBoundaryBytes need to get two additional hyphens which are NOT transmitted in the Content-Type, so boundaryBytes = ("--" + boundary + "\r\n").get... You also need to transmit the boundaryBytes once BEFORE the first field or the first field will be ignored!

out.write(finishBoundaryBytes);
http.connect();

Sending HTTP POST Request In Java - Stack Overflow

java http post
Rectangle 27 4

Posting code that can send form data in post requests and works even on Java 7

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

    String host = mUri.getHost();

    urlConnection.setRequestMethod("POST"); // PUT is another valid option
    urlConnection.setDoOutput(true);
    Map<String,String> arguments = new HashMap<>();
    arguments.put("key1", "value");
    arguments.put("key2", "value");
    StringBuilder sj = new StringBuilder();
    for(Map.Entry<String,String> entry : arguments.entrySet()) {
        sj.append(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&");
    }
    byte[] out = sj.toString().getBytes();

    urlConnection.setFixedLengthStreamingMode(out.length);
    urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    urlConnection.connect();
    try
    {
        OutputStream os = urlConnection.getOutputStream();
        os.write(out);
    }
    catch (Exception e)
    {

    }
}
catch (Exception e) {...}

You get an extra "&" in the end.

What "mUri", what "host"? how do you read the response? this is useless.

Sending HTTP POST Request In Java - Stack Overflow

java http post
Rectangle 27 4

Posting code that can send form data in post requests and works even on Java 7

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

    String host = mUri.getHost();

    urlConnection.setRequestMethod("POST"); // PUT is another valid option
    urlConnection.setDoOutput(true);
    Map<String,String> arguments = new HashMap<>();
    arguments.put("key1", "value");
    arguments.put("key2", "value");
    StringBuilder sj = new StringBuilder();
    for(Map.Entry<String,String> entry : arguments.entrySet()) {
        sj.append(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&");
    }
    byte[] out = sj.toString().getBytes();

    urlConnection.setFixedLengthStreamingMode(out.length);
    urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    urlConnection.connect();
    try
    {
        OutputStream os = urlConnection.getOutputStream();
        os.write(out);
    }
    catch (Exception e)
    {

    }
}
catch (Exception e) {...}

You get an extra "&" in the end.

What "mUri", what "host"? how do you read the response? this is useless.

Sending HTTP POST Request In Java - Stack Overflow

java http post
Rectangle 27 4

Posting code that can send form data in post requests and works even on Java 7

HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

    String host = mUri.getHost();

    urlConnection.setRequestMethod("POST"); // PUT is another valid option
    urlConnection.setDoOutput(true);
    Map<String,String> arguments = new HashMap<>();
    arguments.put("key1", "value");
    arguments.put("key2", "value");
    StringBuilder sj = new StringBuilder();
    for(Map.Entry<String,String> entry : arguments.entrySet()) {
        sj.append(URLEncoder.encode(entry.getKey(), "UTF-8") + "=" + URLEncoder.encode(entry.getValue(), "UTF-8") + "&");
    }
    byte[] out = sj.toString().getBytes();

    urlConnection.setFixedLengthStreamingMode(out.length);
    urlConnection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");
    urlConnection.connect();
    try
    {
        OutputStream os = urlConnection.getOutputStream();
        os.write(out);
    }
    catch (Exception e)
    {

    }
}
catch (Exception e) {...}

You get an extra "&" in the end.

What "mUri", what "host"? how do you read the response? this is useless.

Sending HTTP POST Request In Java - Stack Overflow

java http post
Rectangle 27 13

You are getting the exception because none of RestTemplate's default MessageConverters know how to serialize the InputStream contained by the MultipartFile file. When sending objects via RestTemplate, in most cases you want to send POJOs. You can fix this by adding the bytes of the MultipartFile to the MultiValueMap instead of the MultipartFile itself.

File file1 = (File) req.getAttribute("userfile1");

should always return null, as ServletRequest's getAttribute method does not return request/form parameters but attributes set by the servlet context. Are you sure it is actually working with your curl example?

Here is an example of a Spring MVC method forwarding a file to a servlet:

Servlet (though I tested it running in a Spring MVC container), adapted from here:

@RequestMapping("/pi")
private void doPost(HttpServletRequest request, HttpServletResponse response)
        throws ServletException, IOException {

  final String path = request.getParameter("destination");
  final Part filePart = request.getPart("file");
  final String fileName = request.getParameter("filename");

  OutputStream out = null;
  InputStream fileContent = null;
  final PrintWriter writer = response.getWriter();

  try {
    out = new FileOutputStream(new File(path + File.separator
            + fileName));
    fileContent = filePart.getInputStream();

    int read = 0;
    final byte[] bytes = new byte[1024];

    while ((read = fileContent.read(bytes)) != -1) {
      out.write(bytes, 0, read);
    }
    writer.println("New file " + fileName + " created at " + path);

  } catch (FileNotFoundException fne) {
    writer.println("You either did not specify a file to upload or are "
            + "trying to upload a file to a protected or nonexistent "
            + "location.");
    writer.println("<br/> ERROR: " + fne.getMessage());

  } finally {
    if (out != null) {
      out.close();
    }
    if (fileContent != null) {
      fileContent.close();
    }
    if (writer != null) {
      writer.close();
    }
  }
}
@ResponseBody
@RequestMapping(value="/upload/", method=RequestMethod.POST, 
        produces = "text/plain")
public String uploadFile(MultipartHttpServletRequest request) 
        throws IOException {

  Iterator<String> itr = request.getFileNames();

  MultipartFile file = request.getFile(itr.next());
  MultiValueMap<String, Object> parts = 
          new LinkedMultiValueMap<String, Object>();
  parts.add("file", new ByteArrayResource(file.getBytes()));
  parts.add("filename", file.getOriginalFilename());

  RestTemplate restTemplate = new RestTemplate();
  HttpHeaders headers = new HttpHeaders();
  headers.setContentType(MediaType.MULTIPART_FORM_DATA);

  HttpEntity<MultiValueMap<String, Object>> requestEntity =
          new HttpEntity<MultiValueMap<String, Object>>(parts, headers);

  // file upload path on destination server
  parts.add("destination", "./");

  ResponseEntity<String> response =
          restTemplate.exchange("http://localhost:8080/pi", 
                  HttpMethod.POST, requestEntity, String.class);

  if (response != null && !response.getBody().trim().equals("")) {
    return response.getBody();
  }

  return "error";
}

Using these I can succesfully upload a file through the MVC method to the servlet by the following curl:

curl --form file=@test.dat localhost:8080/upload/

java - How to send Multipart form data with restTemplate Spring-mvc - ...

java spring post multipartform-data resttemplate
Rectangle 27 80

The request body is available by HttpServletRequest#getInputStream() and #getReader().

InputStream body = request.getInputStream();
// ...

Note that you can read it only once. The client ain't going to resend it multiple times. Calling getParameter() and so on will implicitly also read it. You've got to store the body somewhere and process yourself.

So your answer is that there is no way to do what I want to do? Its not about the client sending it more than once. The HttpServletRequest clearly stores the post data internally somewhere (as you can always get post parameters multiple times). I appreciate the answer, I just want to fully understand if you're saying "its impossible" or if you're just reitterating what i've already found out.

On first getParameter() call, the HttpServletRequest will internally use getInputStream() to read and parse the request body (it's a byte stream from a network connection) and store it in a map which you can get by getParameterMap(). After this point, you can't read the request body by getInputStream()/getReader() anymore, because it's already been read. If you clarify the functional requirement behind this need more, then we may be able to suggest you better ways to achieve it.

Well, you may want to create a HttpServletRequestWrapper which holds a copy of the request body in a ByteArrayInputStream.

Thanks for the answer. "only read it once"...gotta say I'm pretty surprised by this design decision.

http - How to retrieve raw post data from HttpServletRequest in java -...

java http servlets post
Rectangle 27 80

The request body is available by HttpServletRequest#getInputStream() and #getReader().

InputStream body = request.getInputStream();
// ...

Note that you can read it only once. The client ain't going to resend it multiple times. Calling getParameter() and so on will implicitly also read it. You've got to store the body somewhere and process yourself.

So your answer is that there is no way to do what I want to do? Its not about the client sending it more than once. The HttpServletRequest clearly stores the post data internally somewhere (as you can always get post parameters multiple times). I appreciate the answer, I just want to fully understand if you're saying "its impossible" or if you're just reitterating what i've already found out.

On first getParameter() call, the HttpServletRequest will internally use getInputStream() to read and parse the request body (it's a byte stream from a network connection) and store it in a map which you can get by getParameterMap(). After this point, you can't read the request body by getInputStream()/getReader() anymore, because it's already been read. If you clarify the functional requirement behind this need more, then we may be able to suggest you better ways to achieve it.

Well, you may want to create a HttpServletRequestWrapper which holds a copy of the request body in a ByteArrayInputStream.

Thanks for the answer. "only read it once"...gotta say I'm pretty surprised by this design decision.

http - How to retrieve raw post data from HttpServletRequest in java -...

java http servlets post
Rectangle 27 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)

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};

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 + '}';
    } 
}

I tried this also, but I was getting something like could not found boundary of media error, What does this boundary is for?

It 's part of the multipart specification. Most likely you did not send the request out correctly, maybe allowing the browser to create the request. Even if you set the content type to false/undefined, using FormData as proposed in some of these answers, the data would still be sent out as plain text, and you would still need to parse it on the server side. With the JSON approach, you let the framework parse it. In the solution above, we are created the request body ourselves

@FormDataParam
org.glassfish.jersey.media.multipart.FormDataParam;
javax.ws.rs.FormParam;
org.springframework.web.bind.annotation.RequestBody

Are you using Jersey? If so, go to the link, and it will have the Maven dependency you need to add. Then you need to register the feature also. The link shows Java configuration of the feature. If you are using web.xml, then you can set an init param for the jersey servlet jersey.config.server.provider.classnames - value - org.glassfish.jersey.media.multipart.MultiPartFeature

I am not using Jersey, I am using javax.ws.rs APIs, and also Spring. For example RequestBody was Spring annotation and QueryParam was javax annotation. FormDataParam is not there. How can I add

angularjs - Trouble in posting data as form data in Angular JS to Java...

java angularjs http-post jax-rs
Rectangle 27 1

PRG is used to prevent reload resubmit event, you can always go back to page from browser and submit the form with this

to prevent this you can issue tokens while rendering form and while submitting send it to server and see if that is the right token (by putting it somewhere in session) then process the request

request.getSession().setAttribute("formToken", someCode);

now on submit of form, post the token back to server, and match it with the one from session, if both matches allow the request, if doesn't matches that means the request is already executed or some one is trying to simulate form post and missing the form token in submitted data,

so now if you already have submitted once and if you go back using browser button and resubmit it again the code won't match and it will prevent resubmission

make the token check thing synchronized to handle parallel request case

"By putting it somewhere in session" It would be immensely helpful to me if you could describe how to do that using the code on the page I linked to as an example. You don't necessarily have to grab that code and run it, just describe the process... :)

I guess I'm being a bit dense. But, if I use your snippet above in the doGet (which serves up the form), then match it in doPost, they'll always match because when I click the back button, the doGet gets executed which sets the attribute...

if your browser didn't cache page it will execute doGet, not otherwise, this way you can detect if the user has already submitted the form then don't render the form for this user again and don't take any request for processing for that form for that user

eclipse - Prevent back button resubmit form data in java servlet - Sta...

java eclipse jsp tomcat servlets
Rectangle 27 13

The POST data is available in a controller with request().body().

On the body, you can call .asFormUrlEncoded() to retrieve a Map of the data. You will find more information in the documentation.

For more complex use cases, you can use the Form API to define data constraints and validation and bind data directly to a specific class.

java - How to get form data in Play Framework - Stack Overflow

java playframework playframework-2.0
Rectangle 27 1

You have two bugs in your code, both in the HTML form:

<form action="/locationAccepted" method="GET">
    <input type="text" name="userLocation"/>
    <div class="button">
        <button type="submit">Send your message</button>
    </div>
</form>
request.queryParams("userLocation")

How to get form data in Java Spark using Thymeleaf template engine? - ...

thymeleaf spark-java
Rectangle 27 12

queryParams
request.queryParams("userName")

Note you have to ensure that request.body() is not invoked beforehand (for logging purpose for example), otherwise it consumes the body, the form param won't be parsed. The javadoc is quite lacking on that matter.

This is weird. I was expecting request.params("userName") to return the value but instead request.queryParams("userName") gives the same value. I thought queryParams was supposed to return query strings. Is this normal behaviour of java spark?

Is this normal behaviour of java spark?

@Stephan thanks, your answer saved me. I wanted to test microservice and I have done it kind of differently than most tests example available online, can you please have a look at this question stackoverflow.com/questions/37715875/ , your feedback would be appreciated.

post - How to get data from form with spark java? - Stack Overflow

java post spark-java
Rectangle 27 2

your post entry point is /scanRequest but your submitting to /requestlist, it fails cause you are not targeting the right mapped method .

if /requestlist is the request Mapping of your controller (the one who contains the method scanRequest) than change your form to :

<form:form method="POST" 
action="${contextPath}/requestlist/scanRequest" 
modelAttribute="scanForm"  class="form-signin">...

if is is not and your controller do

<form:form method="POST" 
    action="${contextPath}/scanRequest" 
    modelAttribute="scanForm"  class="form-signin">...

Your scanForm is not present when rendering the page containing the form, so you have to add it, add this method to your controller :

@ModelAttribute("scanForm")
public UserRequestDTO getScanForm(){
  return new UserRequestDTO();
}
public String getSellerName() {
        return seller_name;
    }

this is not a proper getter for attribute seller_name change it to

public String getSeller_name() {
    return seller_name;
}

I added it but another Error, I dont understand what i`m doing wrong..

@Guyb check my edit , dude your getter is wrong, the convention is get+firtLetterto uppercase+the rest of the name of your attribute

@Guyb you are welcome , can you mark it as an answer

java - Spring web application - getting form data - post method - Stac...

java html spring spring-mvc spring-data
Rectangle 27 30

You will need to set the data retrieved in the servlet in request scope so that the data is available in JSP

You will have following line in your servlets.

List<Account> accounts = getAccounts();  
request.setAttribute("accountList",accounts);

Then in JSP you can access this data using the expression language like below

${accountList}

I would use request dispatches instead of the sendRedirect as follows

RequestDispatcher rd = sc.getRequestDispatcher(url);
  rd.forward(req, res);

If you can use RequestDispatcher then you can store these values in request or session object and get in other JSP.

request.sendRedirect
RequestDispatcher
public class AccountServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    List<Account> accounts = getAccountListFromSomewhere();

    String url="..."; //relative url for display jsp page
    ServletContext sc = getServletContext();
    RequestDispatcher rd = sc.getRequestDispatcher(url);

    request.setAttribute("accountList", accounts );
    rd.forward(request, response);
  }
}

google app engine - Pass data from Java Servlet to JSP? - Stack Overfl...

java google-app-engine jsp servlets
Rectangle 27 6

We had a situation where IE forced us to post as text/plain, so we had to manually parse the parameters using getReader. The servlet was being used for long polling, so when AsyncContext::dispatch was executed after a delay, it was literally reposting the request empty handed.

So I just stored the post in the request when it first appeared by using HttpServletRequest::setAttribute. The getReader method empties the buffer, where getParameter empties the buffer too but stores the parameters automagically.

String input = null;

    // we have to store the string, which can only be read one time, because when the
    // servlet awakens an AsyncContext, it reposts the request and returns here empty handed
    if ((input = (String) request.getAttribute("com.xp.input")) == null) {
        StringBuilder buffer = new StringBuilder();
        BufferedReader reader = request.getReader();

        String line;
        while((line = reader.readLine()) != null){
            buffer.append(line);
        }
        // reqBytes = buffer.toString().getBytes();

        input = buffer.toString();
        request.setAttribute("com.xp.input", input);
    }

    if (input == null) {
        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        out.print("{\"act\":\"fail\",\"msg\":\"invalid\"}");
    }

http - How to retrieve raw post data from HttpServletRequest in java -...

java http servlets post
Rectangle 27 6

We had a situation where IE forced us to post as text/plain, so we had to manually parse the parameters using getReader. The servlet was being used for long polling, so when AsyncContext::dispatch was executed after a delay, it was literally reposting the request empty handed.

So I just stored the post in the request when it first appeared by using HttpServletRequest::setAttribute. The getReader method empties the buffer, where getParameter empties the buffer too but stores the parameters automagically.

String input = null;

    // we have to store the string, which can only be read one time, because when the
    // servlet awakens an AsyncContext, it reposts the request and returns here empty handed
    if ((input = (String) request.getAttribute("com.xp.input")) == null) {
        StringBuilder buffer = new StringBuilder();
        BufferedReader reader = request.getReader();

        String line;
        while((line = reader.readLine()) != null){
            buffer.append(line);
        }
        // reqBytes = buffer.toString().getBytes();

        input = buffer.toString();
        request.setAttribute("com.xp.input", input);
    }

    if (input == null) {
        response.setContentType("text/plain");
        PrintWriter out = response.getWriter();
        out.print("{\"act\":\"fail\",\"msg\":\"invalid\"}");
    }

http - How to retrieve raw post data from HttpServletRequest in java -...

java http servlets post
Rectangle 27 30

You will need to set the data retrieved in the servlet in request scope so that the data is available in JSP

You will have following line in your servlets.

List<Account> accounts = getAccounts();  
request.setAttribute("accountList",accounts);

Then in JSP you can access this data using the expression language like below

${accountList}

I would use request dispatches instead of the sendRedirect as follows

RequestDispatcher rd = sc.getRequestDispatcher(url);
  rd.forward(req, res);

If you can use RequestDispatcher then you can store these values in request or session object and get in other JSP.

request.sendRedirect
RequestDispatcher
public class AccountServlet extends HttpServlet {

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

    List<Account> accounts = getAccountListFromSomewhere();

    String url="..."; //relative url for display jsp page
    ServletContext sc = getServletContext();
    RequestDispatcher rd = sc.getRequestDispatcher(url);

    request.setAttribute("accountList", accounts );
    rd.forward(request, response);
  }
}

google app engine - Pass data from Java Servlet to JSP? - Stack Overfl...

java google-app-engine jsp servlets
Rectangle 27 137

Your JSON is not correct. Instead of

JSONObject cred = new JSONObject();
JSONObject auth=new JSONObject();
JSONObject parent=new JSONObject();
cred.put("username","adm");
cred.put("password", "pwd");
auth.put("tenantName", "adm");
auth.put("passwordCredentials", cred.toString()); // <-- toString()
parent.put("auth", auth.toString());              // <-- toString()

OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream());
wr.write(parent.toString());
JSONObject cred = new JSONObject();
JSONObject auth=new JSONObject();
JSONObject parent=new JSONObject();
cred.put("username","adm");
cred.put("password", "pwd");
auth.put("tenantName", "adm");
auth.put("passwordCredentials", cred);
parent.put("auth", auth);

OutputStreamWriter wr= new OutputStreamWriter(con.getOutputStream());
wr.write(parent.toString());

So, the JSONObject.toString() should be called only once for the outer object.

Another thing (most probably not your problem, but I'd like to mention it):

To be sure not to run into encoding problems, you should specify the encoding, if it is not UTF-8:

con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

// ...

OutputStream os = con.getOutputStream();
os.write(parent.toString().getBytes("UTF-8"));
os.close();
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");

POST request send json data java HttpUrlConnection - Stack Overflow

java json post curl httpurlconnection