I am sending this as body from postman : "userId":"11" .
#PostMapping(value="/logout",consumes = "application/json")
public void logout(#RequestBody String userId){
ordersService.logout(userId);
}
Then return holds userId= "{\r\n "userId":"11"\r\n}" ,but i just want to get the value 11.I dont want to get the key. How can I do that?
This should do the work
#RequestMapping(
path = "/logout",
method = RequestMethod.PUT,
produces = MediaType.APPLICATION_JSON_UTF8_VALUE
)
public void logout(#NotNull #RequestBody Long userId)
{
ordersService.logout(userId);
}
Related
I am trying to check if the response from the API GET method is Null. The response is like
{
"#odata.context": "https://dev.com/data/$metadata#Customers",
"value": []
}
I need to check if the value array is null or not and do the necessary steps below is what I tried
public class deserializeData
{
public String #odata_context {get;set;} // in json: #odata.context
public List<Value> value {get;set;}
}
public class getDataFromExternalSystem{
public string getDataFrom(){
.......
Http http1 = new Http();
HttpRequest req1 = new HttpRequest();
req1.setEndpoint(endPoint);
req1.setMethod('GET');
req1.setHeader('Authorization','Bearer '+atoken);
HttpResponse res1 = http1.send(req1);
System.debug('Response Body=========' + res1.getBody());
deserializeData dsData = (deserializeData)JSON.deserialize(res1.getbody(),deserializeData.class);
if(dsData.value.size = null) {
......
}
else{
......
}}
But I get below error like
#odata_context is not a legal identifier in Apex. # is used to introduce annotations.
If you're using JSON2Apex, which appears to be the case, you'll need to change the name of the property to something legal for Apex (like odata_context), and make the corresponding change in the parser method. E.g., where JSON2Apex generates
if (text == '#odata.context') {
#odata_context = parser.getText();
you'll need to replace that identifier with the new one you choose.
I am working on/extending TOH. I have an add method that wants to push the new Hero onto the array then return user to the list.
the result of the call to addHero is coming back as a JSON hero inside double ticks, so as a string.
i have read many articles which seem to point to
angular.toJson
or
.map(response=> response.JSON())
These are not working.
Here is the excerpt from my heroes.component.ts
add(name: string): void {
name = name.trim();
if (!name) { return; }
this.heroService.addHero({ name } as Hero)
.subscribe(hero =>
{
this.heroes.push(hero);
this.location.go('/Heroes');
}
);
}
and hero.service.ts
This clearly returns a Hero object...
addHero (hero: Hero): Observable<Hero> {
return this.http.post<Hero>(this.heroesUrl, hero, httpOptions).pipe(
tap((hero: Hero) => console.log(`added hero w/ id=${hero.id}`)),
catchError(this.handleError<Hero>('addHero'))
);
}
Upon return, the result is successfully pushed to the array, but enclosed in quotes.
The UI evidence of this is that the list has a blank entry at the bottom because there is no .Name property on that final array element.
If i refresh the page, everyone gets loaded as json.
Simple question but I can not seem to find an answer. Have been through many S/O questions involving ng2, php, etc. but none seem to address ng6, or provide a clue I can take away. if they do, Im missing it.
If you want to parse a json into a javascript object you can use JSON.parse(response.JSON())
I'm guessing response.JSON() is returning the response as json, which then needs to be parsed
Edit: you can probably just remove the map => response.JSON() . As angular httpClient already parses it
The issue was the return type of the routine in the service.
#youris question got me to look harder at the service.
The issue is that the default response is not coded correctly as utf8 and 'text/html'
Here is the corrected code.
Public Function add(mh As mHero) As CustomJsonStringResult
Dim h As New TOHbos.Hero()
h.name.Value = mh.name
h.Save()
Return JsonStringResultExtension.JSONString(Me, h.JSON, HttpStatusCode.OK)
End Function
the referenced JsonStringResultExtension is credited to #NKosi in this post. (Code included for ease of referece)
Web Api: recommended way to return json string
public static class JsonStringResultExtension {
public static CustomJsonStringResult JsonString(this ApiController controller, string jsonContent, HttpStatusCode statusCode = HttpStatusCode.OK) {
var result = new CustomJsonStringResult(controller.Request, statusCode, jsonContent);
return result;
}
public class CustomJsonStringResult : IHttpActionResult {
private string json;
private HttpStatusCode statusCode;
private HttpRequestMessage request;
public CustomJsonStringResult(HttpRequestMessage httpRequestMessage, HttpStatusCode statusCode = HttpStatusCode.OK, string json = "") {
this.request = httpRequestMessage;
this.json = json;
this.statusCode = statusCode;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken) {
return Task.FromResult(Execute());
}
private HttpResponseMessage Execute() {
var response = request.CreateResponse(statusCode);
response.Content = new StringContent(json, Encoding.UTF8, "application/json");
return response;
}
}
}
Making these changes, the result is json, its pushed to the array correctly, and shows up in the Heroes list correctly.
Hi I have a json request which I have to pass in my junit testcase but the request is delete as delete do not support setEntity method. How can I pass the request in my testcase.
Json request which I have to pass
{
"userId":"AJudd",
"siteId":"131",
"alternateSiteId":"186"
}
mytest case for this
#Test
public void testdeleteAltSite() throws ClientProtocolException, IOException {
String resultCode = "001";
String resultText = "Success";
String url = "http://localhost:8080/adminrest1/alternatesite";
HttpClient client = HttpClientBuilder.create().build();
HttpDelete delete = new HttpDelete(url);
// add header
delete.addHeader("Transaction-Id", "11");
delete.addHeader("content-type", "application/json");
LOG.info(url);
HttpResponse response = client.execute(delete);
byte[] buf = new byte[512];
InputStream is = response.getEntity().getContent();
int count = 0;
StringBuilder builder = new StringBuilder(1024);
while ((count = is.read(buf, 0, 512)) > 0) {
builder.append(new String(buf, 0, count));
}
String output = builder.toString();
System.out.println(output);
}`
How to pass the json value so that the passed value data can be deleted?
IMHO this is a problem with your design.
If your intent is to delete an alternate site and its id is unique then passing the alternateSiteId as part of the URI should sufficient:
Method: DELETE
URL: http://localhost:8080/adminrest1/alternatesite/{alternateSiteId}
If alternateSiteId is not unique then you are updating a relationship. In that case you should use a PUT which allows you to include a body in your request. Please note you should pass the id of the resource you are updating as part of your URI, for example:
Method: PUT
URL: http://localhost:8080/adminrest1/alternatesite/{userId}
Body:{
"siteId":"131",
"alternateSiteId":"186"
}
Ok, first of all: Sending a body with a DELETE is not what usually happens around the internet. Nevertheless, it is not forbidden (Is an entity body allowed for an HTTP DELETE request?). So, two ideas:
1) New class
I assume you use org.apache.http.client: Just extend HttpEntityEnclosingRequestBase:
public class HttpDeleteWithEntity extends HttpEntityEnclosingRequestBase {
public final static String METHOD_NAME = "DELETE";
public HttpDeleteWithEntity() {
super();
}
public HttpDeleteWithEntity(final URI uri) {
super();
setURI(uri);
}
public HttpDeleteWithEntity(final String uri) {
super();
setURI(URI.create(uri));
}
#Override
public String getMethod() {
return METHOD_NAME;
}
}
This is basically c&p'ed from the HttpPost class. I did not test this, tho.
Then use your HttpDeleteWithEntity class instead of HttpDelete.
2) Use custom headers
If you can modify your server code that might be a good alternative.
delete.addHeader("testwith", jsonString);
or
delete.addHeader("userId","AJudd");
delete.addHeader("siteId","131");
delete.addHeader("alternateSiteId","186);
Finally, if you are in charge of the server implementation I would recommend to implement DELETE requests without any body (see artemisian's answer).
I have the following situation:
My REST API one:
#RestController
#RequestMapping("/controller1")
Public Class Controller1{
#RequestMapping(method = RequestMethod.POST)
public void process(#RequestBody String jsonString) throws InterruptedException, ExecutionException
{
............
}
}
JSON POST request, request1, for the REST API(Controller1):
{
"key1":"value1",
"key2":"value2"
}
My REST API two:
#RestController
#RequestMapping("/controller2")
Public Class Controller2{
#RequestMapping(method = RequestMethod.POST)
public void process(#RequestBody String jsonString) throws InterruptedException, ExecutionException
{
............
}
}
JSON request, request2, for the REST API(Controller2):
{
"key1":"value1",
"key2":"value2",
"key3":"value3"
}
I have several such "primitive" requests.
Now, I am expecting a JSON request, let's call it request3, which is a combination of such "primitive" queries- something that looks like below:
{
{
"requestType":"requestType1",
"request":"[{"key1":"value1","key2":"value2"}]"
},
{
"requestType":"requestType2",
"request":"[{"key1":"value1","key2":"value2","key3":"value3"}]"
}
}
Here, I need to trigger the respective API (one or two) upon identifying the query type. I wanna know how I can forward the request to the corresponding REST API. I wrote the REST API for request3 like below:
#RestController
#RequestMapping("/controller3")
Public Class Controller3{
#RequestMapping(method = RequestMethod.POST)
public void process(#RequestBody String jsonString) throws InterruptedException, ExecutionException
{
..................
..................
switch(request){
case request1: //how to call REST API 1?
case request2: //how to call REST API 2?
}
}
}
You can call a utility method which posts request to controller using Rest Template as below. Since you are using POST method it's easy to send parameters using Rest Template. You may need to edit this code a bit to work in your environment with exact syntax.
#RequestMapping( value= "/controller3" method = RequestMethod.POST)
public #ResponseBody void process(#RequestBody String jsonString){
String request = requestType //Get the request type from request
String url = "";
MultiValueMap<String, String> params= null;
switch(request){
case request1: //how to call REST API 1?
url = "/controller1";
params = request1param //Get the parameter map from request
case request2: //how to call REST API 2?
url = "/controller2";
params = request2Param //Get the parameter map from request
}
//Now call the method with parameters
getRESTResponse(url, params);
}
private String getRESTResponse(String url, MultiValueMap<String, String> params){
RestTemplate template = new RestTemplate();
HttpEntity<MultiValueMap<String, String>> requestEntity=
new HttpEntity<MultiValueMap<String, String>>(params);
String response = "";
try{
String responseEntity = template.exchange(url, HttpMethod.POST, requestEntity, String.class);
response = responseEntity.getBody();
}
catch(Exception e){
response = e.getMessage();
}
return response;
}
Redirect from one controller method to another controller method
Alternatively you also can call the rest method using Rest Template
Spring MVC - Calling a rest service from inside another rest service
You may find how to send POST request with params in this post
https://techie-mixture.blogspot.com/2016/07/spring-rest-template-sending-post.html
i have json string like this downbelow
{"0":{"in":"mmm","loc":"1234"},"1":{"in":"mmm","loc":"1234"}}
Now i need to parse them as like
in | loc
---------
mmm| 1234
mmm| 1234
So far i did
public with sharing class Search
{
public String strTag {get;set;}
public String strlocation {get;set;}
public String result {get;set;}
public PageReference find() {
HttpRequest req = new HttpRequest();
HttpResponse res = new HttpResponse();
Http http = new Http();
req.setEndpoint('http://test.3spire.net/index.php?in='+strTag+'&loc='+strlocation);
req.setMethod('GET');
//these parts of the POST you may want to customize
req.setCompressed(false);
req.setBody('key1=value1&key2=value2');
req.setHeader('Content-Type', 'application/x-www-form-urlencoded');
try {
res = http.send(req);
} catch(System.CalloutException e) {
system.debug('Callout error: '+ e);
result = ''+e;
}
Result results = (Result) JSON.deserialize(res.getBody(),ResultSet.class);
result = res.getBody();
system.debug(res.getBody());
return null;
}
public class ResultSet{
public List<Result> resultSet;
}
public class Result
{
public String ins;
public String loc;
}
}
But its returns
System.TypeException: Invalid conversion from runtime type Search.ResultSet to Search.Result
How can i solved this problem
Thanks in advance
You are calling JSON.deserialize(res.getBody(),ResultSet.class). The second parameter ResultSet is the Apex object type you want the result to be. But then you attempt to cast it to a type of Result instead.
Either do
Result results = JSON.deserialize(res.getBody(), Result.class);
or
ResultSet results = JSON.deserialize(res.getBody(), ResultSet.class);
In your case, based on the JSON it would seem you want the second option. However, your JSON doesn't quite match your ResultSet class either. Your JSON is a map, not a list. Also, there's a field mismatch between "in" and "ins". This JSON is what would match your ResultSet class:
{{"ins":"mmm","loc":"1234"},{"ins":"mmm","loc":"1234"}}