How to consume a REST service which accepts form data in Spring?

Let’s say you want to consume a REST service from your Spring Boot / Spring MVC application.

The developer who created the REST service you wanted to consume, developed it in such a way that it accepts only form data.

May be he created it to accept data from HTML forms.

And now you want to consume it.

You can’t access the service the same way you access a regular POST method . You can use the same REST template (provided by Spring) but you need to change a few things.

Here is the algorithm to implement:

  • Create HTTP header with content type as URL encoded application form.
  • Use MultiValueMap datastructure to populate the input parameters
  • Create HttpEntity object using the mutlivaluemap and the header created in the previous steps
  • Use postForEntity() method of Rest Template class( provided by Spring )to invoke the REST service using its service URL and the entity object created above.

Here is the code :

package com.springrest.formdataconsumer;

import java.util.Map;

import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

@RestController
public class FormDataConsumerController {

	@PostMapping("/submitFormThroughService")
	public String sumitForm(@RequestBody Map<String, String> request) {

		HttpHeaders headers = new HttpHeaders();
		headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

		MultiValueMap<String, String> inputMap = new LinkedMultiValueMap<>();

		inputMap.add("name", request.get("name"));

		HttpEntity<MultiValueMap<String, String>> entity = new HttpEntity<MultiValueMap<String, String>>(inputMap,
				headers);

		RestTemplate template = new RestTemplate();

		ResponseEntity<String> response = template.postForEntity("http://localhost:8080/submitForm", entity,
				String.class);

		return response.getBody();

	}
}

As you can see , I have implemented all of the steps mentioned in the above algorithm.

The service I want to consume is deployed at :

http://localhost:8080/submitForm

It returns a string message .

I am getting the response and exposing it again through a regular POST REST service.

Here is the service accepting form data , invoked through postman:

I have selected Body type as x-www-form-urlencoded and entered value for the field “name”.

The service returns the message “Thank you ” along with the name passed.

Now let me call it through the REST service I created.

Here is the new REST service called through POSTMAN rest client:

As you see I have passed a JSON input with value for “name” field.

On hitting SEND , the REST service I created internally calls the REST service which accepts only form data.

And returns the same response.

Note:

I deployed the REST service accepting form data at port 8080 and the REST service which calls it at port 9090 for the above demonstration.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s