Trying to call/post a third party api in java spring - java

My issue is when I try this I get a media type error, then I changed the header. Now I receive a 500 error. The problem isnt the api , on postman it works perfectly , am I doing something wrong in my code when requesting a post?
My object model
public class EmailModel {
private String module;
private String notificationGroupType;
private String notificationGroupCode;
private String notificationType;
private String inLineRecipients;
private String eventCode;
private HashMap<String, Object> metaData;
public EmailModel() {
this.module = "CORE";
this.notificationGroupType = "PORTAL";
this.notificationGroupCode = "DEFAULT";
this.notificationType = "EMAIL";
this.inLineRecipients = "[chrispotjnr#gmail.com,chris#mqattach.com]";
this.eventCode = "DEFAULT";
this.metaData = metaData;
}
}
My Controller
It should send a post request with a object body, the emails get sent
#RequestMapping(value = "test", method = RequestMethod.Post)
public void post() throws Exception {
String uri = "TestUrl";
EmailModel em = new EmailModel();
EmailModel data = em;
HttpClient client = HttpClient.newBuilder().build();
HttpRequest request = HttpRequest.newBuilder()
.headers("Content-Type", "application/json")
.uri(URI.create(uri))
.POST(HttpRequest.BodyPublishers.ofString(String.valueOf(data)))
.build();
HttpResponse<?> response = client.send(request, HttpResponse.BodyHandlers.discarding());
System.out.println(em);
System.out.println(response.statusCode());
}
postmanImage

You must to convert EmailModel to json format by ObjectMapper
ObjectMapper objectMapper = new ObjectMapper();
String data = objectMapper
.writerWithDefaultPrettyPrinter()
.writeValueAsString(em);
and change POST to :
.POST(HttpRequest.BodyPublishers.ofString(data))
See more about ObjectMapper

Capture requests and cookies(on the left side of setting icon)
->Request
->port and put the port number there

Related

HMAC Validation in SpringBoot failing due to rearrangement of JSON

I am trying to have HMAC in springBoot for REST API.
The request I send from Postman is
{
"name":"xyz",
"description":"hello world",
"phone":"123456",
"id":"1"
}
it reached my controller and then to the service where I have a function to validate HMAC.
In the controller I pass the signature as the header and payload in the requestBody
#RestController
public class UserController {
#Autowired
UserInterface userInterface;
#PostMapping(value = "/" ,consumes = MediaType.APPLICATION_JSON_VALUE, produces = MediaType.APPLICATION_JSON_VALUE)
public void createUser(#RequestBody User user, #RequestHeader Map<String, String> headers) {
userInterface.hmacValidation(user, headers);
}
}
#Service
public class UserService implements UserInterface {
public void hmacValidation(User requestBody, Map<String, String> header) {
var headerSignature = header.get("signature");
var payload = getRequestBodyAsString(requestBody);
String result = Hashing.hmacSha256("12345".getBytes(StandardCharsets.UTF_8)).hashString(payload,StandardCharsets.UTF_8).toString();
}
private String getRequestBodyAsString(User requestBody) {
var mapper = new ObjectMapper();
String payload = null;
try {
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
payload = mapper.writeValueAsString(requestBody);
} catch (JsonProcessingException e) {
}
return payload;
}
}
here from the getRequestBodyAsString(User requestbody) function the output I get is a shuffled/rearranged JSON request which generates different Signature which then mismatches the signature client is sending.
the payload that is converted back from UserObject:
{"name":"xyz","id":"1","description":"hello world","phone":"123456"}
public class User {
private String name;
private String id;
private String description;
private String phone;
}
The client can send the request in any order but I have to validate signature regardless of the order the request comes in
Is there any other way to validate HMAC?
You should not deserialize if you want to take hash value. Use string or byte for the request. And map it to your pojo later on once you have the hash
For ex :
public #ResponseBody String controllerMethod(HttpServletRequest httpReq,
HttpServletResponse httpResponse) {
BufferedReader bufferedReader;
StringBuilder sb;
sb = new StringBuilder();
bufferedReader = httpReq.getReader();
char[] charBuffer = new char[128];
int bytesRead;
while ((bytesRead = bufferedReader.read(charBuffer)) != -1) {
sb.append(charBuffer, 0, bytesRead);
}
String reqBody = sb.toString();
}
Use reqBody to get your hashed value.

