RestTemplate GET with parameteres with Spring Boot Controller - rest

I'm creating a microservice that recieves data from Rest Template requests to API. I run microservice at localhost:8080 and API at localhost:13001 and test it with Postman. Test method returns String. And there is an issue when request has parameteres. With code below I always get "404 Not Found". But when API controller don't have any parameteres - method works. Can't solve this problem.
Sequence:
1) Postman (GET http://localhost:8080/test)
2) Microservice Controller (Rest Template exchange) --> code below
#RequestMapping(
method = [RequestMethod.GET],
produces = [MediaType.APPLICATION_JSON_VALUE],
path = ["/test"],
params = ["workspace_id"]
)
#ResponseBody
fun test(
authentication : OAuth2Authentication,
#RequestParam(value = "workspace_id")
workspaceId : UUID
) : String
{
return serviceDashboard.get(authentication, workspaceId)
}
3) Rest Template (GET http://localhost:13001/test?workspace_id=......) --> code below
#Autowired
lateinit var restTemplate : RestTemplate
override fun get(
authentication : OAuth2Authentication,
workspaceId : UUID
) : String
{
//Header
val token = (authentication.details as OAuth2AuthenticationDetails).tokenValue
val headers = HttpHeaders()
headers.setBearerAuth(token)
val entity = HttpEntity<Any>(headers)
//Parameters
val params = HashMap<String, UUID>()
params["workspace_id"] = workspaceId
//URI
val endpoint = URI.create("http://localhost:13001/test")
return restTemplate.exchange(endpoint.toString(), HttpMethod.GET, entity, String::class.java, params).body!!
}
4) API Controller (return data) --> code below
----------- Non-working version ----------------
#GetMapping(
produces = [MediaType.APPLICATION_JSON_VALUE],
params = ["workspace_id"],
path = ["/test"])
#ResponseBody
fun test(
#RequestParam(value = "workspace_id")
workspaceId : UUID
) : String
{
if ( workspaceId.toString() == "650a539a-0356-467e-a0d0-71d472c41aae") return "It works"
else return "It doesn't work"
}
----------- Working version ----------------
#GetMapping(
produces = [MediaType.APPLICATION_JSON_VALUE]
path = ["/test"])
#ResponseBody
fun test() : String
{
return "It works"
}

What is the annotation you are using at Class level.
You need to use #RestController.

Related

Spring Boot Feign and Restemplate verify purchase order with Apple return error 21004

