I want to send a POST request but i want to add XML as string in the post rather adding JAXBObject. The reason is that i am writing some unit test. With JAXBObject, I am limited to provide only valid value in my jaxb generated object via XSD (i.e. valid ENUM Type).
Now i want to test my WS by inputting some random value for that input type so that i can test it.
If i do
ClientResponse clientResponse = service.post(ClientResponse.class, jaxbElement);
It works fine as expected. However I don't want to send the jaxbElement .. I wana send a custom XML say
When you call the following from a test case
ClientResponse response = builder.
accept(MediaType.APPLICATION_JSON).
type(MediaType.APPLICATION_XML).
entity(entityObj).
post(ClientResponse.class);
you can send anything in entity(entityObj)
You can also try SoapUI for REST Tesing
Related
I'm trying to use one api that in the response body we have this structure:
{"flag": false,
"codes":[
"a3f2b9ddf8886b04993632"]}
At Postman, and executing a curl, the response is exactly this one.
But when I use restTemplate.exchange(...) to return the response body,it's always returning for codes: [[object Object]]
UriComponentsBuilder builder = UriComponentsBuilder.fromUri(URL...); //cannot show partner's url here
header.add("Accept", MediaType.APPLICATION_JSON_VALUE);
header.add("Content-Type", MediaType.APPLICATION_JSON_VALUE);
ResponseEntity<String> resourceHttpEntity = restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
new HttpEntity<>(header), String.class); //header also has an authorization bearer token that is in another class
System.out.println(resourceHttpEntity.getBody());
Response body from this:
{"flag":false,"codes":["[object Object]"]}
I saw some examples that this occurs, but in Javascript, and we use JSON.stringfy to solve it.
But at Java we don't have this option. I don't know if is a miss-configuration or something.
Even I try to get this response body with the class model using String[], ArrayList for this property. Tried to convert in String.class, JSonNode.class, and it's returning this way.
I tried to use objectMapper to convert, and even test with HTTPURLConnection to confirm and it's happening the same thing. I have the same result.
Any suggestions?
If you need to print the content of a generic object in Json format you can print it as follow:
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
System.out.println(ow.writeValueAsString(object));
// Or better log.info(ow.writeValueAsString(object);
If you don't need to format your output you can call directly writeValueAsString on the objectMapper:
Method that can be used to serialize any Java value as a String
System.out.println(new ObjectMapper().writeValueAsString(object));
Updated answer after the update on the question.
It seems that the remote service that you are invoking is returning exactly the body that you showed in the updated answer.
Your code is treating the body as a simple string, so there is no manipulation on the client-side (your code). It means that is possible that for particular values the server-side (the web service that you are invoking) is performing some strange operation (probably a bean to json conversion) that will generate this output.
You have many ways to check it:
make the same call using postman
make the same call using curl
add a sniffer between your client and the server and use it to log the passing data
For the first two alternatives you have to be sure to use exactly the same data used by the java code. And execute them from the same machine (may be that a proxy can change the behaviour of the call).
We discover that the RestTemplate #Bean that we already have in code, was causing this issue. So I just instantiate a new RestTemplate from scratch, and the issue was resolved.
Thank you for your time.
Create Java class with below attributes and use as response entity type.
Public class Response{
boolean flag;
List<String> codes;
}
ResponseEntity<Response> resourceHttpEntity =
restTemplate.exchange(
builder.toUriString(),
HttpMethod.GET,
new HttpEntity<>(header), Response.class);
I have an angular project with a java backend.
the following is the scenario.
I create a DTO object in the Backend, and submit it to the frontend.
...
QuestionResponseDTO dto = new QuestionResponseDTO();
dto.setStart(ZonedDateTime.now());
dto.setEnd(ZonedDateTime.now());
dto.setDuration("X seconds");
dto.setResponse(new ActivityListResponseDTO(Arrays.asList("Cooking", "Eating")));
return dto;
}
in which the ActivityListResponseDTO just contains a List<String> activities.
Also note that ActivityListResponseDTO extends QuestionResponseBodyDTO.
In the frontend I send the request to the backend, and I receive the object back.
this is how the object looks like.
{"id":2,"responses":[{"id":0,"dto":{"start":"2021-06-16T09:08:28.142Z","end":"2021-06-16T09:08:28.142Z","duration":"X seconds",
"response":{
"activities":["Cooking","Eating"],
"typeName":"ActivityListResponseDTO",
"className":null},
"typeName":"QuestionResponseDTO",
"className":null}}]}
which means that the backend works fine.
The java classes I mentioned earlier have their corresponding classes in the Frontend with the exact same name. Idk what exactly happens to parse the response.
When I receive the object I check:
//angular
if (dto instanceof QuestionResponseDTO) {
console.log("this ran");
const responseBody = ((<QuestionResponseDTO>dto).response);
if(responseBody instanceof ActivityListResponseDTO) {
console.log("this ran 2");
// because backend only returns a string
const arr = (<ActivityListResponseDTO>responseBody)
.activities.map(s => ({stringContent: s}));
...
The responseBody per default has the Type QuestionResponseBodyDTO in the frontend as well. the ActivityListResponseDTO extends this in the frontend too, so it should work.
but for some reason the program doesn't go in the inner if statement, and "this ran 2" is never logged.
Is there something I am doing wrong?
The response received from the HTTP API will be a simple JSON Object.
For it to work correctly on frontend, you will have to map that object to its corresponding type on frontend.
You can use json-object-mapper library to achieve this.
Create a Typescript class named QuestionResponseDTO with all the nested object classes. I usually do this using json2ts which provides me interfaces and then I convert those interfaces to typescript classes.
Use json-object-mapper or use your own class constructors to initialize the properties
In your HTTP service, when you get the data, pipe that data to deserialize it to typescript object. http.get<QuestionResponseDTO>(url).pipe(map(data => ObjectMapper.deserialize(QuestionResponseDTO, data)));
Once this is done, you should be able to correctly use instanceof on any nested objects
i am trying to make a client for services exposed through REST.I have multiple number of classes extending a single class.
Now when i send the request and get a response,every time i need to type cast the response for specific class.i am trying to automate this process,can this be achieved at run time?
I am thinking of using generics and reflection but unable to move forward.what i exactly want to achieve is by just mentioning a unique string or say request,i must be able to get exact same response without type casting it with that particular response class.
By using generics i succeeded in reducing some code for typecasting,still i am not satisfied as i want to completely achieve it at run time.
RequestClass request=(RequestClass)getRequest(some attributes);
output=(Responseclass)response.getResult();
Here every time i need to mention the request and response classes,i don't want to do this.
can i do something where i can map the request and response classes to a key or a string and based on it the code will fetch the request and response class and perform the operation according to it(not sure about it).
please guide me in doing this,or any other way i can do the above mentioned thing.
Thanks in advance.
Consider using one of the many Java REST libraries. Our client uses the Jersey API to handle requests and responses to our Python based RESTful server.
Jersey uses a class called ClientResponse that stores the generic response data. you can use the getEntity method to return the response as a specific type.
Here is an excerpt of my code, which only deals with strings, but you can see how it could be extended:
ClientResponse response; //a Jersey class
String responseText;
WebResource odbc = resourceCollection.path("ODBC"); //another Jersey class
try {
//we send a POST and get a response stored as generic
response = odbc.type(media)
.accept(MediaType.APPLICATION_XML,MediaType.TEXT_PLAIN)
.post(ClientResponse.class, formdata);
//we pull out the response entity as a string
responseText = response.getEntity(String.class);
} catch (UniformInterfaceException e) {
write("<UniformInterfaceException>\n");
write(" Response type was not expected\n");
write("</UniformInterfaceException>\n");
return;
} catch (ClientHandlerException e) {
write("<Error>\n");
write(" Unable to connect or connection refused\n");
write("</Error>\n");
return;
public class DynamicCasting{
DynamicCasting e1=new DynamicCasting();
private Object obj=new Object();
DynamicCasting.doSomething(obj);
public static DynamicClass doSomething(DynamicClass dynClassObject){
return dynClassObject;
}
}
The obj will be type casted to DynamicClass in this example.
I know that GWT has a good RPC support. But for various purposes I need to build this on my own:
1.) How can I convert a Bean Object (on the Client Side) like;
class MyPerson {
String name;
String getName();
void setName(String name);
//..
}
with GWT into a JSON String? (Ideally only using libraries that come officially from GWT/Google).
2.) Secondly, how can I send this generated JSON String from the Client side to any Server also using any GWT Client Logik. (Ideally only using libraries that come officially from GWT/Google).
I have searched a lot, but the examples never show how to send data but only to receive JSON data.
Thank you very much!!!
Jens
There's a nifty class called AutoBeanFactory that GWT will create for you, no third-party libs required. See http://google-web-toolkit.googlecode.com/svn-history/r9219/javadoc/2.1/com/google/gwt/editor/client/AutoBeanFactory.html
Once you have your AutoBeanFactory, you can use it like this:
producing JSON from an object of type SimpleInterface
AutoBean<SimpleInterface> bean = beanFactory.create(SimpleInterface.class, simpleInterfaceInstance);
String requestData = AutoBeanCodex.encode(bean).getPayload();
useRequestBuilderToSendRequestWhereverYouWant(requestData);
parsing JSON from an object of type SimpleInterface
SimpleInterface simpleInterfaceInstance = AutoBeanCodex.decode(beanFactory, SimpleInterface.class, responseText).as();
You can use RequestBuilder to send these requests without GWT-RPC or the RF stuff.
I recommend you use RestyGWT it makes JSON rest services work just like GWT RPC services.
Take a look at GWT's AutoBean framework, which can be used to create and receive JSON payloads. The RequestBuilder type can be used to send HTTP requests to the server.
You have also another solution which is 3rd party solution, maybe a second place solution but it can be also the first place.
The 3rd party called GSON and it's a project open source on google code.
You can find it here.
I used it and it's very good and very simple.
Does anyone know of a way to get only POST parameters from an HttpServletRequest object?
IE, PHP has the $_POST superglobal and Perl's CGI.pm will only retrieve POST parameters if the HTTP method is POST (by default).
HttpServletRequest.getParameter(String) will include the GET URL parameters even if the HTTP method is POST.
From my understanding, there are no such things as POST parameters and GET parameters in HTTP, there are POST and GET methods. When a request is made using the POST method, parameters go within the message body. In case of a GET request, parameters go in the URL.
My first thought was that it was an implementation bug in your servlet container. But, since things are not always as you expect, java servlet specification (at least the 2.4 version) does not differentiate between the two kind of parameters. So, there is no way to obtain post or url parameters using the servlet API.
Surely you already have a plan B. But, just in case, I post two alternatives that came to my mind:
If you have access to the parameter name definition, you could use a prefix to differentiate between the two when you iterate the getParameterNames() result.
You could parse the URL creating an URL object and using getQuery() method to obtain just the parameters. Then, parse the parameters on the query string using some utility class such as ParameterParser in HttpClient library. And finally, subtract that names from the getParameterNames() result.
I guess one way might be to manually parse HttpServletRequest.getQueryString() and check that a parameter is not present in it.
A naive implementation (ignoring url-escaped key values) would go something like this (untested) :
public boolean isInQuery(HttpServletRequest request, String key) {
String query = request.getQueryString();
String[] nameValuePairs = query.split("&");
for(String nameValuePair: nameValuePairs) {
if(nameValuePair.startsWith(key + "=")) {
return true;
}
}
return false;
}
Couldn't you just get the parameters from the HttpServletRequest within doPost or doGet in a subclass of HttpServlet?
Anything you grab (via getParemeter) inside of doPost is a POST and anything inside of doGet is a GET.
I think you could do something with getMethod() available from the HttpServletRequest Interface.
Java doc 1.6
This is also available in 1.4 and 1.5.
I'm not sure if this would work, but you could try extracting the raw content of the POST body using request.getReader(). The container may remove that data before handing control to your application, though, and even if it didn't, you'd have to decode the parameter string yourself.
The question was answered in this related post:
Normaly you can GET and POST parameters in a servlet the same way:
request.getParameter("cmd");
But only if the POST data is encoded as key-value pairs of content
type: "application/x-www-form-urlencoded" like when you use a standard
HTML form.