How to make Resteasy understand map-style HTTP parameters? - jax-rs

I have a problem with making Resteasy understand this syntax in the context of #FormParam and #QueryParam:
customer[name]=John
This doesn't work.
This does work:
customer.name=John
Is there a way to make Resteasy accept the first parameter style?
UPDATED:
Apologies, my question was very imprecise so here is the updated version:
For example:
class Customer {
public #Valid #Form(prefix="address") Address address;
}
class Address {
public #FormParam("line1") String line1;
}
Customer is the top-level POJO used by resteasy to receive parameters from the client. This is how the request looks like:
name=John
address[line1]=Street 123
This does not work. But, this DOES work:
name=John
address.line1=Street 123
Sorry for the mixup.

Related

How to send custom http response code back from spring cloud functions in gcp?

We are using the new gcp cloud functions using Java / Kotlin.
As in the current reference implementations, we are returning org.springframework.messaging.support.GenericMessage objects.
So our code looks like this (Kotlin):
fun generatePdfInBase64(message: Message<Map<String, Any>>): Message<*> {
val document = process(message)
val encoded = Base64.getEncoder().encodeToString(document.document)
return GenericMessage(encoded)
}
We were not able to find any way to include a custom http response code to our message, e.g. 201 or something. The function only responds 200 in case of no exception or 500.
Does someone know of a way to do this?
Best wishes
Andy
As it is mentioned at the official documentation, the HttpResponse class has a method called setStatusCode where you are able to set the number of the status as your convenience
For example:
switch (request.getMethod()) {
case "GET":
response.setStatusCode(HttpURLConnection.HTTP_OK);
writer.write("Hello world!");
break;
On the other hand the constructor of the GenericMessage receives as parameter a payload, therefore I think you can create a string with a json format and use the constructor for create your GenericMessage instance with the status response you need.
If you want to know more about the statuds codes take a look at this document.

how to see actual body sent from restassured

I have created a jax-rs rest api and tested it with rest-assured. All tests are green. Now I am trying to create an html/js front end for it.
My problem is I do not know how my json objects should look like to be accepted by my rest api. Thanks to restassured/jax-rs I never handled request strings. I fill in objects and I get objects, (un)marshaling (json) is invisible.
Is there any way I can see (debug) what strings are created by rest-assured/java and sent over the "wire"?
If you want to log the request body you can do:
given().log().body(). ..
Or if you want to log the response body you can do:
.. .then().log().body(). ..
See documentation on logging for more details.
I'm not a RestAssured used, so I can't answer your question directly, but here are some ideas that may help you out.
I don't know what serializer RestAssured uses under the hood, but Resteasy on Wildfly uses Jackson by default. I would get familiar with this library. For less trivial application, you may need to dig into its APIs directly to get your desired results. Here is it's documentation. For your particular case you can do something as simple as
ObjectMapper mapper = new ObjectMapper();
String jsonString = mapper.writeValueAsString(yourObject);
System.out.println(jsonString);
This will print out the POJO in JSON format, based on your getters in the class. This is at the most basic level. If you don't already have Jackson as a dependency, you can add
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.0</version>
</dependency>
A really good friend (tool) to have is cURL. It's a command line tool that allows you to make REST/HTTP (other protocols also) requests. Though for this particular case it wouldn't help, you could send a GET request to one your resources that serves up the same type that you accepted in your POST. That way, you can see the resulting JSON. This may be a little much at this point, but I would definitely look into this tool if you're going to be doing a lot of REST development.
You might also want to check out a Browser tool like [Postman for Chrome]
You should really get familiar with JSON format. Once you get familiar with it, and you start working with JSON framework, you'll notice that at a basic level, they all work similarly.
Java Object == JSON Object ( {} )
Java Collection/Array == JSON Array ( [] )
Java fields/properties == JSON keys
Getters are used for they keys and their values (for serialization)
Setters are used for deserialization
So for example you have this class
public class Person {
String name;
List<Person> friends;
public String getName() { return name; }
public void setName(String name) { return name; }
// Getter and Setter for friends
}
An instance of Person would produce the following JSON
{
"name" : "Peeskillet",
"friends": [
{
"name": "Lebron James"
},
{
"name": "Steph Curry"
}
]
}
It's actually pretty simple once you get the hang of it.
Oh and another thing you can do is add a logging filter on the server side as mentioned here.
As far as working with Javascript, there is a JSON.stringify(javascriptObject) that will serialize your Javacript objects to JSON strings. So generally, you can model your Javascript object like your Java objects.
Hope this helped.
In RestAssured just use this:
String body = resp.asString();
System.out.println(body);
Try this for Request Body
RequestSpecification httpRequest = RestAssured.given().urlEncodingEnabled(true);
..
..
..
System.out.println(" Body ==> "+ httpRequest.log().body());
And for response body:
System.out.println("Res Body ===>"+ response.getBody().prettyPrint());

JAX-RS and #Produces ability to match on regex

I'm writing a Restful web service that requires versioning. The way I want to go about this is using the Media type in the header to do this.
Example of request:
Accept: application/vnd.test.books.v1+xml
I would have an endpoint of
#GET
#Path("/test")
#Produces("application/vnd.test.books.v1+xml")
public Response getA(){
...
}
I would also like to have regex matching all versions. So I want to match on anything with Accept header of application/vnd.test.books.*+xml . So any version in my case. I tried something like the following with no lucks.
#GET
#Path("/test")
#Produces("application/vnd.test.books*+xml")
public Response getB(){
...
}
What I want is the ability to down the line have endpoint for v1 specifically then anything above v2 I want a different end point.
You must explicitly list all the MIME types a method #Produces:
#Produces(value = {"application/vnd.test.books.v2+xml",
"application/vnd.test.books.v3+xml",
"application/vnd.test.books.v4+xml"})

