I am trying to pass a dynamic string builder variable in jsp I am generating a string through code. String Builder variable has some value but i am not able to pass it in at run time.It doesn't get the value.
CODE FOR VARIABLE
<%
StringBuilder sb = new StringBuilder("");
if (request.getAttribute("Brand") != null) {
String Brand[] = (String[]) request.getAttribute("Brand");
for (String brand : Brand) {
sb.append("Brand=");
sb.append(brand);
sb.append("&");
}
}
if (request.getAttribute("Flavour") != null) {
String Flavour[] = (String[]) request.getAttribute("Flavour");
for (String flavour : Flavour) {
sb.append(flavour);
sb.append("&");
}
sb.trimToSize();
pageContext.setAttribute("sb", sb);
}
out.print("this is string" + sb);
%>
CODE FOR HYPERLINK
Next</td>
You do need to add sb to the pageContext, request, session or context scope to be able to access it through an EL expression - it will not pick up variables declared only in scriptlets. Modify as follows so that that sb is always put into the pageContext:
if (request.getAttribute("Flavour") != null) {
String[] flavours = (String[]) request.getAttribute("Flavour");
for (String flavour : flavours) {
sb.append(flavour);
sb.append("&");
}
sb.trimToSize();
}
pageContext.setAttribute("sb", sb);
I have also suggested a change to improve the clarity of your code when assigning the array of 'flavour' String values.
You are setting the value to pageContext and trying to accessed via ${}. This by default refer to request scope. Try ${pageScope.sb}
Apart from that Your code looks fine, but i'm confused with the &&. Usually the URL parameter are separated by just one & symbol. Why do you need 2?
Related
Can’t convert String into json, and it seems that it will be superfluous for the entire string.
Was thinking maybe json might have helped me out here, but it doesn't seem to give me what I want or I don't know how it will be work.
How I can check the string?
I need to check:
METHOD: GET and URL: http://google.com/
also to check the BODY contains the fields userId, replId and view (no values, only keys)
I was trying to find a way to check that:
if (msg.contains("METHOD: GET") && msg.contains("URL: http://google.com/") && msg.contains("BODY: etc...")) {
System.out.println("ok");
}
It doesn't work. Some values from BODY that are dynamic and that's why for BODY the check won't pass if it’s so hardcoded String. And I guess there're any better ways to do that.
I'd like to have something like:
Assert.assertEquals(
msg,
the expected value for METHOD, which contains GET); // same here for URL: http://google.com/
Assert.assertEquals(
msg,
the expected value for BODY that has userId, replId, and view fields); // or make this assertion for each field separately, such as there is an assertion for the userId field, the same assertions for replId and view
And here's the String:
String msg = "METHOD: GET\n" +
"URL: http://google.com/\n" +
"token: 32Asdd1QQdsdsg$ff\n" +
"code: 200\n" +
"stand: test\n" +
"BODY: {\"userId\":\"11022:7\",\"bdaId\":\"110220\",\"replId\":\"fffDss0400rDF\",\"local\":\"not\",\"ttpm\":\"000\",\"view\":true}";
I can't think of any way to check that. Any ideas?
You can use the java.util.List Interface (of type String) and place the string contents into that list. Then you can use the List#contains() method, for example:
String msg = "METHOD: GET\n" +
"URL: http://google.com/\n" +
"token: 32Asdd1QQdsdsg$ff\n" +
"code: 200\n" +
"stand: test\n" +
"BODY: {\"userId\":\"11022:7\",\"bdaId\":\"110220\",\"replId\":\"fffDss0400rDF\",\"local\":\"not\",\"ttpm\":\"000\",\"view\":true}";
// Split contents of msg into list.
java.util.List<String> list = Arrays.asList(msg.split("\n"));
if (list.contains("METHOD: GET")) {
System.out.println("YUP! Got: --> 'METHOD: GET'");
}
else {
System.out.println("NOPE! Don't have: --> 'METHOD: GET'");
}
I've tried to use Assert:
String[] arr1 = msg.split("\n");
Map<String, String> allFieldsMessage = new HashMap<>();
for (String s : arr1) {
String key = s.trim().split(": ")[0];
String value = s.trim().split(": ")[1];
allFieldsMessage.put(key, value);
}
Assert.assertEquals(
allFieldsMessage.get("METHOD"),
"GET"
);
And the same for URL. But my problem is in BODY part. I thought maybe try to parse this particular part of String into json and then only check the necessary keys.
I receive a list of models. The number of models could be large. This models has a bunch of properties and any of them could be null potentially.
I need to build a string for every model based of it's properties. If property == null then I add some static part to the result string like "property1 is null".
If else property != null then I add something like this "property1 == 'valueOfThePropertyHere'".
The result string should look something like this:
prop1 == 'value1' and prop2 is null and prop3 == 'value3' and prop4 == 'value4' and prop5 is null and ..... propN == 'valueN'
And I generate such string for every model from the list.
Obviously I do this in for loop and I use StringBuilder for this. The thing is that in append method of StringBuilder I check every field of the model for null using ternary operator and based on this I add the result of this check to the result string. But if a property is not null then I need to add some static part + value of the field itself + some more static stuff. And that means I need to add one more StringBuilder for every property I have. Or I can use '+' which will be transformed into StringBuilder anyway and as far as I know it's a bad practise to use '+' inside StringBuilder (but I have to use it anyway).
Example:
List<Model> models = repository.getModels();
for (Model m: models) {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
.append(m.getField1() == null ? "field1 is null" : "field1 == '" + new StringBuiler().append(m.getField1()).append("'").append(" and ").toString()))
.append(m.getField2() == null ? "field2 is null" : "field2 == '" + new StringBuiler().append(m.getField2()).append("'").append(" and ").toString()))
...............
.append(m.getFieldN() == null ? "fieldN is null" : "fieldN == '" + new StringBuiler().append(m.getFieldN()).append("'").append(" and ").toString()));
System.out.println(stringBuilder.toString());
}
In my opinion from the performance perspective it doesn't look so well because for every model from a list of models I create another bunch of StringBuilder objects in heap just to get the result string.
Am I missing something? Are there better ways to do so from the performance perspective? Or it's okay because I don't see other options for now.
Go for simple.
Instead of
stringBuilder
.append(m.getField1() == null ? "field1 is null" : "field1 == '" + new StringBuiler().append(m.getField1()).append("'").append(" and ").toString()))
use:
if (m.getField1() == null) {
stringBuilder.append("field1 is null");
} else {
stringBuilder.append("field1 == '").append(m.getField1()).append("'").append(" and ");
}
Aside from the distinct oddness of using a StringBuilder inside a StringBuilder.append call (and why not just use + anyway...), it's really hard to parse where the : is in the conditional expression. Breaking it into lines is much easier.
If you find yourself having to repeat this code pattern a lot, define a method:
void append(StringBuilder stringBuilder, String name, Object value) {
stringBuilder.append(name);
if (value == null) {
stringBuilder.append(" is null");
} else {
stringBuilder.append(" == '").append(value).append("'").append(" and ");
}
}
and then invoke like:
append(stringBuilder, "field1", m.getField1());
append(stringBuilder, "field2", m.getField2());
append(stringBuilder, "field3", m.getField3());
What a mess! Just because you can chain invocations, doesn't mean you should:
List<Model> models = repository.getModels();
for (Model m: models) {
StringBuilder stringBuilder = new StringBuilder();
String field = m.getField1();
if(field==null) {
stringBuilder.append("field1 is null");
} else {
stringBuilder.append("field1 == ").append(m.getField1()).append("'");
}
if(stringBuilder.length()>0) {
stringBuilder.append(" and ");
}
field = m.getField2();
if(field==null) {
stringBuilder.append("field2 is null");
} else {
stringBuilder.append("field2 == ").append(m.getField1()).append("'");
}
if(stringBuilder.length()>0) {
stringBuilder.append(" and ");
}
...
System.out.println(stringBuilder.toString());
}
To avoid all this potential repetition (depending on number of fields):
void appendField(StringBuilder stringBuilder, String fieldName, String value) {
if(stringBuilder.length()>0) {
stringBuilder.append(" and ");
}
stringBuilder.append(fieldName);
if(value==null) {
stringBuilder.append(" is null");
} else {
stringBuilder.append(" == '").append(value).append("'");
}
}
String toString(Model m) {
StringBuilder stringBuilder = new StringBuilder();
appendField(stringBuilder, "field1", m.getField1());
appendField(stringBuilder, "field2", m.getField2());
...
appendField(stringBuilder, "fieldN", m.getFieldN());
return stringBuilder.toString();
}
List<Model> models = repository.getModels();
for (Model m: models) {
System.out.println(toString(m));
}
Is it possible to parse a delimited file and find column datatypes? e.g
Delimited file:
Email,FirstName,DOB,Age,CreateDate
test#test1.com,Test User1,20/01/2001,24,23/02/2015 14:06:45
test#test2.com,Test User2,14/02/2001,24,23/02/2015 14:06:45
test#test3.com,Test User3,15/01/2001,24,23/02/2015 14:06:45
test#test4.com,Test User4,23/05/2001,24,23/02/2015 14:06:45
Output:
Email datatype: email
FirstName datatype: Text
DOB datatype: date
Age datatype: int
CreateDate datatype: Timestamp
The purpose of this is to read a delimited file and construct a table creation query on the fly and insert data into that table.
I tried using apache validator, I believe we need to parse the complete file in order to determine each column data type.
EDIT: The code that I've tried:
CSVReader csvReader = new CSVReader(new FileReader(fileName),',');
String[] row = null;
int[] colLength=(int[]) null;
int colCount = 0;
String[] colDataType = null;
String[] colHeaders = null;
String[] header = csvReader.readNext();
if (header != null) {
colCount = header.length;
}
colLength = new int[colCount];
colDataType = new String[colCount];
colHeaders = new String[colCount];
for (int i=0;i<colCount;i++){
colHeaders[i]=header[i];
}
int templength=0;
String tempType = null;
IntegerValidator intValidator = new IntegerValidator();
DateValidator dateValidator = new DateValidator();
TimeValidator timeValidator = new TimeValidator();
while((row = csvReader.readNext()) != null) {
for(int i=0;i<colCount;i++) {
templength = row[i].length();
colLength[i] = templength > colLength[i] ? templength : colLength[i];
if(colHeaders[i].equalsIgnoreCase("email")){
logger.info("Col "+i+" is Email");
} else if(intValidator.isValid(row[i])){
tempType="Integer";
logger.info("Col "+i+" is Integer");
} else if(timeValidator.isValid(row[i])){
tempType="Time";
logger.info("Col "+i+" is Time");
} else if(dateValidator.isValid(row[i])){
tempType="Date";
logger.info("Col "+i+" is Date");
} else {
tempType="Text";
logger.info("Col "+i+" is Text");
}
logger.info(row[i].length()+"");
}
Not sure if this is the best way of doing this, any pointers in the right direction would be of help
If you wish to write this yourself rather than use a third party library then probably the easiest mechanism is to define a regular expression for each data type and then check if all fields satisfy it. Here's some sample code to get you started (using Java 8).
public enum DataType {
DATETIME("dd/dd/dddd dd:dd:dd"),
DATE("dd/dd/dddd",
EMAIL("\\w+#\\w+"),
TEXT(".*");
private final Predicate<String> tester;
DateType(String regexp) {
tester = Pattern.compile(regexp).asPredicate();
}
public static Optional<DataType> getTypeOfField(String[] fieldValues) {
return Arrays.stream(values())
.filter(dt -> Arrays.stream(fieldValues).allMatch(dt.tester)
.findFirst();
}
}
Note that this relies on the order of the enum values (e.g. testing for datetime before date).
Yes it is possible and you do have to parse the entire file first. Have a set of rules for each data type. Iterate over every row in the column. Start of with every column having every data type and cancel of data types if a row in that column violates a rule of that data type. After iterating the column check what data type is left for the column. Eg. Lets say we have two data types integer and text... rules for integer... well it must only contain numbers 0-9 and may begin with '-'. Text can be anything.
Our column:
345
-1ab
123
The integer data type would be removed by the second row so it would be text. If row two was just -1 then you would be left with integer and text so it would be integer because text would never be removed as our rule says text can be anything... you dont have to check for text basically if you left with no other data type the answer is text. Hope this answers your question
I have slight similar kind of logic needed for my project. Searched lot but did not get right solution. For me i need to pass string object to the method that should return datatype of the obj. finally i found post from #sprinter, it looks similar to my logic but i need to pass string instead of string array.
Modified the code for my need and posted below.
public enum DataType {
DATE("dd/dd/dddd"),
EMAIL("#gmail"),
NUMBER("[0-9]+"),
STRING("^[A-Za-z0-9? ,_-]+$");
private final String regEx;
public String getRegEx() {
return regEx;
}
DataType(String regEx) {
this.regEx = regEx;
}
public static Optional<DataType> getTypeOfField(String str) {
return Arrays.stream(DataType.values())
.filter(dt -> {
return Pattern.compile(dt.getRegEx()).matcher(str).matches();
})
.findFirst();
}
}
For example:
Optional<DataType> dataType = getTypeOfField("Bharathiraja");
System.out.println(dataType);
System.out.println(dataType .get());
Output:
Optional[STRING]
STRING
Please note, regular exp pattern is vary based on requirements, so modify the pattern as per your need don't take as it is.
Happy Coding !
I have a properties file with all the fields. dynamically I need to draw the text box with fields as read from the properties file and enter values and post it to controller in spring - java !
Example Properties File
name=String
age=int
address=string
How can I do this from java code..
For my idea, I will do it as below:
Using ajax to get fields from property file on server and return a list of field and type of field in a json format (key, value).
Now we have the data of those fields, then we generate them to your form using jquery or javascript.
Submit the form to server to get value.
Step 1 and 2 are quite easy, so I do not post the code; for step 3, you can try the method below to parse the params in query string to a map.
public static Map getMapFromQueryString(String queryString) {
Map returnMap = new HashMap();
StringTokenizer stringTokenizer = new StringTokenizer(queryString, "&");
while (stringTokenizer.hasMoreTokens()) {
String key, value;
String keyAndValue = stringTokenizer.nextToken();
int indexOfEqual = keyAndValue.indexOf("=");
if (indexOfEqual >= 0) {
key = keyAndValue.substring(0, indexOfEqual);
if ((indexOfEqual + 1) < keyAndValue.length()) {
value = keyAndValue.substring(indexOfEqual + 1);
} else {
value = "";
}
} else {
key = keyAndValue;
value = "";
}
if (key.length() > 0) returnMap.put(key, value);
}
return returnMap;
}
Now you can get all the value of dynamic fields on the form.
Hope this solution is helpful for you.
I've got a really simple code snippet that I'm trying to move into two methods but for the life of me can't figure out what I'm doing wrong, here is the code currently:
if (chatLayer != null) {
Page checkPage = resource.resourceResolver.getResource(url).adaptTo(Page);
url = (checkPage) ? ".html" : "";
} else {
PageManager manager = resource.getResourceResolver().adaptTo(PageManager.class);
String currentPage = manager.getContainingPage(resource).getPath();
url = "&refer="+currentPage;
}
When I try to turn it into methods:
url = chatLayer ? chatOverlay() : chatURL()
private static String chatOverlay(Page checkPage, String url) {
Page checkPage = resource.resourceResolver.getResource(url).adaptTo(Page);
url = (checkPage) ? ".html" : "";
}
private static String chatURL(Page checkPage, String url) {
PageManager manager = resource.getResourceResolver().adaptTo(PageManager.class);
String currentPage = manager.getContainingPage(resource).getPath();
url = "&refer="+currentPage;
}
All I get as an error is a current scope already contains a variable of checkpage. Any help is greatly appreciated. I'm a newbie so modifications to my code or code snippets is greatly appreciated.
In your method chatOverlay you have a Page checkPage parameter and a Page checkPage local variable. Change the name of one of them. Additional: you're not returning anything from your methods (not sure if this is a typo).
private static String chatOverlay(Page checkPage, String url) {
//changed the name of the local variable
Page checkedPage = resource.resourceResolver.getResource(url).adaptTo(Page);
url = (checkedPage) ? ".html" : "";
return url;
}
private static String chatOverlay(Page checkPage, String url) {
Page checkPage = resource.resourceResolver.getResource(url).adaptTo(Page);
url = (checkPage) ? ".html" : "";
}
You already have a variable named checkPage as one of your method parameters. You can't have two variables named checkPage in your method -- how would the compiler know which variable you are referring to?