Java-Servlets: String null or "null" - string

String says its not null but then later throw NullPointerException
I had this problem(see the link), where I was sure that a String is null, but in fact the String was "null"
jcasso told me:
Since you get the string from a
servlet i can say that this is normal.
Java converts a null string to a
"null" string on some conditions.
When this situations appear?

Mostly when you use string concatenation or String.valueOf():
String x = null;
String y = x + ""; // y = "null"
String z = String.valueOf(x); // z = "null"
(There are similar variants, such as using StringBuilder.append((String) null).)

Related

Making sure every Alphabet is in a string (Kotlin)

So I have a question where I am checking if a string has every letter of the alphabet in it. I was able to check if there is alphabet in the string, but I'm not sure how to check if there is EVERY alphabet in said string. Here's the code
fun isPangram (pangram: Array<String>) : String {
var panString : String
var outcome = ""
for (i in pangram.indices){
panString = pangram[i]
if (panString.matches(".^*[a-z].*".toRegex())){
outcome = outcome.plus('1')
}
else {outcome = outcome.plus('0')}
}
return outcome
}
Any ideas are welcomed Thanks.
I think it would be easier to check if all members of the alphabet range are in each string than to use Regex:
fun isPangram(pangram: Array<String>): String =
pangram.joinToString("") { inputString ->
when {
('a'..'z').all { it in inputString.lowercase() } -> "1"
else -> "0"
}
}
Hi this is how you can make with regular expression
Kotlin Syntax
fun isStrinfContainsAllAlphabeta( input: String) {
return input.lowercase()
.replace("[^a-z]".toRegex(), "")
.replace("(.)(?=.*\\1)".toRegex(), "")
.length == 26;
}
In java:
public static boolean isStrinfContainsAllAlphabeta(String input) {
return input.toLowerCase()
.replace("[^a-z]", "")
.replace("(.)(?=.*\\1)", "")
.length() == 26;
}
the function takes only one string. The first "replaceAll" removes all the non-alphabet characters, The second one removes the duplicated character, then you check how many characters remained.
Just to bounce off Tenfour04's solution, if you write two functions (one for the pangram check, one for processing the array) I feel like you can make it a little more readable, since they're really two separate tasks. (This is partly an excuse to show you some Kotlin tricks!)
val String.isPangram get() = ('a'..'z').all { this.contains(it, ignoreCase = true) }
fun checkPangrams(strings: Array<String>) =
strings.joinToString("") { if (it.isPangram) "1" else "0" }
You could use an extension function instead of an extension property (so it.isPangram()), or just a plain function with a parameter (isPangram(it)), but you can write stuff that almost reads like English, if you want!

Grails convert String to Map with comma in string values