I cannot send an HTTP request (500 internal server error)

I am currently receiving the following error for the http request am sending. I am trying to send a JSON Array list to trigger a method in the receiving end so as it saves the list in its database.
The 500 Internal Server Error is a very general HTTP status code that means something has gone wrong on the website's server, but the server could not be more specific on what the exact problem is.
Websites phrase 500 errors in many ways but they're all basically saying the same thing: there's a general server issue going on right now.
Most of the time there isn't anything you can do but contact the website directly and then wait on them to fix it.
In the off chance there is a problem on your end, try clearing the cache and deleting any cookies from the site with the error.
Please find the error below:
org.springframework.web.client.HttpServerErrorException: 500 Internal Server
public static String FRONT_URL;
public static String BACK_URL;
public static final String REST_SYNC = "rest/sync";
public static final String REST_API = "rest/api";
private Logger log = Logger.getLogger(FrontSynchronizer.class);
static final Logger synclog = Logger.getLogger("sync");
ResourceBundle rb = ResourceBundle.getBundle("bundles.sync-application-resources", Locale.getDefault());
//method sending the request
public void syncApplications(List<SchemeApplication> accList) {
schemeApplicationDto=new SchemeApplicationDto();
FRONT_URL = rb.getString("sync.front.url").concat(REST_SYNC);
BACK_URL = rb.getString("sync.back.url").concat(REST_API);
JSONArray array = new JSONArray();
if (accList != null && accList.size() > 0) {
for (SchemeApplication student : accList) {
schemeApplicationDto.setId(student.getId());
schemeApplicationDto.setAccountID(student.getAccountID());
schemeApplicationDto.setNoOfPersonsEmployedLocal(student.getNoOfPersonsEmployedLocal());
schemeApplicationDto.setLocalmainclients(student.getLocalmainclients());
JSONObject studentJSON = new JSONObject(schemeApplicationDto);
array.put(studentJSON);
}
}
HttpHeaders headers = new HttpHeaders();
JSONObject object = new JSONObject();
object.put("array", array);
headers.setContentType(MediaType.APPLICATION_JSON);
RestTemplate restTemplate = this.createnewTemplate();
String url = BACK_URL.concat("/application");
HttpEntity<String> requestEntity = new HttpEntity<String>(object.toString(), headers);
ResponseEntity<Boolean> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity,
Boolean.class);
if (responseEntity.getBody())
{
for(SchemeApplication scheme:accList) {
schemeApplicationService.getDao().delete(scheme);
}
}
}
public RestTemplate createnewTemplate() {
// RestTemplate restTemplate = new RestTemplate(clientHttpRequestFactory());
HttpComponentsClientHttpRequestFactory httpRequestFactory = new HttpComponentsClientHttpRequestFactory();
httpRequestFactory.setConnectTimeout(120000);
RestTemplate restTemplate = new RestTemplate(httpRequestFactory);
return restTemplate;
}
// method that needs to process the request
//The method is trying to send an Array list so as the receiving end can receive the list and save it in its database.
#RequestMapping(value = "application", method = RequestMethod.POST)
public Boolean getAllArchivedpplications(#RequestBody String schemeJson) {
List<SchemeApplication> accList = null;
try {
accList = new ArrayList<SchemeApplication>();
if (StringUtils.isNotEmpty(schemeJson)) {
JSONObject listObject = new JSONObject(schemeJson);
JSONArray entryArray = listObject.getJSONArray("array");
for (int i = 0; i < entryArray.length(); i++) {
JSONObject res = new JSONObject(entryArray.get(i).toString());
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
schemeApplication doc = mapper.readValue(res.toString(),
new TypeReference<schemeApplication>() {
});
accList.add(doc);
}
schemeService.getDao().save(accList); // Service.save accountlist;
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
#RequestBody must work on an object.
Standard way to do this kind of work in two ways:
Form a class having class files with same name and structure with your json data you are sending and capture that data in by #RequestBody annotation
As you are sending data as String, send it as request param, and use #RequestParam instead of #RequestBody and parse the way you need to do things. For I think for this kind of arrayList of bulk data you are working with, option 1 will be better/feasible.
For details you can check here: #RequestBody and #ResponseBody annotations in Spring

How can I pass headers using RestTemplate?

In my method I initially used RestTemplate postForObject method to post request to an endpoint. Now I have to add default OAuth token and pass it as Post request. Is there any way I can pass both request as well as Default Header as part of POST request by using postForObject?
Initiall I used below postForObject
String result = restTemplate.postForObject(url, request, String.class);
I am looking for something like below
restTemplate.exchange(url,HttpMethod.POST,getEntity(),String.class );
Here is my code
private final String url;
private final MarkBuild header;
public DataImpl(#Qualifier(OAuth) MarkBuild header,RestTemplate restTemplate) {
this.restTemplate= restTemplate;
this.header = header;
}
public void postJson(Set<String> results){
try {
Map<String, String> requestBody = new HashMap<>();
requestBody.put("news", "data");
JSONObject jsonObject = new JSONObject(requestBody);
HttpEntity<String> request = new HttpEntity<String>(jsonObject.toString(), null);
String result = restTemplate.postForObject(url, request, String.class);
}
}
Below is getHttpEntity which I want to pass with Post request
private HttpEntity getHttpEntity(Set <String>results) {
return new HttpEntity<>( null, getHttpHeaders() );
}
private HttpHeaders getHttpHeaders() {
return header.build();
}
}
Is there any way I can pass both request as well as Default Header as
part of POST request by using postForObject?
Yes, there is a way to do that, I can give a basic example:
HttpHeaders lHttpHeaders = new HttpHeaders();
lHttpHeaders.setContentType( MediaType.APPLICATION_JSON );//or whatever it's in your case
String payload="<PAYLOAD HERE>"
try
{
String lResponseJson = mRestTemplate.postForObject( url, new HttpEntity<Object>( payload, lHttpHeaders ), String.class);
return lResponseJson;
}
catch( Exception lExcp )
{
logger.error( lExcp.getMessage(), lExcp );
}
Let me know if this doesn't work!!

How to do GET API Request with URL params?

Client client = ClientBuilder.newClient();
urlApi="https://localhost:123/demo/api/v1/rows/search?";
WebTarget webTarget = client.target(urlApi);
for (Map.Entry<String, String> entry : queryParams.entrySet()) {
webTarget.queryParam(entry.getKey(), entry.getValue());
}
webTarget.queryParam("searchConditions",webTarget.queryParam("mobileNo","+9999999999"));
Invocation.Builder builder = webTarget.request();
builder.header("id", "ABC");
String asB64 = Base64.getEncoder().encodeToString("ABC:PWD".getBytes("utf-8"));
logger.debug("Calling API "+urlApi);
builder.header("Authorization", "Basic "+asB64);
builder.header("Content-type", MediaType.APPLICATION_JSON);
response = builder.get();
responseData = response.readEntity(String.class);
System.out.println(responseData);
I am trying to do GET request with searchCondition as Key and value as {mobileNo="+919999999999"}, I am unable to get this to work.
Apart from that, how can I print the Request "Headers" along with "Query params"? Thank you in advance
I think you need to encode the value inputs, something like this:
webTarget.queryParam("searchCondition", URLEncoder.encode("{mobileNo=\"+919999999999\"}", StandardCharsets.UTF_8.toString()));
UDPATE:
Example of the rest client with Spring:
#Test
public void testStack() throws Exception {
RestTemplate rest = new RestTemplate();
String fooResourceUrl="http://localhost:8080/usersParam?";
RestTemplate restTemplate = new RestTemplate();
String parameter = "{mobileNo=\"+919999999999\"}";
ResponseEntity<String> response = restTemplate.getForEntity(fooResourceUrl + "parameter=" + URLEncoder.encode(parameter, StandardCharsets.UTF_8.toString() ), String.class);
assertThat(response.getStatusCode()).isEqualTo(HttpStatus.OK);
}
And this would be the rest service:
#RequestMapping(method = RequestMethod.GET, value="/usersParam")
public User getUsersInfo(#RequestParam String parameter) throws UnsupportedEncodingException {
System.out.println(URLDecoder.decode(parameter, StandardCharsets.UTF_8.toString() ));
return null;
}

Facing difficulty in creating Request Object in Front End Java Spring MVC, need to replicate following .NET-MVC code into java

I am developing a front end application using Java Spring-MVC, however I'm facing difficulties in creating Request Object for Hitting Web-Services as I did in .Net-MVC. Can anyone tell me the equivalent classes and methods in Java for below given code.
I need to replicate these 2 methods from .Net-MVC to Java.
1st Method:
private HttpWebRequest RequestObj { get; set; }
public Stream DataStreamObj { get; set; }
private RequestModel RequestModelObj { get; set;
public RequestGenerator(String WebserviceUrl)
{
RequestObj = (HttpWebRequest)WebRequest.Create(WebConfigurationManager.AppSettings["WebServiceURL"] + WebserviceUrl);
RequestObj.Method = "POST";GenerateLoginRequest
RequestObj.ContentType = "application/json";
RequestModelObj = new RequestModel();
RequestModelObj.ApiKey = WebConfigurationManager.AppSettings["apiKey"];
RequestModelObj.DeviceId = Constant.AppConstants.ONE;
}
2nd Method:
private string CallWebservice(Dictionary<String, Object> RequestDict)
{
try
{
HttpWebRequest Request = (HttpWebRequest)RequestDict["request"];
RequestModel RequestModel = (RequestModel)RequestDict["requestData"];
//Tell them the length of content
string Json = JsonConvert.SerializeObject(RequestModel);
byte[] ByteArray = Encoding.UTF8.GetBytes(Json);
Request.ContentLength = ByteArray.Length;
//Write content on stream
Stream DataStream = Request.GetRequestStream();
DataStream.Write(ByteArray, 0, ByteArray.Length);
DataStream.Close();
//Initiate Call
HttpWebResponse Response = GetWebResponse(Request);
DataStream = Response.GetResponseStream();
StreamReader Reader = new StreamReader(DataStream);
// Read the content.
string responseFromServer = Reader.ReadToEnd();
// Display the content.
Reader.Close();
Response.Close();
return responseFromServer;
}
catch (System.Net.WebException ex)
{
var response = ex.Response as HttpWebResponse;
return "";
}
}
RestTemplate class is designed to call REST services, it should come as no surprise that its main methods are closely tied to REST’s underpinnings, which are the HTTP protocol’s methods: HEAD, GET, POST, PUT, DELETE, and OPTIONS. E.g. it’s methods are headForHeaders(), getForObject(), postForObject(), put() and delete() etc.
Read More and Source Code : Spring REST JSON Example
HTTP GET Method Example
1) Get XML representation of employees collection in String format
REST API Code
#RequestMapping(value = "/employees", produces =
MediaType.APPLICATION_XML_VALUE, method = RequestMethod.GET)
public String getAllEmployeesXML(Model model)
{
model.addAttribute("employees", getEmployeesCollection());
return "xmlTemplate";
}
REST Client Code
private static void getEmployees()
{
final String uri =
"http://localhost:8080/springrestexample/employees.xml";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
System.out.println(result);
}
2) Get JSON representation of employees collection in String format
REST API Code
#RequestMapping(value = "/employees", produces =
MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public String getAllEmployeesJSON(Model model)
{
model.addAttribute("employees", getEmployeesCollection());
return "jsonTemplate";
}
REST Client Code
private static void getEmployees()
{
final String uri =
"http://localhost:8080/springrestexample/employees.json";
RestTemplate restTemplate = new RestTemplate();
String result = restTemplate.getForObject(uri, String.class);
System.out.println(result);
}
3) Using custom HTTP Headers with RestTemplate
REST API Code
#RequestMapping(value = "/employees", produces =
MediaType.APPLICATION_JSON_VALUE, method = RequestMethod.GET)
public String getAllEmployeesJSON(Model model)
{
model.addAttribute("employees", getEmployeesCollection());
return "jsonTemplate";
}
REST Client Code
private static void getEmployees()
{
final String uri = "http://localhost:8080/springrestexample/employees";
RestTemplate restTemplate = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
HttpEntity<String> entity = new HttpEntity<String>("parameters",
headers);
ResponseEntity<String> result = restTemplate.exchange(uri,
HttpMethod.GET, entity, String.class);
System.out.println(result);
}
4) Get data as mapped object
REST API Code
#RequestMapping(value = "/employees", produces =
MediaType.APPLICATION_XML_VALUE, method = RequestMethod.GET)
public String getAllEmployeesXML(Model model)
{
model.addAttribute("employees", getEmployeesCollection());
return "xmlTemplate";
}
REST Client Code
private static void getEmployees()
{
final String uri = "http://localhost:8080/springrestexample/employees";
RestTemplate restTemplate = new RestTemplate();
EmployeeListVO result = restTemplate.getForObject(uri,
EmployeeListVO.class);
System.out.println(result);
}
5) Passing parameters in URL
REST API Code
#RequestMapping(value = "/employees/{id}")
public ResponseEntity<EmployeeVO> getEmployeeById (#PathVariable("id")
int id)
{
if (id <= 3) {
EmployeeVO employee = new
EmployeeVO(1,"Lokesh","Gupta","howtodoinjava#gmail.com");
return new ResponseEntity<EmployeeVO>(employee, HttpStatus.OK);
}
return new ResponseEntity(HttpStatus.NOT_FOUND);
}
REST Client Code
private static void getEmployeeById()
{
final String uri =
"http://localhost:8080/springrestexample/employees/{id}";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "1");
RestTemplate restTemplate = new RestTemplate();
EmployeeVO result = restTemplate.getForObject(uri, EmployeeVO.class,
params);
System.out.println(result);
}
HTTP POST Method Example
REST API Code
#RequestMapping(value = "/employees", method = RequestMethod.POST)
public ResponseEntity<String> createEmployee(#RequestBody EmployeeVO
employee)
{
System.out.println(employee);
return new ResponseEntity(HttpStatus.CREATED);
}
REST Client Code
private static void createEmployee()
{
final String uri = "http://localhost:8080/springrestexample/employees";
EmployeeVO newEmployee = new EmployeeVO(-1, "Adam", "Gilly",
"test#email.com");
RestTemplate restTemplate = new RestTemplate();
EmployeeVO result = restTemplate.postForObject( uri, newEmployee,
EmployeeVO.class);
System.out.println(result);
}
HTTP PUT Method Example
REST API Code
#RequestMapping(value = "/employees/{id}", method = RequestMethod.PUT)
public ResponseEntity<EmployeeVO> updateEmployee(#PathVariable("id")
int id, #RequestBody EmployeeVO employee)
{
System.out.println(id);
System.out.println(employee);
return new ResponseEntity<EmployeeVO>(employee, HttpStatus.OK);
}
REST Client Code
private static void deleteEmployee()
{
final String uri =
"http://localhost:8080/springrestexample/employees/{id}";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "2");
EmployeeVO updatedEmployee = new EmployeeVO(2, "New Name", "Gilly",
"test#email.com");
RestTemplate restTemplate = new RestTemplate();
restTemplate.put ( uri, updatedEmployee, params);
}
HTTP DELETE Method Example
REST API Code
#RequestMapping(value = "/employees/{id}", method =
RequestMethod.DELETE)
public ResponseEntity<String> updateEmployee(#PathVariable("id") int
id)
{
System.out.println(id);
return new ResponseEntity(HttpStatus.OK);
}
REST Client Code
private static void deleteEmployee()
{
final String uri =
"http://localhost:8080/springrestexample/employees/{id}";
Map<String, String> params = new HashMap<String, String>();
params.put("id", "2");
RestTemplate restTemplate = new RestTemplate();
restTemplate.delete ( uri, params );
}

Categories