Bad Request response when passing a JSON in process variables - flowable - json

I'm using flowable and try to pass a JSON as body, but it's seen as malformed when processing the request (or so I think since the error is Bad Request). Basically I'm passing some parameters this way:
#PostMapping(path = PathConstants.START_ACTION)
public ResponseEntity<BaseResponse<ProcessInstance>> start(#PathVariable String processDefinitionId,
#RequestBody(required = false) Map<String, Object> params)
The params are set using postman, this way:
{
"body": {
"email":"testmail#test",
"password":"password"
}
}
The process starts and the POST call is made, but Bad Request is given back. I've tried printing the variables of the process after this call and this is what I have:
body={email=testmail#test, password=password}
So I've tried passing this instead:
{
"body": "{ \"email\":\"testmail#test\", \"password\":\"password\"}"
}
And when printing the variables I have:
body={"email":"testmail#test", "password":"password"}
but still it's a bad request. What is wrong with this JSON?

If you want to pass a variable that is a JSON then you would need to make sure that body is type JsonNode from Jackson.
Looking at your request signature Map<String, Object>, Jackson would contain a map of maps.
I don't know what you are trying to do. However, I would highly advise you to work with predefined parameters in your REST API. If you need something generic you can use the REST API of Flowable to do what you want to do.

Related

Camel binding mode for JSON not working, cant unmarshal it to POJO

I'm trying to send message from rest API to new route, and even thou I receive request in JSON format on my REST API and binding is set to JSON, when I forward it to new route it will be shown as InputStream and I will have to marshal it to JSON in order to use it.
I already tried using streamCaching and other components in RestConfiguration (consumes, produces, type, dataType). Also i'm using all dependencies in POM.
public void configure() {
restConfiguration().component("servlet")
.bindingMode(RestBindingMode.json)
.skipBindingOnErrorCode(false);
rest("/resttest")
.patch("/t1")
.id("t1")
.description("t1")
.consumes("application/json")
.produces("application/json")
.param()
.name("body")
.type(RestParamType.body)
.dataType("json")
.required(true)
.endParam()
.to("direct:test2");
This route is in other class:
from("direct:test2").id("test2")
.marshal().json(JsonLibrary.Jackson,SomePOJO.class)
.unmarshal().json(JsonLibrary.Jackson, SomePOJO.class)
.choice()
.when(simple("${body.getStatus()} =~ 'Closed'"))
.....
I was expecting to get JSON message on test2 route, and somehow I get InputStream, so i have to do marshaling first. Anybody know how I can make REST API forward me to route message in JSON format, not as stream?
Try:
.convertBodyTo(String.class)
before your unmarshal.
I was having the same issue, and I had to apply the marshal method for incoming values and unmarshal method for response.
This was the response in postman:
And I was using this code:
rest(service.service)
.description(ContentCategory.api("Service Test"))
.post("/product/{productType}/{enterpriseId}")
.description("service for saving a product")
.consumes(MediaType.APPLICATION_JSON)
.type(Product.class)
.bindingMode(RestBindingMode.json)
.produces(MediaType.APPLICATION_JSON)
.outType(String.class)
.route()
.bean("productService", "saveProduct")
.marshal()
.json(JsonLibrary.Jackson)
.setHeader(Exchange.CONTENT_TYPE, constant(MediaType.APPLICATION_JSON))
.endRest();
I just added the unmarshall method after realizing that I was receiving an InputStream
rest(service.service)
.description(ContentCategory.api("Service Test"))
.post("/product/{productType}/{enterpriseId}")
.description("service for saving a product")
.consumes(MediaType.APPLICATION_JSON)
.type(Product.class)
.bindingMode(RestBindingMode.json)
.produces(MediaType.APPLICATION_JSON)
.outType(String.class)
.route()
.bean("productService", "saveProduct")
.marshal()
.json(JsonLibrary.Jackson)
.unmarshal()
.json(JsonLibrary.Jackson)
.setHeader(Exchange.CONTENT_TYPE, constant(MediaType.APPLICATION_JSON))
.endRest();
In fact, I just added this two lines
.unmarshal()
.json(JsonLibrary.Jackson)
And it starts working:
It think is probably you need to use the unmarshal method for the resttest service.

Call API using Refit and deserialize to dynamic

I'm calling a REST service using Refit and I want to deserialize the JSON that is returned as a dynamic type.
I tried defining the interface as
[Get("/foo")]
Task<dynamic> GetFoo();
but the call times out.
I know I can deserialize to a dynamic like this
var mockString = "{ title: { name: 'fred', book: 'job'} }";
dynamic d = JsonConvert.DeserializeObject(mockString);
but I can't figure out what to pass to Refit to get it to do the same.
Another option would be to get Refit to pass the raw JSON back so I can deserialize it myself but I can't see a way to do that either.
Any ideas?
You can define your interface to return a string and get the raw JSON that way:
[Get("/foo")]
Task<string> GetFoo();
As described here:
https://github.com/paulcbetts/refit#retrieving-the-response
Refit uses JSON.NET under the hood, so any deserialization that works with that will work with Refit, including dynamic. The interface you have described is exactly right.
Here's a real working example:
public interface IHttpBinApi
{
[Get("/ip")]
Task<dynamic> GetIp();
}
var value = await RestService.For<IHttpBinApi>("http://httpbin.org").GetIp();
If you are using iOS and Refit 4+, you might be seeing this bug: https://github.com/paulcbetts/refit/issues/359
As Steven Thewissen has stated, you can use Task<string> as your return type (or Task<HttpResponseMessage>, or even Task<HttpContent>) to receive the raw response and deserialize yourself, but you shouldn't have to -- the whole point of Refit is that it's supposed to save you that hassle.

How can I define a ReST endpoint that allows json input and maps it to a JsonSlurper

I want to write an API ReST endpoint, using Spring 4.0 and Groovy, such that the #RequestBody parameter can be any generic JSON input, and it will be mapped to a Groovy JsonSlurper so that I can simply access the data via the slurper.
The benefit here being that I can send various JSON documents to my endpoint without having to define a DTO object for every format that I might send.
Currently my method looks like this (and works):
#RequestMapping(value = "/{id}", method = RequestMethod.PUT, consumes = MediaType.APPLICATION_JSON_VALUE)
ResponseEntity<String> putTest(#RequestBody ExampleDTO dto) {
def json = new groovy.json.JsonBuilder()
json(
id: dto.id,
name: dto.name
);
return new ResponseEntity(json.content, HttpStatus.OK);
}
But what I want, is to get rid of the "ExampleDTO" object, and just have any JSON that is passed in get mapped straight into a JsonSlurper, or something that I can input into a JsonSlurper, so that I can access the fields of the input object like so:
def json = new JsonSlurper().parseText(input);
String exampleName = json.name;
I initially thought I could just accept a String instead of ExampleDTO, and then slurp the String, but then I have been running into a plethora of issues in my AngularJS client, trying to send my JSON objects as strings to the API endpoint. I'm met with an annoying need to escape all of the double quotes and surround the entire JSON string with double quotes. Then I run into issues if any of my data has quotes or various special characters in it. It just doesn't seem like a clean or reliable solution.
I open to anything that will cleanly translate my AngularJS JSON objects into valid Strings, or anything I can do in the ReST method that will allow JSON input without mapping it to a specific object.
Thanks in advance!
Tonya

Netty HTTPRequest doesn't captured posted JSOn

I am attempting to build a REST service using Netty on the backend. I need to be able to post raw JSON to the service outside of any key/value parameters. Content-type=applicaiton/json not form multi-part.
I am able to get the initial part of the service to receive the request, but when I cast the MessageEvent content to HTTPRequest, it no longer has any posed data associated with it. That leaves me with no ability to get the JSON data back.
In order to access the posted JSON, do I need to use a different process for extracting the data from the MessageEvent?
Here is the snippet in question.
#Override
public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
System.out.println("The message was received");
HttpRequest request = (HttpRequest) e.getMessage();
if (request.getMethod() != POST) {
sendError(ctx, METHOD_NOT_ALLOWED);
return;
}
// Validate that we have the correct URI and if so, then parse the incoming data.
final String path = sanitizeUri(request.getUri());
decoder = new HttpPostRequestDecoder(request);
System.out.println("We have the decoder for the request");
List<InterfaceHttpData> datas = decoder.getBodyHttpDatas();
for (InterfaceHttpData data : datas){
System.out.println(data.toString());
}
What am I missing that it causing this? Do I need to use the ChunkedWrite portion? I am a noob to Netty so forgive me if this is basic. I found lots of other questions about posting raw JSON to other URL's from inside Netty, but nothing about receiving it.
I've only used HttpPostRequestDecoder to read application/x-www-form-urlencoded or mime data.
Try just reading the data directly form the request as per the snoop example.
ChannelBuffer content = request.getContent();
if (content.readable()) {
String json = content.toString(CharsetUtil.UTF_8);
}

WebClient.DownLoadString is adding \" infront of my JSON data elements.How to parse it as normal JSON without \"?

I am trying to access a REST Service in my MVC application.I am calling getJSON method to get the data from a controller which internally calls the REST service which returns data in json format.But I am getting the a lot of "\ in my output of DownLoadString method and my return Json is not returning proper JSON data and hence my client side script is not able to access the JSON properties.
My Script in my view is
$.getJSON("#Url.Action("GetManufacturers", "Home")",function(data){
console.debug("Status is : "+data.Status)
});
My Action method looks like this
public ActionResult GetManufacturers()
{
string restURL ="http://mytestserver/myapi/Manufacturers";
using (var client = new WebClient())
{
var data = client.DownloadString(restURL);
//data variable gets "\" everywhere
return Json(data,JsonRequestBehavior.AllowGet);
}
}
I used visual studio breakpoints in my action method and i am seeing a lot of \"
And i checked what is coming out to my getJSON callback and the JSON tab is empty.
But my response tab has content like this
I belive if there is no \", i would be able to parse it nicely.
I used fiddler to see whether i am getting correct (JSON format) data from my REST service and it seems fine.
Can anyone help me to tackle this ? I would like to return proper JSON from my action method. Sometime i may want to read the json properties in the C# code itself. I saw some example of doing it with DataContractJsonSerializer. But that needs a concrete type to be converted to. I don't want to do that. because other clients would also access my RESTService and how will expect them to write a fake entity for this ?
You need to return the data as is:
public ActionResult GetManufacturers()
{
string restURL ="http://mytestserver/myapi/Manufacturers";
using (var client = new WebClient())
{
var data = client.DownloadString(restURL);
return Content(data, "application/json");
}
}