I want convert string to Map in grails. I already have a function of string to map conversion. Heres the code,
static def StringToMap(String reportValues){
Map result=[:]
result=reportValues.replace('[','').replace(']','').replace(' ','').split(',').inject([:]){map,token ->
List tokenizeStr=token.split(':');
tokenizeStr.size()>1?tokenizeStr?.with {map[it[0]?.toString()?.trim()]=it[1]?.toString()?.trim()}:tokenizeStr?.with {map[it[0]?.toString()?.trim()]=''}
map
}
return result
}
But, I have String with comma in the values, so the above function doesn't work for me. Heres my String
[program_type:, subsidiary_code:, groupName:, termination_date:, effective_date:, subsidiary_name:ABC, INC]
my function returns ABC only. not ABC, INC. I googled about it but couldnt find any concrete help.
Generally speaking, if I have to convert a Stringified Map to a Map object I try to make use of Eval.me. Your example String though isn't quite right to do so, if you had the following it would "just work":
// Note I have added '' around the values.
​String a = "[program_type:'', subsidiary_code:'', groupName:'', termination_date:'', effective_date:'', subsidiary_name:'ABC']"
Map b = Eval.me(a)​
// returns b = [program_type:, subsidiary_code:, groupName:, termination_date:, effective_date:, subsidiary_name:ABC]
If you have control of the String then if you can create it following this kind of pattern, it would be the easiest solution I suspect.
In case it is not possible to change the input parameter, this might be a not so clean and not so short option. It relies on the colon instead of comma values.
​String reportValues = "[program_type:, subsidiary_code:, groupName:, termination_date:, effective_date:, subsidiary_name:ABC, INC]"
reportValues = reportValues[1..-2]
def m = reportValues.split(":")
def map = [:]
def length = m.size()
m.eachWithIndex { v, i ->
if(i != 0) {
List l = m[i].split(",")
if (i == length-1) {
map.put(m[i-1].split(",")[-1], l.join(","))
} else {
map.put(m[i-1].split(",")[-1], l[0..-2].join(","))
}
}
}
map.each {key, value -> println "key: " + key + " value: " + value}
BTW: Only use eval on trusted input, AFAIK it executes everything.
You could try messing around with this bit of code:
String tempString = "[program_type:11, 'aa':'bb', subsidiary_code:, groupName:, termination_date:, effective_date:, subsidiary_name:ABC, INC]"
List StringasList = tempString.tokenize('[],')
def finalMap=[:]
StringasList?.each { e->
def f = e?.split(':')
finalMap."${f[0]}"= f.size()>1 ? f[1] : null
}
println """-- tempString: ${tempString.getClass()} StringasList: ${StringasList.getClass()}
finalMap: ${finalMap.getClass()} \n Results\n finalMap ${finalMap}
"""
Above produces:
-- tempString: class java.lang.String StringasList: class java.util.ArrayList
finalMap: class java.util.LinkedHashMap
Results
finalMap [program_type:11, 'aa':'bb', subsidiary_code:null, groupName:null, termination_date:null, effective_date:null, subsidiary_name:ABC, INC:null]
It tokenizes the String then converts ArrayList by iterating through the list and passing each one again split against : into a map. It also has to check to ensure the size is greater than 1 otherwise it will break on f[1]

Convert String to Long using BufferReader