Custom Collection null when passed through WCF Service

We have some custom collections such as this:
[Serializable]
public class OccupationCollection : Collection<Occupation>
{
}
We use these in objects like the following:
private OccupationCollection _occupations;
public OccupationCollection CurrentOccupations
{
get
{
if (this._occupations == null)
return new OccupationCollection();
else
return _occupations;
}
}
Now we are making a call to a WCF service, passing objects that contain these type of lists. The lists always end up being null in the service.
I'm pretty sure this has somthing to do with serialization or something like that.
What would the simplest solution that would require minimal changes to the existing objects to get this to work?
Have you hosted your service over HTTP?
If yes, can you use fiddler to check the HTTP traffic and confirm whether serialized version of the parameter is being sent across the wire? If yes, there can be a parameter mismatch in contract between server and client.
Also is the object holding OccupationCollection decorated with Serializable/DataContract attribute? If you have DataContract attribute, ensure that the properties that need to be serialized are marked with Datamember attribute.
More details out here..
http://blog.functionalfun.net/2009/09/if-your-wcf-service-is-unexpectedly.html

Silverlight enabled WCF Service and Entity Framework 504 issue

I'm building a Silverlight MVVM template and and am getting stuck with the WCF Service returning and Entity Object.
Here's what I did:
Using Entity Framework on the server side
Created a small test database with a couple of tables.
Created a WCF Service on the server side
I then created a small test method returning an integer.
On my client side, I added a service reference and I receive the integer result in my completed method successfully
then changed my test service method to return a "Person" object (which is an Entity from Entity Framework)
updated my service reference and then it doesn't work!
I then the return type to any basic CLR Type and it works again
I checked Fiddler and I get the following 504 error in my service response:
HTTP/1.1 504 Fiddler - Receive Failure
Content-Type: text/html; charset=UTF-8
Connection: close
Timestamp: 08:56:23.783
[Fiddler] ReadResponse() failed: The server did not return a response for this request.
After trying to figure this out, I came across WCF Trace Logging and found this error:
There was an error while trying to serialize parameter :BasicResult. The InnerException message was 'Type 'MVVMProject.Web.DataSource.Person' with data contract name 'Person:http://schemas.datacontract.org/2004/07/MVVMProject.Web.DataSource' is not expected. Consider using a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.'. Please see InnerException for more details.
I don't understand why this is so difficult? Must I set some property on my Entity to make it serializable? If I look at the Entity Framework's designer.cs file, I see a Serializable attribute on the Entity. Surely this means I can pass this via the WCF Service??? I don't understand this error, unfortunately...
Is it even possible to use Entity Framework with WCF Service?
Any help would be greatly appreciated.
I had same problem, it seams that the DataContractSerializer has a problem with the navigation properties of ef objects.
In my test project, I'm using the northwind database. I wanted to test the CodeFirst approach with the recommended DbContext.
The provided navigation properties are virtual and they are loading on demand, but the ef just return with the first level of the entity on navigation properties is filled.
On serializing the entity object the DataContractSerializer failed because the entity object is no longer bound to the DbContext and the serialization of the navigation properties failed.
This is happen when I try to consume a NW Employee object over my wcf service.
My soultion is to copy all data in a new object with the data contract attributes!
the service call:
public IEnumerable<EmployeeWcf> GetAll()
{
IEnumerable<EmployeeWcf> result = null;
result = from e in context.Employees.OrderBy( e => e.LastName )
select new EmployeeWcf
{
EmployeeId = e.EmployeeID,
Firstname = e.FirstName,
Lastname = e.LastName
};
return result;
}
the class:
[DataContract]
public class EmployeeWcf
{
[DataMember]
public int EmployeeId { get; set; }
[DataMember]
public string Firstname { get; set; }
[DataMember]
public string Lastname { get; set; }
}
This work but it seems to me that this is not a perfect solution.
I hope this helps you.