I am consuming a third party webservice using AXIS2 stub. The primary method which I use works FINE and has below signature:
boolean isValidUser(username, password);
The webservice is supposed to return a String (token) in the response headers as cookie :- WSToken
But I cannot find ANY method to extract the headers and cookies from the response. In fact there is no HTTPResponse object to fetch the cookies !.
I have tried this code:
MessageContext context = stub._getServiceClient().getLastOperationContext().getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
Object response = context.getProperty("response");
But it returns a null value as there is no such property in the context. The context has below properties:
transport.http.statusCode
CHARACTER_SET_ENCODING
TRANSPORT_HEADERS
org.apache.axiom.om.util.DetachableInputStream
messageType
ContentType
TRANSPORT_IN
How can I get the cookie called 'WSToken' from the response using the stub ?
The TRANSPORT_HEADERS property should give you the HTTP headers you got. You can then look for Set-Cookie headers.
Related
I'm new to the java rest CXF client. I will make various requests to a remote server, but first I need to create a Ticket Granting Ticket (TGT). I looked through various sources but I could not find a solution. The server requests that I will create a TGT are as follows:
Content-Type: text as parameter, application / x-www-form-urlencoded as value
username
password
I create TGT when I make this request with the example URL like below using Postman. (URL is example). But in the code below, I'm sending the request, but the response is null. Could you help me with the solution?
The example URL that I make a request with POST method using Postman: https://test.service.com/v1/tickets?format=text&username=user&password=pass
List<Object> providers = new ArrayList<Object>();
providers.add(new JacksonJsonProvider());
WebClient client = WebClient.create("https://test.service.com/v1/tickets?format=text&username=user&password=pass", providers);
Response response = client.getResponse();
You need to do a POST, yet you did not specify what your payload looks like?
Your RequestDTO and ResponseDTO have to have getters/setters.
An example of using JAX-RS 2.0 Client.
Client client = ClientBuilder.newBuilder().register(new JacksonJsonProvider()).build();
WebTarget target = client.target("https://test.service.com/v1/tickets");
target.queryParam("format", "text");
target.queryParam("username", "username");
target.queryParam("password", "password");
Response response = target.request().accept(MediaType.APPLICATION_FORM_URLENCODED).post(Entity.entity(yourPostDTO,
MediaType.APPLICATION_JSON));
YourResponseDTO responseDTO = response.readEntity(YourResponseDTO.class);
int status = response.getStatus();
Also something else that can help is if you copy the POST request from POSTMAN as cURL request. It might help to see the differences between your request and POSTMAN. Perhaps extra/different headers are added by postman?
Documentation: https://cxf.apache.org/docs/jax-rs-client-api.html#JAX-RSClientAPI-JAX-RS2.0andCXFspecificAPI
Similar Stackoverflow: Is there a way to configure the ClientBuilder POST request that would enable it to receive both a return code AND a JSON object?
So I've been trying to create token based authentication in Java EE lately and I tried to sent token via HTTP Header, but failed so many times.
My question : If I have for example #POST response method and I set header via return response statement
return Response.ok(entity).header(HttpHeader.AUTHORIZATION, authToken).build()
Then I invoke other method that was binded to ContainerRequestFilter and in this filter I try to access header via ContainerRequestContext.getHeaderString(HttpHeaders.AUTHORIZATION) then should it work?
Will I get the value from that header that was set in response method? If not then what should I do to get value of this header in filter method?
The Authorization header(or any other header) must be included by the client in each request
Your client should get the token from the server response, keep it in a secure storage and set the Authorization header when performs a request. Then, with RequestContextFilter your server will be able to recover it
I'm learning how to build RESTful web services using Spring 4, and one thing I'm not clear on is in #RequestMapping. I've seen examples where one uses headers = "Accept=application/xml" and other examples using consumes (or produces) = "application/xml".
For instance, in my own #RestController class, I have this function...
// POST
#RequestMapping(method = RequestMethod.POST, headers = "Accept=application/xml")
public User create(#RequestBody User user) {
LOG.info("User = " + user.toString());
return userService.create(user);
}
What is the difference between using headers = "Accept=application/xml" vs. using consumes = "application/xml"? Or even using headers = "content-type=application/xml"?
Could someone explain the differences between headers and consumes/produces, and when each is used?
SHORT ANSWER
In the example you have above, using headers = "Accept=application/xml" or produces = "application/xml" will both respond to the client the same way i.e. send a response to the client with XML representation.
LONGER ANSWER
i. Headers
For RESTful web services, the client (e.g. your browser) sends a request (e.g. GET, POST, etc.) to a server, and the server will send a response back. This is an HTTP Transaction. Both the request and response have HTTP header fields ("headers"), which define the operating parameters of an HTTP transaction (I will refer to the headers for client request as "request headers", and these differ from headers from server response "response headers").
As part of the request your browser sends to server, there are different request headers and some examples include Accept, Connection, Content-Length etc. and each of these headers have their own function (see a full list of headers here: https://en.wikipedia.org/wiki/List_of_HTTP_header_fields).
Using your code example, if a client does a POST request, Spring will check the request header(s) and if it finds a header Accept with a value of application/xml, it will map the request to the create method you have above (and in your case the server will return an XML response representation to the client).
Let me modify the headers element in the code you provided:
#RequestMapping(method = RequestMethod.POST, headers = "Connection=keep-alive")
public User create(#RequestBody User user) {
...
}
Notice the headers element now has a value of Connection=keep-alive. If a client does a POST request, Spring will check the request header(s) and if it finds a header Connection with a value of keep-alive, it will map that client request to the create method above.
ii. Produces and Consumes
If you used produces="application/xml" for the create method, this means a client request is only mapped to the create method if the client's Accept header matches application/xml. This essentially is the client saying, "Hey server, I prefer to accept your response in XML representation, so send your response to me in XML". Effectively, the produces="application/xml" is also the server saying, "Hey client, I can only produce responses for you in XML representation, so I will send you that format".
Link to Spring documentation reference.
If you used consumes="application/xml" for the create method, this means a client request is only mapped to the create method if the client's Content-Type header matches application/xml (the Content-Type request header describes the representation the client request is coming in). This essentially is the server saying, "Hey client, I can only consume requests in XML representation, so send that format to me".
SUMMARY
The headers element within the #RequestMapping annotation can take different request headers (Accept, Connection, Cache-Control etc.), but the produces element is only concerned with the Accept request header and the consumes element is only concerned with the Content-Type request header.
As the javadoc of HeadersRequestCondition (which handles the value provided in the headers attribute of a #RequestMapping annotation) states
Expressions passed to the constructor with header names 'Accept' or
'Content-Type' are ignored. See ConsumesRequestCondition and
ProducesRequestCondition for those.
So don't use those headers in headers. Use the produces and consumes attributes for Accept and Content-Type.
As to how to use them, the documentation gives examples: for consumes and for produces.
I'm using httpclient 4.2.5 to make http requests which have to handle redirects as well.
Here is a little example to understand the context:
A sends http request (using httpclient 4.2.5) to B
B sends 302 redirect (containing url to C) back to A
A follows redirect to C
C retrieves request URL and do some work with it
If C parses the request URL by request.getRequestURL() (HttpServlet API) it contains e.g. host and port of the original request from step 1, which is wrong.
The problem exists in step 2, where httpclient handles the redirect. It just copies all headers from the original request (step 1) to the current request (step 3). I already had a look at the responsible code, via grepcode:
DefaultRequestDirector
HttpUriRequest redirect = redirectStrategy.getRedirect(request, response, context);
HttpRequest orig = request.getOriginal();
redirect.setHeaders(orig.getAllHeaders());
I don't really understand why all headers of the original request are copied to the current request.
E.g. using cURL for a simple test is doing it as expected, C would receive the correct host and port.
Implementing my own redirect strategy does not help because the original headers are copied after it.
I had the same problem when trying to download files from bitbucket's download section using HttpClient. After the first request bitbucket sends a redirect to CDN which then complains if the Authorization header is set.
I worked around it by changing DefaultRedirectStrategy.getRedirect() method to return redirect object which does not allow Authorization headers to be set.
I work with Scala so here is the code:
val http = new DefaultHttpClient()
http.setRedirectStrategy(new DefaultRedirectStrategy() {
override def getRedirect(
request: HttpRequest, response: HttpResponse, context: HttpContext
): HttpRequestBase = {
val uri: URI = getLocationURI(request, response, context)
val method: String = request.getRequestLine.getMethod
if (method.equalsIgnoreCase(HttpHead.METHOD_NAME)) {
new HttpHead(uri) {
override def setHeaders(headers: Array[Header]) {
super.setHeaders(headers.filterNot(_.getName == "Authorization"))
}
}
}
else {
new HttpGet(uri) {
override def setHeaders(headers: Array[Header]) {
super.setHeaders(headers.filterNot(_.getName == "Authorization"))
}
}
}
}
})
Please note orig.getAllHeaders() returns an array of headers explicitly added to the message by the caller. The code from DefaultRequestDirector posted above does not copy request headers automatically generated by HttpClient such as Host, Content-Length, Transfer-Encoding and so on.
You post a wire log of the session exhibiting the problem I may be able to tell why redirects do not work as expected.
I'm using rest assured to test API's.am facing issues in making a request with below configuartion using rest assured.
Request type : POST
Headers:
Content-Type :text/plain
api-key : 12263783493
user : emailid
Cookie : changesetId=4604
Body type-: raw : Text
applyToAllMapsOnController=false&applyToAllMaps=false (this is the text in the request body to be passed)
Below is what i tried but I'm getting 400 bad request
Response response= (Response) RestAssured.given().
header("Content-Type", "text/plain").
header("charset","utf-8").
header("api-key","dV43+Rbr9uncPd&;ydiQx]uUFX2").
header("user","P2899445,Bhavan Ramakrishnappa").
cookie("cookie", "changesetId="+Number).
body("applyToAllMapsOnController=false&applyToAllMaps=false").
when().
post(servicelevel);
can someone help me how to pass cookie in header and raw text in the body.
You can do multiple things to Debug the issue.
Try passing ("cookie", "changesetId="+Number) as a header
use when().log().all so that you can see what is the Request being Sent.