Parsing multi-line, multi-column text response with jersey/apache REST client - java

I'm trying to hit a REST end-point that returns a multi-line, multi-column response, such as:
A1 B1 C1
A2 B2 C2
A3 B3 C3
...
...
I'm currently using jersey-client to hit this endpoint and trying to look for the neatest way to parse this response. Here, each line would represent a bean, say MyBean and each column on that would represent a property in that bean. The order of values in the response is always fixed.
I can get the response back as a long String, split it at line-feeds and tabs to get individual values.
However, I would like to know if there is a way where I can get the results as a List<String>, where each element in the List would represent a line of the response. I can then split it on \t to get individual values.
Here's what I've tried:
WebResource resource = client.resource(NETSPEAK_URL)
.type(MediaType.TEXT_PLAIN)
.get(new GenericType<List<String>>(){});
But this leads to the following exception:
A message body reader for Java class java.util.List,
and Java type java.util.List<java.lang.String>,
and MIME media type text/plain; charset=UTF-8 was not found
If I be even greedier, I would like to know if I can get the individual column values mapped to the properties of my bean, MyBean. I've considered creating a wrapper around MyBean, to have a list of MyBeans, but then how would I annotate it to assist parsing? That would have made sense for an xml/json response. But this is plain text.
Is it possible to somehow tell jersey-client about the parsing of this text/plain response? If this is achievable through Apache HTTP client, I'm ready to move.
Thanks

