Why org.apache.commons.lang.StringUtils.isBlank() returns false for empty and null values - junit

I saw the implementation of StringUtils.isBlank() and was surprised that in my case, it is not working as expected.
I was writing a Junit and I faced this issue.
AmazonSNSRegistrationService.java:
public String doAWSSNSNDeviceRegistration(Map<String, Object> jsonBody){
String deviceId = (String) jsonBody.get(PushNotificationsConstants.DEVICE_ID);
String pushToken = (String) jsonBody.get(PushNotificationsConstants.PUSH_TOKEN);
String appId = (String) jsonBody.get(PushNotificationsConstants.APP_ID);
if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(pushToken) || StringUtils.isBlank(appId)) {
System.out.println("$$$$$ Empty");
throw new Exception("Required parameters are empty.");
}
return registerWithSNS(pushToken, deviceId, appId);
}
AmazonSNSRegistrationServiceTest.java:
#Test
public void doAWSSNSNDeviceRegistrationBlankTest() {
Map<String, Object> jsonBody = new HashMap<String, Object>();
jsonBody.put(PushNotificationsConstants.APP_ID, "");
jsonBody.put(PushNotificationsConstants.DEVICEID, " ");
try{
amazonSNSRegistrationService.doAWSSNSNDeviceRegistration(jsonBody);
}
catch(Exception e){
}
}
I'm not passing Push Token , so it will be null. Other values are either "" or " ".
But in if condition, none of the statements give true. All return false and the Exception is not thrown. I want this code to throw exception when any of the statement in if (StringUtils.isBlank(deviceId) || StringUtils.isBlank(pushToken) || StringUtils.isBlank(appId)) returns true.

Related

NewtonSoft.Json Treating Blank Value as Null but not throwing error

