trimming parameter before sending to controller in playframework - java

In my web app,I need to get a user entered number and process it in the controller.I need to make sure that the number is at least 14 digits in length.If the user enters 12 digits and then presses 'space' twice ,the validation should catch it.
I coded it like this
public static void processNumber(#Required #MinSize(value=14,message="min size is 14") String inputNumber){
if(validation.hasErrors()) {
params.flash();
validation.keep();
...
}
}
However ,this doesn't work as I expected..Looks like ,I need to trim the input before it reaches the controller method.
Can someone suggest how to do this?
p.s:
More complex cases will be input like
'11 2233444444'
'1122334ad44444' etc,is there any validation to make sure that the input is a number and does not contain any alphabetic characters?

I don't think a custom binder is going to give you what you are looking for, as you are not trying to modify the way the data is bound, but to validate what is in there. Therefore, I think what you are looking for is a custom validator.
See here for more information - http://www.playframework.org/documentation/1.2/validation#custom
But effectively, you can just use the #CheckWith annotation to specify which validator to use, and then in your validator, you can check that your trimmed string, contains no spaces, and no alpha characters etc.
Note, that the validator will not modify your input, so if you want to ignore trimmed data, then this will continue to stay in your data, so you can therefore modify (trim) it after it is validated, or you could do it using the custom binder as discussed in the other answer.

Please check if that could help you on what you want to do link
I hope it helped.