I'm trying to convert my input read Strings to long (Long). I've tried the valueof() and Long.Parslong(String s) but no luck. Im not sure what is going on. I can certainly print the String but cannot convert to Long ):
while ((line = br.readLine()) != null) {
String[] sheet = line.split(cvsSplitBy); //comma as separator
if(isNumeric(sheet[3])){ //parse into integer, only if first col is num
int n = Integer.parseInt(sheet[0]);
int pop = Integer.parseInt(sheet[3]);
System.out.println(sheet[4]);
System.out.println(sheet[4].getClass().getName());
Long lon = Long.valueOf(sheet[4]); //THIS IS WHERE THE ERROR OCCURS
......skip
The Error is the usual NumberFormatException
Exception in thread "main" java.lang.NumberFormatException: For input string: "34.95"
Any ideas? Thanks Aj
Focus on the description of the exception.
For input string: "34.95"
It has a Decimal value, which can't convert into a Long. You could either use Double.valueOf("34.95") or do a validation for non integer values.

Convert string to double do not respect current number decimal separator

I'm trying to convert a string representing a double from invariant culture to a double in current culture representation, I'm concerned with how to get the new double representation to use the current number decimal separator of Current Culture.
I used the code below for the conversion :
public static double ConvertToDouble(this object inputVal, bool useCurrentCulture = false)
{
string currentSep = CultureInfo.CurrentCulture.NumberFormat.NumberDecimalSeparator;
string invariantSep = CultureInfo.InvariantCulture.NumberFormat.NumberDecimalSeparator;
if (inputVal.GetType() == typeof(string))
{
if (!currentSep.Equals(invariantSep))
{
inputVal = (inputVal as string).Replace(invariantSep, currentSep);
}
}
if (useCurrentCulture)
return Convert.ToDouble(inputVal, CultureInfo.CurrentCulture);
else
return Convert.ToDouble(inputVal);
}
But the above code always gives me a double with ".", although I use the CurrentCulture for example French supposed to give me a double with comma (",").
Many thanks in advance for any hint.
FreeDev
But the above code always gives me a double with "." as the NumberDecimalSeparator
No, it returns a double. A double is just a number. It doesn't have a NumberDecimalSeparator... only a culture does, and that's only applied when converting to or from strings. Talking about the separator for a double is like talking about whether an int is in decimal or hex - there's no such concept. 0x10 and 16 are the same value, represented by the same bits.
It's not really clear what you're trying to do, but it's crucial to understand the difference between what's present in a textual representation, and what's inherent to the data value itself. You should care about the separator when parsing or formatting - but after you've parsed to a double, that information is gone.
From the comments and your question i guess that you actually want to convert a string to a double with either InvariantCulture or current-culture. This double should then be converted to a string which is formatted by the current-culture datetime-format informations(like NumberDecimalSeparator).
So this method should do two things:
parse string to double
convert double to string
public static string ConvertToFormattedDouble(this string inputVal, IFormatProvider sourceFormatProvider = null, IFormatProvider targetFormatProvider = null)
{
if (sourceFormatProvider == null) sourceFormatProvider = NumberFormatInfo.InvariantInfo;
if (targetFormatProvider == null) targetFormatProvider = NumberFormatInfo.CurrentInfo;
if (sourceFormatProvider == targetFormatProvider)
return inputVal; // or exception?
double d;
bool isConvertable = double.TryParse(inputVal, NumberStyles.Any, sourceFormatProvider, out d);
if (isConvertable)
return d.ToString(targetFormatProvider);
else
return null; // or whatever
}
You can use it in this way:
string input = "1234.567";
string output = input.ConvertToFormattedDouble(); // "1234,567"
Note that i've extended string instead of object. Extensions for object are a bad idea in my opinion. You pollute intellisense with a method that you 'll almost never use (although it applies also to string).
Update:
If you really want to go down this road and use an extension for object that supports any kind of numbers as (boxed) objects or strings you could try this extension:
public static string ConvertToFormattedDouble(this object inputVal, IFormatProvider sourceFormatProvider = null, IFormatProvider targetFormatProvider = null)
{
if (sourceFormatProvider == null) sourceFormatProvider = NumberFormatInfo.InvariantInfo;
if (targetFormatProvider == null) targetFormatProvider = NumberFormatInfo.CurrentInfo;
if (inputVal is string)
{
double d;
bool isConvertable = double.TryParse((string)inputVal, NumberStyles.Any, sourceFormatProvider, out d);
if (isConvertable)
return d.ToString(targetFormatProvider);
else
return null;
}
else if (IsNumber(inputVal))
{
decimal d = Convert.ToDecimal(inputVal, sourceFormatProvider);
return Decimal.ToDouble(d).ToString(targetFormatProvider);
}
else
return null;
}
public static bool IsNumber(this object value)
{
return value is sbyte
|| value is byte
|| value is short
|| value is ushort
|| value is int
|| value is uint
|| value is long
|| value is ulong
|| value is float
|| value is double
|| value is decimal;
}
Usage:
object input = 1234.56745765677656578d;
string output = input.ConvertToFormattedDouble(); // "1234,56745765678"

How to check whether a string is Base64 encoded or not

I want to decode a Base64 encoded string, then store it in my database. If the input is not Base64 encoded, I need to throw an error.
How can I check if a string is Base64 encoded?
You can use the following regular expression to check if a string constitutes a valid base64 encoding:
^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$
In base64 encoding, the character set is [A-Z, a-z, 0-9, and + /]. If the rest length is less than 4, the string is padded with '=' characters.
^([A-Za-z0-9+/]{4})* means the string starts with 0 or more base64 groups.
([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$ means the string ends in one of three forms: [A-Za-z0-9+/]{4}, [A-Za-z0-9+/]{3}= or [A-Za-z0-9+/]{2}==.
If you are using Java, you can actually use commons-codec library
import org.apache.commons.codec.binary.Base64;
String stringToBeChecked = "...";
boolean isBase64 = Base64.isArrayByteBase64(stringToBeChecked.getBytes());
[UPDATE 1] Deprecation Notice
Use instead
Base64.isBase64(value);
/**
* Tests a given byte array to see if it contains only valid characters within the Base64 alphabet. Currently the
* method treats whitespace as valid.
*
* #param arrayOctet
* byte array to test
* #return {#code true} if all bytes are valid characters in the Base64 alphabet or if the byte array is empty;
* {#code false}, otherwise
* #deprecated 1.5 Use {#link #isBase64(byte[])}, will be removed in 2.0.
*/
#Deprecated
public static boolean isArrayByteBase64(final byte[] arrayOctet) {
return isBase64(arrayOctet);
}
Well you can:
Check that the length is a multiple of 4 characters
Check that every character is in the set A-Z, a-z, 0-9, +, / except for padding at the end which is 0, 1 or 2 '=' characters
If you're expecting that it will be base64, then you can probably just use whatever library is available on your platform to try to decode it to a byte array, throwing an exception if it's not valid base 64. That depends on your platform, of course.
As of Java 8, you can simply use java.util.Base64 to try and decode the string:
String someString = "...";
Base64.Decoder decoder = Base64.getDecoder();
try {
decoder.decode(someString);
} catch(IllegalArgumentException iae) {
// That string wasn't valid.
}
Try like this for PHP5
//where $json is some data that can be base64 encoded
$json=some_data;
//this will check whether data is base64 encoded or not
if (base64_decode($json, true) == true)
{
echo "base64 encoded";
}
else
{
echo "not base64 encoded";
}
Use this for PHP7
//$string parameter can be base64 encoded or not
function is_base64_encoded($string){
//this will check if $string is base64 encoded and return true, if it is.
if (base64_decode($string, true) !== false){
return true;
}else{
return false;
}
}
var base64Rejex = /^(?:[A-Z0-9+\/]{4})*(?:[A-Z0-9+\/]{2}==|[A-Z0-9+\/]{3}=|[A-Z0-9+\/]{4})$/i;
var isBase64Valid = base64Rejex.test(base64Data); // base64Data is the base64 string
if (isBase64Valid) {
// true if base64 formate
console.log('It is base64');
} else {
// false if not in base64 formate
console.log('it is not in base64');
}
Try this:
public void checkForEncode(String string) {
String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(string);
if (m.find()) {
System.out.println("true");
} else {
System.out.println("false");
}
}
It is impossible to check if a string is base64 encoded or not. It is only possible to validate if that string is of a base64 encoded string format, which would mean that it could be a string produced by base64 encoding (to check that, string could be validated against a regexp or a library could be used, many other answers to this question provide good ways to check this, so I won't go into details).
For example, string flow is a valid base64 encoded string. But it is impossible to know if it is just a simple string, an English word flow, or is it base 64 encoded string ~Z0
There are many variants of Base64, so consider just determining if your string resembles the varient you expect to handle. As such, you may need to adjust the regex below with respect to the index and padding characters (i.e. +, /, =).
class String
def resembles_base64?
self.length % 4 == 0 && self =~ /^[A-Za-z0-9+\/=]+\Z/
end
end
Usage:
raise 'the string does not resemble Base64' unless my_string.resembles_base64?
Check to see IF the string's length is a multiple of 4. Aftwerwards use this regex to make sure all characters in the string are base64 characters.
\A[a-zA-Z\d\/+]+={,2}\z
If the library you use adds a newline as a way of observing the 76 max chars per line rule, replace them with empty strings.
/^([A-Za-z0-9+\/]{4})*([A-Za-z0-9+\/]{4}|[A-Za-z0-9+\/]{3}=|[A-Za-z0-9+\/]{2}==)$/
this regular expression helped me identify the base64 in my application in rails, I only had one problem, it is that it recognizes the string "errorDescripcion", I generate an error, to solve it just validate the length of a string.
For Flutter, I tested couple of the above comments and translated that into dart function as follows
static bool isBase64(dynamic value) {
if (value.runtimeType == String){
final RegExp rx = RegExp(r'^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$',
multiLine: true,
unicode: true,
);
final bool isBase64Valid = rx.hasMatch(value);
if (isBase64Valid == true) {return true;}
else {return false;}
}
else {return false;}
}
In Java below code worked for me:
public static boolean isBase64Encoded(String s) {
String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(s);
return m.find();
}
This works in Python:
import base64
def IsBase64(str):
try:
base64.b64decode(str)
return True
except Exception as e:
return False
if IsBase64("ABC"):
print("ABC is Base64-encoded and its result after decoding is: " + str(base64.b64decode("ABC")).replace("b'", "").replace("'", ""))
else:
print("ABC is NOT Base64-encoded.")
if IsBase64("QUJD"):
print("QUJD is Base64-encoded and its result after decoding is: " + str(base64.b64decode("QUJD")).replace("b'", "").replace("'", ""))
else:
print("QUJD is NOT Base64-encoded.")
Summary: IsBase64("string here") returns true if string here is Base64-encoded, and it returns false if string here was NOT Base64-encoded.
C#
This is performing great:
static readonly Regex _base64RegexPattern = new Regex(BASE64_REGEX_STRING, RegexOptions.Compiled);
private const String BASE64_REGEX_STRING = #"^[a-zA-Z0-9\+/]*={0,3}$";
private static bool IsBase64(this String base64String)
{
var rs = (!string.IsNullOrEmpty(base64String) && !string.IsNullOrWhiteSpace(base64String) && base64String.Length != 0 && base64String.Length % 4 == 0 && !base64String.Contains(" ") && !base64String.Contains("\t") && !base64String.Contains("\r") && !base64String.Contains("\n")) && (base64String.Length % 4 == 0 && _base64RegexPattern.Match(base64String, 0).Success);
return rs;
}
There is no way to distinct string and base64 encoded, except the string in your system has some specific limitation or identification.
This snippet may be useful when you know the length of the original content (e.g. a checksum). It checks that encoded form has the correct length.
public static boolean isValidBase64( final int initialLength, final String string ) {
final int padding ;
final String regexEnd ;
switch( ( initialLength ) % 3 ) {
case 1 :
padding = 2 ;
regexEnd = "==" ;
break ;
case 2 :
padding = 1 ;
regexEnd = "=" ;
break ;
default :
padding = 0 ;
regexEnd = "" ;
}
final int encodedLength = ( ( ( initialLength / 3 ) + ( padding > 0 ? 1 : 0 ) ) * 4 ) ;
final String regex = "[a-zA-Z0-9/\\+]{" + ( encodedLength - padding ) + "}" + regexEnd ;
return Pattern.compile( regex ).matcher( string ).matches() ;
}
If the RegEx does not work and you know the format style of the original string, you can reverse the logic, by regexing for this format.
For example I work with base64 encoded xml files and just check if the file contains valid xml markup. If it does not I can assume, that it's base64 decoded. This is not very dynamic but works fine for my small application.
This works in Python:
def is_base64(string):
if len(string) % 4 == 0 and re.test('^[A-Za-z0-9+\/=]+\Z', string):
return(True)
else:
return(False)
Try this using a previously mentioned regex:
String regex = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
if("TXkgdGVzdCBzdHJpbmc/".matches(regex)){
System.out.println("it's a Base64");
}
...We can also make a simple validation like, if it has spaces it cannot be Base64:
String myString = "Hello World";
if(myString.contains(" ")){
System.out.println("Not B64");
}else{
System.out.println("Could be B64 encoded, since it has no spaces");
}
if when decoding we get a string with ASCII characters, then the string was
not encoded
(RoR) ruby solution:
def encoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count.zero?
end
def decoded?(str)
Base64.decode64(str.downcase).scan(/[^[:ascii:]]/).count > 0
end
Function Check_If_Base64(ByVal msgFile As String) As Boolean
Dim I As Long
Dim Buffer As String
Dim Car As String
Check_If_Base64 = True
Buffer = Leggi_File(msgFile)
Buffer = Replace(Buffer, vbCrLf, "")
For I = 1 To Len(Buffer)
Car = Mid(Buffer, I, 1)
If (Car < "A" Or Car > "Z") _
And (Car < "a" Or Car > "z") _
And (Car < "0" Or Car > "9") _
And (Car <> "+" And Car <> "/" And Car <> "=") Then
Check_If_Base64 = False
Exit For
End If
Next I
End Function
Function Leggi_File(PathAndFileName As String) As String
Dim FF As Integer
FF = FreeFile()
Open PathAndFileName For Binary As #FF
Leggi_File = Input(LOF(FF), #FF)
Close #FF
End Function
import java.util.Base64;
public static String encodeBase64(String s) {
return Base64.getEncoder().encodeToString(s.getBytes());
}
public static String decodeBase64(String s) {
try {
if (isBase64(s)) {
return new String(Base64.getDecoder().decode(s));
} else {
return s;
}
} catch (Exception e) {
return s;
}
}
public static boolean isBase64(String s) {
String pattern = "^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{4}|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)$";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(s);
return m.find();
}
For Java flavour I actually use the following regex:
"([A-Za-z0-9+]{4})*([A-Za-z0-9+]{3}=|[A-Za-z0-9+]{2}(==){0,2})?"
This also have the == as optional in some cases.
Best!
I try to use this, yes this one it's working
^([A-Za-z0-9+/]{4})*([A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{2}==)?$
but I added on the condition to check at least the end of the character is =
string.lastIndexOf("=") >= 0

Resources