I have a Object Dto to verify purchase order with Apple.
String payload = "MIIT3w.....";
String password = "****";
AppleVerifyReceiptRequestCli requestCli= new AppleVerifyReceiptRequestCli();
receiptRequestCli.setReceiptData(payload);
receiptRequestCli.setPassword(password);
receiptRequestCli.setExcludeOldTransaction(false);
Using Restemplate :
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
headers.setAccept(Arrays.asList(MediaType.APPLICATION_JSON));
// Call api to Apple Store to verify
String url = "https://buy.itunes.apple.com/verifyReceipt";
HttpEntity<AppleVerifyReceiptRequestCli> reqUpContentDTO = new HttpEntity<>(requestCli, headers);
HttpEntity<AppleVerifyReceiptResponseCli> responseCliHttpEntity = restTemplate.exchange(url, HttpMethod.POST,reqUpContentDTO, AppleVerifyReceiptResponseCli.class);
Receiver a right resposne {"environment":"Production","receipt":{"adam_id":"159579***" .....}
Using Feign :
#FeignClient(value = "IAppleFeign", url = "https://buy.itunes.apple.com")
public interface IAppleFeign {
#PostMapping(path = "/verifyReceipt",
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<AppleVerifyReceiptResponseCli> verifyReceipt(
#RequestBody AppleVerifyReceiptRequestCli request);
}
Receive response error : {"environment":"Production","receipt":null,"status":21004}
I don't know, why Apple return 21004 with feign ?
Tell me why? please.

How to create a SOAP request in EWS?

I've got such kind of class with required login, password, url and domain:
class Service
{
public ExchangeService service;
public void Connect()
{
const string exchangeUser = "login";
const string exchangePassword = "password";
const string exchangeUri = "url";
service = new ExchangeService(ExchangeVersion.Exchange2010_SP2);
service.UseDefaultCredentials = true;
service.Credentials = new WebCredentials(exchangeUser, exchangePassword, "domain");
service.Url = new Uri(exchangeUri);
}
}
And I need to add such method as CreateAppointment()
public void CreateAppointment()
{
Appointment appointment = new Appointment(service);
appointment.Subject = "Team building exercise";
appointment.Body = "Let's learn to really work as a team and then have lunch!";
appointment.Start = DateTime.Now.AddHours(2);
appointment.End = appointment.Start.AddHours(4);
appointment.Location = "Some city";
appointment.RequiredAttendees.Add("somebody#something.com");
appointment.ReminderMinutesBeforeStart = 30;
appointment.Save(SendInvitationsMode.SendToNone);
}
Save() method doesn't work because of some reasons for creating service and appointment objects. So I need to rewrite this method using xml request. And I've got an example of SOAP request from msdn https://msdn.microsoft.com/en-us/library/office/dd633661(v=exchg.80).aspx
How could I insert the SOAP request instead of CreateAppointment() method? I've got no idea what to do with xml code to make it work as CreateAppointment() method.

Calling a Spring controller from itself based on the response

We have a requirement where...when we get a request to our controller we make a call to another api and based on the other api response we have to retrigger the request to controller with different parameter
#RequestMapping(value = "/search", method = RequestMethod.GET, produces = "application/json")
public Map<String, Account> searchEndpoint(#RequestParam(name = "query", required = true) String query) {
RequestPayload req = new RequestPayload(query);
SearchResponse searchResponse = http.executeSecurePost(this.searchUrl, req, SearchResponse.class);
if(("particularModel").equalsIgnoreCase(searchResponse.getModel()))
{
String differentQueryParameter = searchResponse.getName();
searchEndpoint(differentQueryParameter);
}
else {
//do something else
}
return json response;
}
when i do like this ...it's working fine where it's making the second call and getting the new response and returns ...but again a third query where this time is the original query get's fired. Not sure why the third query is fired. Any help will be appreciated.
calling your handler again and again it may result in a recursive function. you could avoid this kind of programming .you put the logic for calling the api in service method and do it .
#RequestMapping(value = "/search", method = RequestMethod.GET, produces = "application/json")public Map<String, Account> searchEndpoint(#RequestParam(name = "query", required = true) String query) {
//put this logic in service
RequestPayload req = new RequestPayload(query);
SearchResponse searchResponse = http.executeSecurePost(this.searchUrl, req, SearchResponse.class);
if(("particularModel").equalsIgnoreCase(searchResponse.getModel()))
{
String differentQueryParameter = searchResponse.getName();
//put this logic in service and just call it
RequestPayload req = new RequestPayload(query);
SearchResponse searchResponse = http.executeSecurePost(this.searchUrl, req, SearchResponse.class)
}
else {
//do something else
}
return json response;
}

Jersey client. MultivaluedMap goes empty

My RESTful client has this method:
public void testGetCateogrywiseData() {
ClientConfig config = new DefaultClientConfig();
Client client = Client.create(config);
client.addFilter(new LoggingFilter(System.out));
WebResource service = client
.resource("http://localhost:8080/MyApp/rest/publicdata");
#SuppressWarnings("rawtypes")
MultivaluedMap queryParams = new MultivaluedMapImpl();
queryParams.add("latitude", "18.522387");
queryParams.add("longitude", "73.878437");
queryParams.add("categoryID", "2");
service.queryParams(queryParams);
ClientResponse response = service.get(ClientResponse.class);
System.out.println(response.getStatus());
System.out.println("Form response " + response.getEntity(String.class));
}
On the server side the method looks like this:
#Path("publicdata")
#GET
#Produces(MediaType.TEXT_HTML)
#Consumes(MediaType.APPLICATION_FORM_URLENCODED)
public String getPublicData() throws JSONException {
MultivaluedMap<String, String> valueMap = uriInfo.getQueryParameters();
Long latString = Long.parseLong(valueMap.getFirst("latitude"));
Long lonString = Long.parseLong(valueMap.getFirst("longitude"));
Long categoryId = Long.parseLong(valueMap.getFirst("categoryID"));
// Do necessary stuff and return json string
return null;
}
My problem is the valueMap at the server end is always empty. It never gets the three parameters that I have sent from the client code. What am I missing?
The problem happens on this line:
service.queryParams(queryParams);
It successfully adds the query params, but it does not change the original service, it returns a new one to you. To make it work you need to change to this:
service = service.queryParams(queryParams);

Spring 4 Restfull Service with bean

I am trying to create a simple Server / Client application that can send a bean as parameter instead of String but failing below is my code
Server
#Controller
public class GreetingController {
private static final String template = "Hello, %s!";
private final AtomicLong counter = new AtomicLong();
#RequestMapping(method=RequestMethod.POST,value="/returnGreet")
public #ResponseBody Greeting returnGreet(
#RequestBody(required=false) Greeting greet) {
if(greet == null)
return new Greeting(counter.incrementAndGet(),
String.format(template, greet));
else
return new Greeting(0,"Testing");
}
}
Client
RestTemplate restTemplate = new RestTemplate();
MultiValueMap<String,Greeting> greet = new LinkedMultiValueMap<String, Greeting>();
greet.add("greet", new Greeting(0,"XOXO"));
greeting = restTemplate.postForObject("http://localhost:8080/returnGreet",greet, Greeting.class,greet);
System.out.println("Content: " + greeting.getContent());
System.out.println("Id: " + greeting.getId() );
The result is always null for the object greet at the server side.
Any Idea ?
You're not using the RestTemplate correctly. Why are you passing a MultiValueMap as the Entity to be sent? This won't get serialized the way your Server expects.
Just use the Greeting object directly.
restTemplate.postForObject("http://localhost:8080/returnGreet", new Greeting(0, "XOXO"), Greeting.class);
Also, the last argument is not necessary, you don't have any URI variables.