If you want to have a numeric value with at least 14 digits, one option would be:
public static void processNumber(#Required #Min(10000000000000) Long inputNumber)
Problems with this method:
Maximum allowed number would be 9223372036854775807l
It won't allow numbers starting with "0".
Some more options:
public static void processNumber(
#Required #MinSize(value=14,message="min size is 14") String inputNumber){
validation.isTrue("inputNumber", !inputNumber.contains(" "));
if(validation.hasErrors()) {
Or even better:
public static void processNumber(
#Required #MinSize(value=14,message="min size is 14") String inputNumber){
for(int i=0;i<inputNumber.length();i++) {
validation.isTrue("inputNumber", Character.isDigit(inputNumber.charAt(i)))
if(validation.hasErrors()) {

Related

NumberFormat doesn't crash with 2 decimal separators

I have a question regarding the behavior of the NumberFormat:
When I want to translate/parse a formatted String into a Number, then I would like to use NumberFormat, since it provides me with nice presets for thousand and decimal separators. Additionally I would like it to crash, if the provided String is not a valid Number.
An example:
// works as expected
String testInput1 = "3,1415";
NumberFormat germanNumberFormat = NumberFormat.getInstance(Locale.GERMANY);
Number number1 = germanNumberFormat.parse(testInput1);
System.out.println(number1); // prints 3.1415
// does not work as expected, cuts off the number after the 2nd decimal
// separator, expected it to crash with java.lang.NumberFormatException:
// multiple points
String testInput2 = "3,14,15";
Number number2 = germanNumberFormat.parse(testInput2);
System.out.println(number2); // prints 3.14
I currently use Double.parseDouble(String s), to have this additional behavior:
// crashes with java.lang.NumberFormatException: multiple points
double number2WithError = Double.parseDouble(testInput2.replace(",", "."));
Is there a way I can use NumberFormat to have my required/expected behavior besides writing my own wrapper class that does some additional checks on e.g. multiple decimal separators?
Also I'm aware that the JavaDoc of the used parse(String source) method of NumberFormat says:
Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.
See the {#link #parse(String, ParsePosition)} method for more information on number parsing.
and parse(String source, ParsePosition parsePosition):
Returns a Long if possible (e.g., within the range [Long.MIN_VALUE, Long.MAX_VALUE] and with no decimals), otherwise a Double. If IntegerOnly is set, will stop at a decimal point (or equivalent; e.g., for rational numbers "1 2/3", will stop after the 1). Does not throw an exception; if no object can be parsed, index is unchanged!
This doesn't tell me though why the method behaves this way. What I get from these is that they can parse only parts of the String (what they obviously do here) and probably just start parsing at the beginning (start position) until they find something they can't deal with.
I didn't find an existing question covering this, so if there is already one, please feel free to close this post and please link to it.
NumberFormat.parse(String) is behaving exactly as documented:
Parses text from the beginning of the given string to produce a number. The method may not use the entire text of the given string.
(Emphasis added)
You ask:
Is there a way I can use NumberFormat to have my required/expected behavior besides writing my own wrapper class that does some additional checks on e.g. multiple decimal separators?
You cannot provide a format that will make NumberFormat.parse() throw an exception for input with only an initial substring that can be parsed according to the format. You can, however, use NumberFormat.parse(String, ParsePosition) to determine whether the whole input was parsed, because the parse position argument is used not only to indicate to the method where to start, but also for the method to say where it stopped. That would be a lot better than implementing format-specific extra checks. Example:
ParsePosition position = new ParsePosition(0);
Number result = format.parse(input, position);
if (position.getIndex() != input.length()) {
throw new MyException();
}
Additionally, you write:
This doesn't tell me though why the method behaves this way.
It behaves that way because sometimes parsing the initial portion of the input is exactly what you want to do. You can build stricter parsing on top of more relaxed parsing, as shown, but it's much more difficult to do it the other way around.

Getting each different numbers separately and examining them in java

I am new to java and i want to make a program where i want to get the integers the user has input, and look at what different numbers they are. and move them around as well as add stuff between them.
For example:
Enter number
User input: 123456
after that i want to see what the first number is, which is 1 or what the third number is which is 3. i want to be able to get those different information. and play around with them, for example add the sixth and the first number and print it out for the user.
Which technique in java allows me to do that, what is the name so i could study it more.
if there is a video online teaching that, it would also be great.
Thanks.
ps. i know the basics, i dont need to know how to do the second part playing with the numbers i just dont know how to tell what the first or second number in the lists of number is.
Eg: 123456
Convert the int to string keep the int also
1) String.valueOf(number)
2) Integer.toString(number)
get the length of the string using String.length();
the if you want the 3rd number
Use the int value for the following operation
Eg: 123456 (3rd number 3) Since you have the length of the string you know what will be the divisor
divide using 10 * 10 * 10 this will 123456/1000 = 123
Then % it with 10 always you can put these within a methos to get any position
Try the below code :You are taking an integer input and converting it into a string
public class InputNumberProgram {
public static void main(String[] args) {
Integer i = 5678;
// Convert your input to a string
String s = Integer.toString(i);
System.out.println("Length of input:" + s.length()); System.out.println(Integer.parseInt(s.valueOf(s.charAt(0)))+Integer.parseInt(s.valueOf(s.charAt(1))));
}
}
If you read it as a String and do what you want with String methods
For example you have String number. To get i-th symbol you can use number.charAt(i)

textinput restrict to accept number with four decimal precision

I have a textfield in which I want to restrict user to enter only valid number with 14 digit before .(dot) and 4 digit after .(dot).
I have tried it using :
<mx:TextInput id="txtValue1" restrict="[0-9]*\.?[0-9]" maxChars="19"/>
Its not working for restriction 4 digit after .(dot).
A more common way would be to use a NumberValidator, and set the precision attribute of the validator to 4. Also, set the maxValue of the NumberValidator to whatever suits, then set the source of the NumberValidator to the textInput id. That should work I'd say, and it will also allow you to set the error fields of the validator which will pop up beside the textInput if incorrect number is entered
you can view and download a code (this works!) in my public repository from this LINK.
Basically, i created a class (NumberInput) based on TextInput class from Adobe, the diferrence in both classes was the textFieldChanged method, i add a call here to myFormat function(). This function does what you're needing.
Be careful with this class, do not use it as the final solution but I will anyway to find what you need. Check the SWF called NumberInputTest.swf, source code is in src\NumberInput.as.
I hope this help you. Sorry for my english :D.

Printing an ArrayList of Strings to a PrintWriter with word wrap

Some classmates and I are working on a homework assignment for Java that requires we print an ArrayList of Strings to a PrintWriter using word wrap, so that none of the output passes 80 characters. We've extensively Googled this and can't find any Java API based way to do this.
I know it's generally "wrong" to ask a homework question on SO, but we're just looking for recommendations of the best way to do this, or if we missed something in the API. This isn't the major part of the homework, just a small output requirement.
Ideally, I'd like to be able to wordwrap the ArrayList's toString since it's nicely formatted already.
Well, this is a first for me, it's the first time one of my students has posted a question about one of the projects I've assigned them. The way it was phrased, that he was looking for an algorithm, and the answers you've all shared are just fine with me. However, this is a typical case of trying to make things too complicated. A part of the spec that was not mentioned was that the 80 characters limit was not a hard limit. I said that each line of the output file had to be roughly 80 characters long. It was OK to go over 80 a little. In my version of the solution, I just had a running count and did a modulus of the count to add the line end. I varied the value of the modulus until the output file looked right. This resulted in lines with small numbers being really short so I used a different modulus when the numbers were small. This wasn't a big part of the project and it's interesting that this got so much attention.
Our solution was to create a temporary string and append elements one by one, followed by a comma. Before adding an element, check if adding it will make the string longer than 80 characters and choose whether to print it and reset or just append.
This still has the issue with the extra trailing comma, but that's been dealt with so many times we'll be fine. I was looking to avoid this because it was originally more complicated in my head than it really is.
I think that better solution is to create your own WrapTextWriter that wraps any other writer and overrides method public void write(String str, int off, int len) throws IOException. Here it should run in loop and perform logic of wrapping.
This logic is not as simple as str.substring(80). If you are dealing with real text and wish to wrap it correctly (i.e. do not cut words, do not move comas or dots to the next line etc) you have to implement some logic. it is probably not too complicated but probably language dependent. For example in English there is not space between word and colon while in French they put space between them.
So, I performed 5 second googling and found the following discussion that can help you.
private static final int MAX_CHARACTERS = 80;
public static void main(String[] args)
throws FileNotFoundException
{
List<String> strings = new ArrayList<String>();
int size = 0;
PrintWriter writer = new PrintWriter(System.out, true); // Just as example
for (String str : strings)
{
size += str.length();
if (size > MAX_CHARACTERS)
{
writer.print(System.getProperty("line.separator") + str);
size = 0;
}
else
writer.print(str);
}
}
You can simply write a function, like "void printWordWrap(List<String> strings)", with that algorithm inside. I think, it`s a good way to solve your problem. :)

small java problem

Sorry if my question sounds dumb. But some time small things create big problem for you and take your whole time to solve it. But thanks to stackoverflow where i can get GURU advices. :)
So here is my problem. i search for a word in a string and put 0 where that word occur.
For example : search word is DOG and i have string "never ever let dog bite you" so the string
would be 000100 . Now when I try to convert this string into INT it produce result 100 :( which is bad. I also can not use int array i can only use string as i am concatinating it, also using somewhere else too in program.
Now i am sure you are wondering why i want to convert it into INT. So here my answer. I am using 3 words from each string to make this kind of binary string. So lets say i used three search queries like ( dog, dog, ever ) so all three strings would be
000100
000100
010000
Then I want to SUM them it should produce result like this "010200" while it produce result "10200" which is wrong. :(
Thanks in advance
Of course the int representation won't retain leading zeros. But you can easily convert back to a String after summing and pad the zeros on the left yourself - just store the maximum length of any string (assuming they can have different lengths). Or if you wanted to get even fancier you could use NumberFormat, but you might find this to be overkill for your needs.
Also, be careful - you will get some unexpected results with this code if any word appears in 10 or more strings.
Looks like you might want to investigate java.util.BitSet.
You could prefix your value with a '1', that would preserve your leading 0's. You can then take that prefix into account you do your sum in the end.
That all is assuming you work through your 10 overflow issue that was mentioned in another comment.
Could you store it as a character array instead? Your using an int, which is fine, but your really not wanting an int - you want each position in the int to represent words in a string, and you turn them on or off (1 or 0). Seems like storing them in a character array would make more sense.

Categories

Resources