lets say I have a url param like token=1234235asdjaklj231k209a&name=sam&firname=Mahan
how can I replace the value of the token with new one ?
I've done something similar to this with pattern and matcher before but I don't recall now
but I know there is a way to do so
Update : the token can contain any letter but &
thanks in advance
Spring has a util that handles this need gracefully. Apache httpcomponents does too. Below is a spring example.
import org.springframework.web.util.UriComponentsBuilder;
import java.net.URI;
public class StackOverflow {
private static class SO46303058 {
public static void main(String[] args) {
final String urlString = "https://subdomain.hostname/path/resource?token=1234235asdjaklj231k209a&name=sam&firname=Mahan";
final URI uri = UriComponentsBuilder.fromHttpUrl(urlString)
.replaceQueryParam("token", "abc")
.build().toUri();
System.out.println(uri);
}
}
}
Don't be afraid of adding dependencies to your project, it beats reinventing the wheel.
We can consider doing a simple regex replacement, with a few caveats (q.v. below the code snippet).
String url = "token=1234235asdjaklj231k209a&name=sam&firname=Mahan";
url = url.replaceFirst("\\btoken=.*?(&|$)", "token=new_value$1");
System.out.println(url);
url = "param1=value&token=1234235asdjaklj231k209a";
url = url.replaceFirst("\\btoken=.*?(&|$)", "token=new_value$1");
System.out.println(url);
Edge cases to consider are first that your token may be the last parameter in the query string. To cover this case, we should check for token=... ending in either an ambersand & or the end of the string. But if we don't use a lookahead, and instead consume that ambersand, we have to also add it back in the replacement. The other edge case, correctly caught by #DodgyCodeException in his comment below, is that there be another query parameter which just happens to end in token. To make sure we are really matching our token parameter, we can preface it with a word boundary in the regex, i.e. use \btoken=... to refer to it.
Output:
token=new_value&name=sam&firname=Mahan
param1=value&token=new_value
make a viewModel.
public class veiwModel(){ String token ; // and get and set for exmample }
then use Gson if u have a json text .
Gson gson = new Gson();
yourViewModel = gson.fronJson(jsonText , viewModel.class);
System.out.println(yourViewModel.getToken());
Related
I hava one jsonString
String target = "[{"nickName":"andy","password":"wei","userword":"weitest32123"}]";
I wish to get
String target = "[{"nickName":"andy","password":"xxx","userword":"xxx"}]";
I want to use the java String method replaceall(regex,"xxx");
how do?
Try this.
String input = "[{\"nickName\":\"andy\",\"password\":\"wei\",\"userword\":\"weitest32123\"}]";
String output = input.replaceAll("(?<=\"(pass|user)word\":\")[^\"]+", "xxx");
System.out.println(output);
output:
[{"nickName":"andy","password":"xxx","userword":"xxx"}]
You can do it with the Positive Lookbehind regexp regex101.com:
public static void main(String... args) {
String str = "\"[{\"nickName\":\"andy\",\"password\":\"wei\",\"userword\":\"weitest32123\"}]\"";
System.out.println(maskPassword(str)); // "[{"nickName":"andy","password":"xxx","userword":"xxx"}]"
}
public static String maskPassword(String str) {
String regex = "(?<=\"(password|userword)\":)(\"[^\"]+\")";
return str.replaceAll(regex, "\"xxx\"");
}
P.S. I strongly recommend you not to do this with json string. This could follow a problem in the future. It's better to parse this json string into an object and then create json back with modification.
E.g. you can use a tool that I wrote gson-utils
This may seem like you're trying to parse some JSON. I'm not sure if casting it to object and then hiding values would be better approach.
But if you really need to do this way, this would be the solution
// You need this 2 imports
//import java.util.regex.Matcher;
//import java.util.regex.Pattern;
String text = "[{\"nickName\":\"andy\",\"password\":\"wei\",\"userword\":\"weitest32123\"}]";
Pattern pattern = Pattern.compile("\"(?<key>password|userword)\":\"(?<value>.*?)\"");
Matcher matcher = pattern.matcher(text);
String result = matcher.replaceAll("\"${key}\":\"xxx\"");
In Regex you need to specify all keys that you want to mask
I'm trying to convert JSON object into string by doing the below
JSONObject object = new JSONObject();
object.put("video", data);
array1.add( object.toString().replace("\\\\"," "));
Actual result
["{\"photos\":\"/contests/1/images/1.png\"}",
{\"photos\":\"/contests/1/images/2.png\"}"]
Expected result
["{"photos":"/contests/1/images/1.png\"}","
{"photos":"/contests/1/images/2.png\"}"]
not able to remove the slashes from key
Use replaceAll instead of replace
replaceAll("\\\\", "")
When you want to replace all the occurences with .replace, the first parameter must be a regex, if you supply a string, only the first occurrence will be replaced, that's why your replace wouldn't work.
Please use:
.replace("/\\/g","")
Alternatively, replaceAll can be used as #Code_Mono suggested
The Code_Mode mentioned is correct one.
Because String is immutable. Make sure that you put it right place.
You can refer code bellow for more detail:
public static void main(String[] args) {
String json = "[\"{\\\"photos\\\":\\\"/contests/1/images/1.png\\\"}\", {\\\"photos\\\":\\\"/contests/1/images/2.png\\\"}\"]";
json.replaceAll("\\\\","");
System.out.println(json);
String jsonReplace = json.replaceAll("\\\\","");
System.out.println(jsonReplace);
}
Output value:
["{\"photos\":\"/contests/1/images/1.png\"}", {\"photos\":\"/contests/1/images/2.png\"}"]
["{"photos":"/contests/1/images/1.png"}", {"photos":"/contests/1/images/2.png"}"]
#RequestMapping(value = "/{userId:\\d+}", method = RequestMethod.DELETE)
public void delete(#PathVariable Long userId) {
try{
this.authorService.delete(userId);
}catch(Exception e){
throw new RuntimeException("delete error");
}
}
Anybody know what url should I match for this definition "/{userId:\d+}", could you give me an example, like "/userid=1", is this right?
I guess that definition like this "/{userId:\d+}" , using regular expression in url to make sure it pass a number parameter.I am not sure about that , if anybody knows it please give me a link for further learning, thank you!
No, that expression maps /1 for example, all the digits.
The syntax {varName:regex} declares a URI variable with a regular expressions with the syntax {varName:regex} — e.g. given URL "/spring-web-3.0.5 .jar", the below method extracts the name, version, and file extension:
#GetMapping("/{name:[a-z-]+}-{version:\\d\\.\\d\\.\\d}{ext:\\.[a-z]+}")
public void handle(#PathVariable String version, #PathVariable String ext) {
// ...
}
Check the complete doc here
It will match any digit. For example,
/1, /11, /123.
/{userId:\\d+} ===> map one or more digits after / to variable userId.
Regular expression for one or more digits is \d+, but since you are using it as a string you need to escape it using another \.
I have looked everywhere, and the only example I could find was one for marking JOptionPane.show and removing it. That doesn't help me much.
Note: This goes over making a hint that will match a method, but when you are done, you should be able to match more (like learning RegEx)
This was rather difficult to do and figure out... I am going to assume you have gone over the tutorial at https://platform.netbeans.org/tutorials/nbm-java-hint.html. After creating the hint via the instructions there, you now have a basic Hint implementation:
#Hint(displayName = "#DN_MainCallHint", description = "#DESC_MainCallHint",
category = "general")
#Messages({
"DN_MainCallHint=MainCall",
"DESC_MainCallHint=Warns the user when they are manually calling public "
+ "static void main"
})
public class MainCallHint {
#TriggerPattern(value = "$str.equals(\"\")", //Specify a pattern as needed
constraints = #ConstraintVariableType(variable = "$str", type
= "java.lang.String"))
#Messages("ERR_MainCallHint=Directly calling main! Did you mean to do that?")
public static ErrorDescription computeWarning(HintContext ctx) {
return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.
ERR_MainCallHint());
}
}
The main trouble I had was with #TriggerPattern.value. If you wanted to match a method call, you would set it to something like this:
"$caller.method($arg1, $arg2)"
and can set type constraints for each of those variables. One important thing to note: if you are trying to match a static method of a particular type, use the FQN of that class or it won't work with arguments. So use something like this:
"test.HintTest.main($args)"
Resulting in the #TriggerPattern bit to look like this:
#TriggerPattern(value = "test.HintTest.main($args)", //Specify a pattern as needed
constraints = #ConstraintVariableType(variable = "$args", type
= "java.lang.String[]"))
And you get this:
Now, the tutorial shows a very cumbersome way to implement a fix. If all you need to do is a simple replace, then it can be done like this:
public static ErrorDescription computeWarning(HintContext ctx) {
Fix fix = JavaFixUtilities.rewriteFix(ctx, "Use notMain instead",
ctx.getPath(), "test.HintTest.notMain($args)");
return ErrorDescriptionFactory.forName(ctx, ctx.getPath(), Bundle.
ERR_MainCallHint(), fix);
}
Note: The variables used for rewriteFix must be the same you used in #TriggerPattern or they will be interpreted as literals.
I am using a query parameters to set the values needed by the Google Maps API.
The issue is I do not need the & sign for the first query parameter.
#GET("/maps/api/geocode/json?")
Call<JsonObject> getLocationInfo(#Query("address") String zipCode,
#Query("sensor") boolean sensor,
#Query("client") String client,
#Query("signature") String signature);
Retrofit generates:
&address=90210&sensor=false&client=gme-client&signature=signkey
which causes the call the fail when I need it to be
address=90210&sensor=false&client=gme-client&signature=signkey
How do I fix this?
If you specify #GET("foobar?a=5"), then any #Query("b") must be appended using &, producing something like foobar?a=5&b=7.
If you specify #GET("foobar"), then the first #Query must be appended using ?, producing something like foobar?b=7.
That's how Retrofit works.
When you specify #GET("foobar?"), Retrofit thinks you already gave some query parameter, and appends more query parameters using &.
Remove the ?, and you will get the desired result.
I am new to retrofit and I am enjoying it. So here is a simple way to understand it for those that might want to query with more than one query: The ? and & are automatically added for you.
Interface:
public interface IService {
String BASE_URL = "https://api.test.com/";
String API_KEY = "SFSDF24242353434";
#GET("Search") //i.e https://api.test.com/Search?
Call<Products> getProducts(#Query("one") String one, #Query("two") String two,
#Query("key") String key)
}
It will be called this way. Considering you did the rest of the code already.
Call<Results> call = service.productList("Whatever", "here", IService.API_KEY);
For example, when a query is returned, it will look like this.
//-> https://api.test.com/Search?one=Whatever&two=here&key=SFSDF24242353434
Link to full project: Please star etc: https://github.com/Cosmos-it/ILoveZappos
If you found this useful, don't forget to star it please. :)
public interface IService {
String BASE_URL = "https://api.demo.com/";
#GET("Login") //i.e https://api.demo.com/Search?
Call<Products> getUserDetails(#Query("email") String emailID, #Query("password") String password)
}
It will be called this way. Considering you did the rest of the code already.
Call<Results> call = service.getUserDetails("abc#gmail.com", "Password#123");
For example when a query is returned, it will look like this.
https://api.demo.com/Login?email=abc#gmail.com&password=Password#123