I am trying to create a simple REST web-server. The actual URL looks like this
http://localhost:8080/Server/files/file?id=34?firstname=alex?lastname=ozouf?age=33?firstname=kevin?lastname=gerfild?age=27
The first ID is the ID of the requested file,the number of person in the parameter is not know in advance. I want to group this person in a collection/map.
It's not mandatory for the URL to be structured in this way. I could also use this URL if it could make it easier
http://localhost:8080/Server/files/file?id=34?firstname1=alex?lastname1=ozouf?age1=33?firstname2=kevin?lastname2=gerfild?age2=27
I tried to adapt these codes but as a newbie it I got really confused.
This is my code
System.out.println(query);
final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>();
final String[] pairs = query.split("&");
for (String pair : pairs) {
final int idx = pair.indexOf("=");
final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair;
if (!query_pairs.containsKey(key)) {
query_pairs.put(key, new LinkedList<String>());
}
final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null;
query_pairs.get(key).add(value);
System.out.println(query_pairs);
And this is the output I got
{id=[23?firstname1=alex]}
{id=[23?firstname1=alex], lastname1=[ozouf]}
{id=[23?firstname1=alex], lastname1=[ozouf], age1=[23?firstname=kevin]}
{id=[23?firstname1=alex], lastname1=[ozouf], age1=[23?firstname=kevin], lastname=[gefild?age=22]}
You have the wrong query string "&" is the parameter separator.
http://localhost:8080/Server/files/file?id=34&firstname=alex&lastname=ozouf&age=33&firstname=kevin&lastname=gerfild&age=27
Also I see that you are trying to have two records at the same time in the URL that's impossible to have to objects records in the query string. For this use the POST method and it body.
Related
I'm trying to parse Json in VBA.
I'm collecting data from an API that returns a json format in a string.
I use JsonConverter to parse my string.
Now when i want to search on it, i got an error 13 incompatibility type.
See my Java API below :
#GetMapping("/rest/collectData/excel/exportAll")
public HashMap<Object, Object> collectAll(){
HashMap<Object, Object> result = new HashMap<>();
String sql = "SELECT affair_code AS codeAffair, name, amount, end_date AS state FROM service_record WHERE affair_code IS NOT NULL AND affair_code != ''";
List<Map<String, Object>> allServiceRecords = jdbcTemplate.queryForList(sql);
if(allServiceRecords != null && allServiceRecords.size() >0){
result.put("result", true);
for(Map<String, Object> serviceRecord : allServiceRecords){
HashMap<Object, Object> details = new HashMap<>();
if(result.containsKey(serviceRecord.get("codeAffair"))){
details.put("alone", false);
details.put("message", "Plusieurs prestations ont été trouvées.");
} else {
details.put("alone", true);
details.put("name", (String) serviceRecord.get("name"));
details.put("amount", (Double) serviceRecord.get("amount"));
details.put("state", ((Date) serviceRecord.get("state")).compareTo(new Date()) < 0 ? "En cours" : "Clos");
}
result.put(serviceRecord.get("codeAffair"), details);
}
} else{
result.put("result", false);
result.put("error", "La liste n'est pas définie, ou vide.");
}
return result;
}
It returns json :
{"03-045251":{"alone":true,"amount":0.0,"name":"name1","state":"En cours"},"03_05494":{"alone":true,"amount":16743.0,"name":"name2","state":"En cours"}}
First, i execute sql request to collect my data and put it in a map.
Then, i send this map to my excel VBA.
Now see my VBA :
Sub JsonDataSqwal()
firstRow = Range("A" & 11).End(xlDown).Row
lastRow = Range("A" & Rows.Count).End(xlUp).Row
Dim httpObject As Object
Set httpObject = CreateObject("MSXML2.XMLHTTP")
sUrl = "http://localhost/rest/collectData/excel/exportAll"
sRequest = sUrl
httpObject.Open "GET", sRequest, False
httpObject.send
sGetResult = httpObject.responseText
If Not IsNull(sGetResult) Then
Dim oJson As Object
JsonConverter.JsonOptions.AllowUnquotedKeys = True
Set oJson = JsonConverter.ParseJson(sGetResult)
Dim i As Long
For i = firstRow To lastRow
Dim codeAffString As String
codeAffString = Cells(i, 4)
Debug.Print oJson(codeAffString)("name")
Next i
End If
End Sub
For the moment, i try to print my data. the loop collects values from a column, which contains all my codeAffair as 00_00000 or 00-00000
It is this data that i try to use in my vba code with the var codeAffString.
When i execute my code, i'm always getting error 13 about type incompatibility.
To solve this, i tried many things :
to add quote to my var
To rename my HashMap as HashMap<String, Object>
To allow unquoting keys
To change my back office program
To replace my value like """" + codeAffairString + """"
To replace my var with a fix String "00_00000". It works in this case.
To check the type of my var with VarTyp function which returns 8 for String index.
Now i Have no other idea to solve my problem..
If someone see where is my mistake..
Thank you !
Just a quick test:
I used the JSON string you gave and the value you gave for codeAffString to build a minimal reproducible example and it does not produce any errors:
Sub test()
Const JsonString As String = "{""03-045251"":{""alone"":true,""amount"":0.0,""name"":""name1"",""state"":""En cours""},""03_05494"":{""alone"":true,""amount"":16743.0,""name"":""name2"",""state"":""En cours""}}"
Const codeAffString As String = "03-045251"
Dim oJson As Object
JsonConverter.JsonOptions.AllowUnquotedKeys = True
Set oJson = JsonConverter.ParseJson(JsonString)
Debug.Print oJson(codeAffString)("name") ' outputs name1
End Sub
The error you describe occurs if codeAffString cannot be found in the JSON.
Test it by the following in your code:
For i = firstRow To lastRow
Dim codeAffString As String
codeAffString = Cells(i, 4)
If IsEmpty(oJson(codeAffString)) Then
Debug.Print codeAffString & " does not exist in the json"
Else
Debug.Print oJson(codeAffString)("name")
End If
Next i
I want to parse the following:
full_uri= "path/for/uri?$param1=value1&$param2=value2
in a way that gives me the uri as a string and the parameters as a map. What I'm trying right now is:
String[] full_uri_split = full_uri.split("\\?");
String uri = full_uri_split[0];
String parameters = full_uri_split[1];
This gives me 2 variables, 1 that is the uri, and another that is a string containing all the parameters, in the format of:
parameters = "$param1=value1&$param2=value2"
My next best guess is to then split it on the & signs:
String parameters_split = parameters.split("&");
which returns:
["$param1=value1", "$param2=value2"]
Now I want to convert this into a Map that looks like so:
"param1":"value1",
"param2":"value2"
and I'm not sure how to go about it.
I'm sure I could get it to work by doing more splits, but it seems horribly inefficient. So essentially, I want to turn:
full_uri = "path/for/uri?$param1=value1&$param2=value2"
into
uri = "path/for/uri"
params = {
"param1": "value1",
"param2": "value2"
}
Here is a solution using a loop.
Map<String, String> params = new HashMap<>();
for (String s : parameters_split){
params.put(s.split("=")[0], s.split("=")[1]);
}
I am trying to retrieve and process code from JIRA, unfortunately the pieces of information (which are in the Metadata-Plugin) are saved in a column, not a row.
Picture of JIRA-MySQL-Database
The goal is to save this in an object with following attributes:
public class DesiredObject {
private String Object_Key;
private String Aze.kunde.name;
private Long Aze.kunde.schluessel;
private String Aze.projekt.name;
private Long Aze.projekt.schluessel
//getters and setters here
}
My workbench is STS and it's a Spring-Boot-Application.
I can fetch a List of Object-Keys with the JRJC using:
JiraController jiraconnect = new JiraController();
List<JiraProject> jiraprojects = new ArrayList<JiraProject>();
jiraprojects = jiraconnect.findJiraProjects();
This is perfectly working, also the USER_KEY and USER_VALUE are easily retrievable, but I hope there is a better way than to perform
three SQL-Searches for each project and then somehow build an object from all those lists.
I was starting with
for (JiraProject jp : jiraprojects) {
String SQL = "select * from jira_metadata where ENRICHED_OBJECT_KEY = ?";
List<DesiredObject> do = jdbcTemplateObject.query(SQL, new Object[] { "com.atlassian.jira.project.Project:" + jp.getProjectkey() }, XXX);
}
to get a list with every object, but I'm stuck as i can't figure out a ObjectMapper (XXX) who is able to write this into an object.
Usually I go with
object.setter(rs.getString("SQL-Column"));
But that isn't working, as all my columns are called the same. (USER_KEY & USER_VALUE)
The Database is automatically created by JIRA, so I can't "fix" it.
The Object_Keys are unique which is why I tried to use those to collect all the data from my SQL-Table.
I hope all you need to enlighten me is in this post, if not feel free to ask for more!
Edit: Don't worry if there are some 'project' and 'projekt', that's because I gave most of my classes german names and descriptions..
I created a Hashmap with the Objectkey and an unique token in brackets, e.g.: "(1)JIRA".
String SQL = "select * from ao_cc6aeb_jira_metadata";
List<JiraImportObjekt> jioList = jdbcTemplateObject.query(SQL, new JiraImportObjektMapper());
HashMap<String, String> hmap = new HashMap<String, String>();
Integer unique = 1;
for (JiraImportObjekt jio : jioList) {
hmap.put("(" + unique.toString() + ")" + jio.getEnriched_Object_Key(),
jio.getUser_Key() + "(" + jio.getUser_Value() + ")");
unique++;
}
I changed this into a TreeMap
Map<String, String> tmap = new TreeMap<String, String>(hmap);
And then i iterated through that treemap via
String aktuProj = new String();
for (String s : tmap.keySet()) {
if (aktuProj.equals(s.replaceAll("\\([^\\(]*\\)", ""))) {
} else { //Add Element to list and start new Element }
//a lot of other stuff
}
What I did was to put all the data in the right order, iterate through and process everything like I wanted it.
Object hinfo = hmap.get(s);
if (hinfo.toString().replaceAll("\\([^\\(]*\\)", "").equals("aze.kunde.schluessel")) {
Matcher m = Pattern.compile("\\(([^)]+)\\)").matcher(hinfo.toString());
while (m.find()) {
jmo[obj].setAzeKundeSchluessel(Long.parseLong(m.group(1), 10));
// logger.info("AzeKundeSchluessel: " +
// jmo[obj].getAzeKundeSchluessel());
}
} else ...
After the loop I needed to add the last Element.
Now I have a List with the Elements which is easy to use and ready for further steps.
I cut out a lot of code because most of it is customized for my problem.. the roadmap should be enough to solve it though.
Good luck!
I have a redirect uri of the form https://stackexchange.com/oauth/login_success#access_token=token&expires=5678. I am trying to get the acces token from this url. tried following methods
uri.getQueryParameter("access_token"); //will return null since it is not a query param
uri.getFragment(); //will return "access_token=token&expires=5678" so i need to seperate it again.
Any direct methods? Pls help
Some one might find this helpful
String queryAfterFragment = uri.getFragment();
String dummy_url = "http://localhost?" + queryAfterFragment;
Uri dummy_uri = Uri.parse(dummy_url);
String access_token = dummy_uri.getQueryParameter("access_token");
Works like a charm and easy to use, thank me later :-)
Simple and elegant solution which can get the values which you want:
public static Map<String, String> parseUrlFragment (String url) {
Map<String, String> output = new LinkedHashMap<> ();
String[] keys = url.split ("&");
for (String key : keys) {
String[] values = key.split ("=");
output.put (values[0], (values.length > 1 ? values[1] : ""));
}
return output;
}
It's using LinkedHashMap to represent values, so it's output:
Map<String, String> data = parseUrlFragment (uri.getFragment ());
data.get ("access_token") // token
data.get ("expires") // 5678
You can try in this way
String str = "https://stackexchange.com/oauth/
login_success#access_token=token&expires=5678";
int indexOfHash = str.indexOf("#");
// now you can substring from this
String subStr = str.substring(indexOfHash+1, str.length());
System.out.println(subStr);
// now you can substring from &
String sStr=subStr.substring(0,subStr.indexOf("&"));
System.out.println(sStr);
// now you can get token
String[] arr=sStr.split("=");
System.out.println(arr[0]);
System.out.println(arr[1]);
Out put
access_token=token&expires=5678
access_token=token
access_token
token
You could use the String method split(String) with Regex
str.split("#|&|=")
this splits the string by the passed 3 chars and you get an array with all the splitted parts.
String s =
"https://stackexchange.com/oauth/login_success#access_token=token&expires=5678";
final String[] split = s.split("#|&|=");
for (String s1 : split) {
System.out.println(s1);
}
Output:
https://stackexchange.com/oauth/login_success
access_token
token
expires
5678
I have a string in the format nm=Alan&hei=72&hair=brown
I would like to split this information up, add a conversion to the first value and print the results in the format
nm Name Alan
hei Height 72
hair Hair Color brown
I've looked at various methods using the split function and hashmaps but have had no luck piecing it all together.
Any advice would be very useful to me.
Map<String, String> aliases = new HashMap<String, String>();
aliases.put("nm", "Name");
aliases.put("hei", "Height");
aliases.put("hair", "Hair Color");
String[] params = str.split("&"); // gives you string array: nm=Alan, hei=72, hair=brown
for (String p : params) {
String[] nv = p.split("=");
String name = nv[0];
String value = nv[1];
System.out.println(nv[0] + " " + aliases.get(nv[0]) + " " + nv[1]);
}
I really do not understand what you problem was...
Try something like this:
static final String DELIMETER = "&"
Map<String,String> map = ...
map.put("nm","Name");
map.put("hei","Height");
map.put("hair","Hair color");
StringBuilder builder = new StringBuilder();
String input = "nm=Alan&hei=72&hair=brown"
String[] splitted = input.split(DELIMETER);
for(Stirng str : splitted){
int index = str.indexOf("=");
String key = str.substring(0,index);
builder.append(key);
builder.append(map.get(key));
builder.append(str.substring(index));
builder.append("\n");
}
A HashMap consists of many key, value pairs. So when you use split, devise an appropriate regex (&). Once you have your string array, you can use one of the elements as the key (think about which element will make the best key). However, you may now be wondering- "how do I place the rest of elements as the values?". Perhaps you can create a new class which stores the rest of the elements and use objects of this class as values for the hashmap.
Then printing becomes easy- merely search for the value of the corresponding key. This value will be an object; use the appropriate method on this object to retrieve the elements and you should be able to print everything.
Also, remember to handle exceptions in your code. e.g. check for nulls, etc.
Another thing: your qn mentions the word "sort". I don't fully get what that means in this context...
Map<String, String> propsMap = new HashMap<String, String>();
Map<String, String> propAlias = new HashMap<String, String>();
propAlias.put("nm", "Name");
propAlias.put("hei", "Height");
propAlias.put("hair", "Hair Color");
String[] props = input.split("&");
if (props != null && props.length > 0) {
for (String prop : props) {
String[] propVal = prop.split("=");
if (propVal != null && propVal.length == 2) {
propsMap.put(propVal[0], propVal[1]);
}
}
}
for (Map.Entry tuple : propsMap.getEntrySet()) {
if (propAlias.containsKey(tuple.getKey())) {
System.out.println(tuple.getKey() + " " + propAlias.get(tuple.getKey()) + " " + tuple.getValue());
}
}