Environment
.net 7
Using Both System.Text.Json
Also NewtonSoft.Json ( 13.0.2)
Example code
string str = #"{
""DateTimeNull"":""""
}";
try
{
var t = System.Text.Json.JsonSerializer.Deserialize<Test>(str);
}
catch (JsonException ex)
{
Console.WriteLine(new { Field = ex.Path , Message = ex.Message });
}
try
{
var t = Newtonsoft.Json.JsonConvert.DeserializeObject<Test>(str);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
public class Test
{
public DateTime? DateTimeNull { get; set; }
}
In above System.Text.Json Deserlizer throw exception but newtonsoft.json line is not throwing any exception. It is converting empty value to null but I want it should thow error and due to limitation I can not move to System.Text.Json as of now.
Payload ( This is i already set in str)
Sample one
#"{
""DateTimeNull"":""""
}";
Expected result: Throw error and should not convert to null.
Sample two.
#"{
""DateTimeNull"": null
}";
Expected result: Should not throw error and it is null value and destination type is null.
I usually recommend to use a JsonConstructor:
var json = #"{
""DateTimeNull"":""""
}";
Test test = JsonConvert.DeserializeObject<Test>(json);
public class Test
{
public DateTime? DateTimeNull { get; set; }
[Newtonsoft.Json.JsonConstructor]
public Test(JToken DateTimeNull)
{
if (DateTimeNull.Type == JTokenType.Null) this.DateTimeNull = null;
else if ((string)DateTimeNull == string.Empty)
throw new JsonException("DateTimeNull property should not be an empty string");
else this.DateTimeNull = DateTimeNull.ToObject<DateTime>();
}
}

org.json.JSONException: No value for name

What could be the reason of this error in the code below?
loginButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick (View v){
final String e_mail = e_mailEditText.getText().toString();
final String password = passwordEditText.getText().toString();
// Response received from the server
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonResponse = new JSONObject(response);
boolean success = jsonResponse.getBoolean("success");
if (success) {
String name = jsonResponse.getString("name");
// int age = jsonResponse.getInt("age");
Intent intent = new Intent(login.this, Welcome.class);
intent.putExtra("name", name);
// intent.putExtra("age", age);
intent.putExtra("e_mail", e_mail);
login.this.startActivity(intent);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
builder.setMessage("Login Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
LoginRequest loginRequest = new LoginRequest(e_mail, password, responseListener);
RequestQueue queue = Volley.newRequestQueue(login.this);
queue.add(loginRequest);
}
});
Check if you have the key first:
if (jsonObject.has("name")) {
String name = jsonObject.getString("name");
}
For others users which have the org.json.JSONException: No value for //your parameter.
In this case you should check if the name is empty.
For example using method jsonResponse.optString("name").
Live example:
if (success) {
String name = jsonResponse.optString("name"); //will get name value or return empty String
if (!name.equals("")) {
//Your code if name is exist
Intent intent = new Intent(login.this, Welcome.class);
intent.putExtra("name", name);
intent.putExtra("e_mail", e_mail);
login.this.startActivity(intent);
} else {
//Your code if the name is empty
}
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(login.this);
builder.setMessage("Login Failed")
.setNegativeButton("Retry", null)
.create()
.show();
}
Can't say for sure without knowing the context (or the line number of the exception), but my money would be on the call:
jsonResponse.getString("name")
Most likely, the JSON received from the server doesn't contain any name/value pairs with name name.

Controller checkEmail returns "Error parsing JSON: undefined false" for 'false', 'true' works as intended

I've got a little problem with returning false from controller. First off, true is being returned normally as "true" in JSON without any problem, but when it should return false this is displayed :
Error parsing JSON: undefined
undefined:
false
Here is my DAO
#Override
public Boolean checkEmail(String email) {
System.out.println(email);
Query query = em.createQuery("SELECT s FROM StudenciEntity s WHERE s.email LIKE :email");
query.setParameter("email", email);
if (query.getResultList().isEmpty()) {
return false;
}
else {
return true;
}
}
Here is Controller
#RequestMapping(value = "/email/{email:.+}", method = RequestMethod.GET)
public ResponseEntity<Boolean> checkEmail(#PathVariable String email) {
Boolean checkEmail = istudenciService.checkEmail(email);
if (checkEmail !=null) {
return new ResponseEntity<Boolean>(checkEmail, HttpStatus.OK);
}
else {
return new ResponseEntity<Boolean>(HttpStatus.NOT_FOUND);
}
}
At the beginning i was returning Long for email (1 and -1) and it worked, then wanted to make it boolean and all this happened.

how to get parameter when mybatis exception

I'm sorry. I can't write English well.
this is my mybatis error message(e.getMessage())
### Error updating database. Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name' at row 1
### The error may involve default.user-Inline
### The error occurred while setting parameters
### SQL: INSERT INTO USER (name) VALUES (?)
### Cause: com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name'
at row 1; SQL []; Data truncation: Data too long for column 'name' at row 1; nested exception is
com.mysql.jdbc.MysqlDataTruncation: Data truncation: Data too long for column 'name' at row 1
I want know parameter when Exception occur.
SQL: INSERT INTO USER (name) VALUES (?) >> I want get this question value.
i try this code
try {
sqlSessionTemplate.insert("namespace.id", parameter);
} catch (Exception e) {
if (e instanceof BadSqlGrammarException) {
logger.error("{}", e.getMessage());
} else if (e instanceof DataIntegrityViolationException) {
logger.error("{}", e.getMessage());
} else if (e instanceof MysqlDataTruncation) {
logger.error("{}", e.getMessage());
}
}
DataIntegrityViolationException, MysqlDataTruncation does not support get error paramters.
this is a sample, I want know get parameters(object) in Exception.
Can you give me some advice to solve this problem?Thanks.
Set up logging in MyBatis and set it to TRACE level. That way you will have your whole INSERT statement (with actually used parameters) written in the log file.
you can write a mybatis's plugin,as follow:
#Intercepts({ #Signature(type = ParameterHandler.class, method = "setParameters", args = { PreparedStatement.class }) })
public class SQLErrorContextInterceptor implements Interceptor {
private final ILogger logger = new LoggerImpl(this.getClass());
#Override
public Object intercept(Invocation invocation) throws Throwable {
invocation.proceed();
Object target=invocation.getTarget();
if( ! (target instanceof DefaultParameterHandler) ){
return null;
}
DefaultParameterHandler hander=(DefaultParameterHandler)target;
//obtains 5 fields from DefaultParameterHandler object
Class<?> clz =hander.getClass();
Field f = clz.getDeclaredField("mappedStatement");
f.setAccessible(true);
MappedStatement mappedStatement=(MappedStatement)f.get(hander);
Configuration configuration = mappedStatement.getConfiguration();
TypeHandlerRegistry typeHandlerRegistry=mappedStatement.getConfiguration().getTypeHandlerRegistry();
f=clz.getDeclaredField("boundSql");
f.setAccessible(true);
BoundSql boundSql=(BoundSql)f.get(hander);
Object parameterObject=hander.getParameterObject();
//used to stored parameters values order by sql parameters
List<Object> columnValues = new ArrayList<Object>();
// get parameters'value by for-each
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings != null) {
MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject);
for (int i = 0; i < parameterMappings.size(); i++) {
ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
value = metaObject == null ? null : metaObject.getValue(propertyName);
}
columnValues.add(value);
}
}
}
// overwrite sql's context in ErrorContext, and append parameters's value-str
ErrorContext.instance().sql(boundSql.getSql() + " parameters:" + this.getParameterValueString(columnValues));
return null;
}
private String getParameterValueString(List<Object> columnValues) {
List<Object> typeList = new ArrayList<Object>(columnValues.size());
for (Object value : columnValues) {
if (value == null) {
typeList.add("null");
} else {
typeList.add(value + "(" + value.getClass().getSimpleName() + ")");
}
}
final String parameters = typeList.toString();
return parameters.substring(1, parameters.length() - 1);
}
#Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
#Override
public void setProperties(Properties properties) {
}
}

exception in java

private String getEmailTemplateWithActualValueForAccount(String template, Account account) throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
Map<String,String> map = new HashMap<String, String>();
List<String> listTags = new ArrayList<String>();
Map<Method, String> methodList = new HashMap<Method, String>();
int startIndex=0;
int endIndex=0;
for(int i=0; i<template.length(); i++)
{
char ch = template.charAt(i);
if(ch=='$')
startIndex = i+1;
if(ch=='#')
{
endIndex = i+1;
listTags.add(template.substring(startIndex,endIndex));
}
}
Method[] methods = Account.class.getMethods();
for (Method method : methods) {
String methodName = method.getName();
if(method.getName().startsWith("get"))
{
methodList.put(method, methodName.substring(3,methodName.length()).toUpperCase()+"#");
}
}
Set<Method> methodKeySet = methodList.keySet();
for (Method method : methodKeySet) {
for (String string : listTags) {
if(methodList.get(method).equals(string))
{
try{
Object obj = method.invoke(account, null);
if(obj!=null)
map.put(string, obj.toString());
}catch(NullPointerException e){
}
}
}
}
final StringBuilder list = new StringBuilder( "\\$(" );
for( final String key: map.keySet() )
{
list.append( key );
list.append( "|" );
}
list.append( "[^\\s\\S])" );
Pattern pattern = Pattern.compile( list.toString() );
Matcher matcher = pattern.matcher( template );
final StringBuffer stringBuffer = new StringBuffer();
while( matcher.find() ){
final String string = matcher.group( 1 );
matcher.appendReplacement( stringBuffer, map.get( string ));
}
matcher.appendTail( stringBuffer );
return stringBuffer.toString();
}
I got an exception at line of code "Object obj = method.invoke(account, null);"
Code is perfectly working but as this code is in scheduler it will create an log at every 20 second on jboss server.
The invoke method of Method throws an InvocationTargetException "if the underlying method throws an exception", according to the Javadoc. So you better look into the method that you are invoking to find out why it's throwing an exception. Check the exception stack trace for the root cause.
Instead of catching NullPointerException, you should catch InvocationTargetException, and check the wrapped exception.