You may want to implement a class representing your list of beans, say class BeanList extends List<Bean>, and implement a MessageBodyReader<BeanList> (see http://jsr311.java.net/nonav/releases/1.1/javax/ws/rs/ext/MessageBodyReader.html) to teach jersey how to read a string as a BeanList.
Then you can use BeanList.class instead of List<String> as argument to the get call.

Related

Pojo Conversion with HibernateMapping & Jaxb

I have two Pojo classes, one for hibernate mapping and one for jaxb.
So I get a List<CarA> using Criteria.list() and I would like to transform it into a List<CarB> in order to send it back to my client as a SOAP message.
Would you have any idea how to do the conversion from CarA to CarB?
My list contains more than 100 elements and the construction gets expensive very fast.
I wish I didn't have to build a list from A to Z.
Thanks for your help
You can use model mapper library : https://www.baeldung.com/java-modelmapper
Example of what you can do:
List<Carb> lb = new ArrayList();
for (Cara a : la )
lb.add(mapper.map(a, Carb.class))

Consuming Rest API- Query Parameter - Passing Map<String, List<String>>. Special Characters gets added

We are a consumer of a Rest API, where we are passing query parameters. We are using Map<String, List>. But we call the API, our producer is getting some special characters for our values.
For ex-
List queryParamters = new ArrayList();
queryParameters.add("ABC");
final Map<String, List> finalMap = new HashMap<>();
finalMap.put("column", Collections.singletonList(queryParamters+""));
when we call our API, our producer gets
"GET /server-url/product?column=%5ABC%5D HTTP/1.1" but our expectation is to send them ABC not %5ABC%5D.
Can we enforce not to add special characters and our producer gets what we expect?
There's nothing wrong with the URI, it is just being encoded.
The %5B and %5D characters you are getting is because you are passing an ArrayList object as a query parameter. If your URI was not encoded, it would look like this:
GET /server-url/product?column=[ABC] HTTP/1.1
If the column parameter has just one value (as the example you gave), use a String object (not an ArrayList). The result would be like this:
GET /server-url/product?column=ABC HTTP/1.1
But if you really need to specify a list of values as URL parameters (and be able to receive them as a list in the backend side), I would recommend you to repeat the parameters, like this:
GET /server-url/product?column=ABC&column=BCD HTTP/1.1

Listing the parameters in a node using RESTassured library with Java

The webservice: http://services.groupkt.com/country/search?text=lands has 16 records returned from a GET request. In the records, there is a parameter called 'name'. So, there are 16 names and each name has a unique value (country). My intention is to list all the 16 values of the 'name'parameter using java and the RESTassured library. I tried this:
Response response = RestAssured.get("http://services.groupkt.com/country/search?text=lands").andReturn();
String json = response.getBody().asString();
JsonPath jp = new JsonPath(json);
List<String> ls = from(response).getList("RestResponse.result.name");// The 'from' text displays an error
An error was seen on the 'from' text and it says: The method from(String) in the type RestTest is not applicable for the arguments (Response). I am not sure how to rectify this. Is there a simple way to create a list of all the values of the 'name' parameter?
Try replacing from(response) to from(jp). That should take care of the error you are getting.
The Response class (which is what the get() method returns) also supports jsonPath, so you could also refactor it to something like this:
List names= get("http://services.groupkt.com/country/search?text=lands").jsonPath().getList("RestResponse.result.name");

How to convert string to MarketDataIncrementalRefresh in QUICKFIX in Java?

I am working on the Stock and Exchange Markets. I have a situation like : I need to take a string from the log and convert it to "Message" type Object. As per this link I have tried using all the three methods of the "MessageUtils" class in JAVA. But my String is being stripped to a Message class type object with unique tags. But as my string is "MarketDataIncrementalRefresh" type I want each every tag to be present in the Message.
For example : I am providing the following string to "MessageUtils.parse()" method.
8=FIX.4.2|9=00795|35=W|49=TT_PRICE|56=SAP0094X|34=2392|52=20170623-04:41:33.375|55=CL|48=00A0HR00CLZ|10455=CLQ7|167=FUT|207=CME|15=USD|262=MDRQ-751|200=201708|18210=1|387=12292|268=24|269=0|290=1|270=4290|271=33|269=0|290=2|270=4289|271=34|269=0|290=3|270=4288|271=40|269=0|290=4|270=4287|271=38|269=0|290=5|270=4286|271=46|269=0|290=6|270=4285|271=53|269=0|290=7|270=4284|271=46|269=0|290=8|270=4283|271=66|269=0|290=9|270=4282|271=48|269=0|290=10|270=4281|271=64|269=1|290=1|270=4291|271=21|269=1|290=2|270=4292|271=40|269=1|290=3|270=4293|271=48|269=1|290=4|270=4294|271=83|269=1|290=5|270=4295|271=62|269=1|290=6|270=4296|271=46|269=1|290=7|270=4297|271=34|269=1|290=8|270=4298|271=55|269=1|290=9|270=4299|271=31|269=1|290=10|270=4300|271=128|269=2|270=4291|271=1|269=4|270=4280|269=7|270=4292|269=8|270=4277|10=044|
But what I am getting is this:
8=FIX.4.2|9=192|35=W|34=2|49=TT_PRICE|52=20170622-14:16:23.685|56=SAP0094X|15=USD|48=00A0HR00GCZ|55=GC|167=FUT|200=201708|207=CME|262=MDRQ-21|268=25|269=0|270=12510|271=24|290=1|387=121890|10455=GCQ7|18210=1|10=036|
As you can observe only unique tags are present in the String. But I want each and every tag , no matter how many times it exists in the provided string.
Please can anyone help me doing this in JAVA. It will be really appreciable.
Below is the code I am using for converting :
MessageUtils mu = new MessageUtils();
Session session = Session.lookupSession(sessionID);
Message msg = MessageUtils.parse(new DefaultMessageFactory(), null, str);
// Message msg = new Message(str, false); //This can also be used for converting
System.out.println(msg.toString());
The other thread says:
MessageUtils.parse(MessageFactory messageFactory, DataDictionary dataDictionary, java.lang.String messageString)
And your code says:
Message msg = MessageUtils.parse(new DefaultMessageFactory(), null, str);
So you need to fix your data dictionary and pass it to the parse method instead of passing 'null'
I think the problem is as follows. There's a repeating group that starts with tag 286 (NoMDEntries). The order of fields in a repeating group should be strict, i.e. the same order as the definition of the repeating group. See Market Data - Snapshot/Full Refresh or the data dictionnary supplied by QuickFIX/J (FIX42.xml).
The 268 tag should be followed by 269 and then 270. I am seeing in your message string: |268=24|269=0|290=1|270=4290| which is the incorrect order of tags. That is probably the reason why the message is truncated by MessageUtils.parse.
As a test you could try to manually correct the order in the string and try parsing that to see if that gives the correct message.

How to write a http get request when a key's value is an array?

I have written a java servlet to deal with http get request.I know ,the common format of get request is like this:http://IP_ADDRESS:8080/test?name="jack"&value="shit.
But now ,I have a list of values to transfer,such as an user id list[1,2,3,4].So ,my question is ,how should I write my http get request to express this?And in java servets doGet(),can I use request.getParameterValues to get such an array?
if you are using GET method your url should be looking like that :
http://IP_ADDRESS:8080/test?list=1&list=2&list=3
for retrieving it:
String[] arrlist=request.getParameterValues('list');
your array will be filled with separated values:
//["1","2","3"]
UPDATE : if to write it list[] or list?
when you retrieving your list parameters it wouldn't be parsed as array but as a series of String which will be grouped later on into an array.
Which means even if you write it list[]=1&list[]=2&list[]=3, list[=1&list[=2&list[=3, list*=1&list*=2&list*=3 or list=1&list=2&list=3 it would always be giving you the same answer whether you retrieve it as
request.getParameterValues('list[]') //["1","2","3"]
request.getParameterValues('list[') //["1","2","3"]
request.getParameterValues('list*') //["1","2","3"]
request.getParameterValues('list') //["1","2","3"]
While ,the http request format should be like this:localhost:8080/test?list[]=1&list[]=2&list[]=3
Maybe too simple, but what about repeat parameters name?
http://IP_ADDRESS:8080/test?userId=1&userId=2&userId=3

Categories