Подтвердить что ты не робот

Как избежать исключения формата номера в java?

В моей повседневной разработке веб-приложений есть много примеров, когда нам нужно принимать некоторые данные от пользователя.

Затем передайте этот ввод номера, который может быть служебным или DAO-слоем приложения.

На каком-то этапе, начиная с его числа (integer или float), нам нужно преобразовать его в Integer, как показано в следующем фрагменте кода.

String cost = request.getParameter("cost");

if (cost !=null && !"".equals(cost) ){
    Integer intCost = Integer.parseInt(cost);
    List<Book> books = bookService . findBooksCheaperThan(intCost);  
}

Здесь, в приведенном выше случае, я должен проверить, не является ли вход не нулевым или нет ввода (пустой), или иногда есть возможность ввода не числовых символов, например. бла, тест и т.д.

Каков наилучший способ решения таких ситуаций?

4b9b3361

Ответ 1

Просто поймайте свое исключение и выполните правильную обработку исключений:

if (cost !=null && !"".equals(cost) ){
        try {
           Integer intCost = Integer.parseInt(cost);
           List<Book> books = bookService . findBooksCheaperThan(intCost);  
        } catch (NumberFormatException e) {
           System.out.println("This is not a number");
           System.out.println(e.getMessage());
        }
    }

Ответ 2

Как всегда, у Джакартских общин есть хотя бы часть ответа:

NumberUtils.isNumber()

Это можно использовать для проверки большинства, является ли данная строка номером. Вы все еще должны выбрать, что делать, если ваша строка не является числом...

Ответ 3

Исключения в последних версиях Java недостаточно дороги, чтобы сделать их предотвращение важным. Используйте предложенный вами блок try/catch; если вы поймаете исключение на ранней стадии процесса (т.е. сразу после того, как пользователь ввел его), тогда у вас не будет проблемы в этом процессе (потому что в любом случае это будет правильный тип).

Исключения были намного дороже, чем сейчас; не оптимизируйте производительность до тех пор, пока не узнаете, что исключения действительно вызывают проблему (и они не будут здесь).

Ответ 4

одна возможность: уловить исключение и показать сообщение об ошибке в интерфейсе пользователя.

edit: добавьте прослушиватель в поле внутри gui и проверьте входные данные там тоже, с этим решением случай исключения должен быть очень редок...

Ответ 5

Документация для метода из Apache Commons Lang (отсюда):

Проверяет, является ли строка допустимым номером Java.

Допустимые числа включают шестнадцатеричные, отмеченные с помощью классификатора 0x, научной нотации и числа, помеченные квалификатором типа (например, 123L).

Null и пустая строка вернет false.

Параметры:

`str` - the `String` to check

Возврат:

`true` if the string is a correctly formatted number

isNumber из java.org.apache.commons.lang3.math.NumberUtils:

public static boolean isNumber(final String str) {
    if (StringUtils.isEmpty(str)) {
        return false;
    }
    final char[] chars = str.toCharArray();
    int sz = chars.length;
    boolean hasExp = false;
    boolean hasDecPoint = false;
    boolean allowSigns = false;
    boolean foundDigit = false;
    // deal with any possible sign up front
    final int start = (chars[0] == '-') ? 1 : 0;
    if (sz > start + 1 && chars[start] == '0' && chars[start + 1] == 'x') {
        int i = start + 2;
        if (i == sz) {
            return false; // str == "0x"
        }
        // checking hex (it can't be anything else)
        for (; i < chars.length; i++) {
            if ((chars[i] < '0' || chars[i] > '9')
                && (chars[i] < 'a' || chars[i] > 'f')
                && (chars[i] < 'A' || chars[i] > 'F')) {
                return false;
            }
        }
        return true;
    }
    sz--; // don't want to loop to the last char, check it afterwords
          // for type qualifiers
    int i = start;
    // loop to the next to last char or to the last char if we need another digit to
    // make a valid number (e.g. chars[0..5] = "1234E")
    while (i < sz || (i < sz + 1 && allowSigns && !foundDigit)) {
        if (chars[i] >= '0' && chars[i] <= '9') {
            foundDigit = true;
            allowSigns = false;

        } else if (chars[i] == '.') {
            if (hasDecPoint || hasExp) {
                // two decimal points or dec in exponent   
                return false;
            }
            hasDecPoint = true;
        } else if (chars[i] == 'e' || chars[i] == 'E') {
            // we've already taken care of hex.
            if (hasExp) {
                // two E's
                return false;
            }
            if (!foundDigit) {
                return false;
            }
            hasExp = true;
            allowSigns = true;
        } else if (chars[i] == '+' || chars[i] == '-') {
            if (!allowSigns) {
                return false;
            }
            allowSigns = false;
            foundDigit = false; // we need a digit after the E
        } else {
            return false;
        }
        i++;
    }
    if (i < chars.length) {
        if (chars[i] >= '0' && chars[i] <= '9') {
            // no type qualifier, OK
            return true;
        }
        if (chars[i] == 'e' || chars[i] == 'E') {
            // can't have an E at the last byte
            return false;
        }
        if (chars[i] == '.') {
            if (hasDecPoint || hasExp) {
                // two decimal points or dec in exponent
                return false;
            }
            // single trailing decimal point after non-exponent is ok
            return foundDigit;
        }
        if (!allowSigns
            && (chars[i] == 'd'
                || chars[i] == 'D'
                || chars[i] == 'f'
                || chars[i] == 'F')) {
            return foundDigit;
        }
        if (chars[i] == 'l'
            || chars[i] == 'L') {
            // not allowing L with an exponent or decimal point
            return foundDigit && !hasExp && !hasDecPoint;
        }
        // last character is illegal
        return false;
    }
    // allowSigns is true iff the val ends in 'E'
    // found digit it to make sure weird stuff like '.' and '1E-' doesn't pass
    return !allowSigns && foundDigit;
}

[код находится под версией 2 лицензии Apache]

Ответ 6

public class Main {
    public static void main(String[] args) {

        String number;

        while(true){

            try{
                number = JOptionPane.showInputDialog(null);

                if( Main.isNumber(number) )
                    break;

            }catch(NumberFormatException e){
                System.out.println(e.getMessage());
            }

        }

        System.out.println("Your number is " + number);

    }

    public static boolean isNumber(Object o){
        boolean isNumber = true;

        for( byte b : o.toString().getBytes() ){
            char c = (char)b;
            if(!Character.isDigit(c))
                isNumber = false;
        }

        return isNumber;
    }

}

Ответ 7

Определить, является ли строка Int или Float и представлять в более длинном формате.

Integer

 String  cost=Long.MAX_VALUE+"";
  if (isNumeric (cost))    // returns false for non numeric
  {  
      BigInteger bi  = new BigInteger(cost);

  }

public static boolean isNumeric(String str) 
{ 
  NumberFormat formatter = NumberFormat.getInstance(); 
  ParsePosition pos = new ParsePosition(0); 
  formatter.parse(str, pos); 
  return str.length() == pos.getIndex(); 
} 

Ответ 8

Я предлагаю сделать 2 вещи:

  • подтвердите ввод на стороне клиента, прежде чем передавать его в Servlet
  • поймать исключение и показать сообщение об ошибке в интерфейсе пользователя, как упоминалось в Тобиаске. Этот случай, как правило, не бывает, но никогда не доверяйте своим клиентам.; -)

Ответ 9

Вы можете избежать неприятного поиска try/catch или regex с помощью класса Scanner:

String input = "123";
Scanner sc = new Scanner(input);
if (sc.hasNextInt())
    System.out.println("an int: " + sc.nextInt());
else {
    //handle the bad input
}

Ответ 10

Попробуйте преобразовать Prize в десятичный формат...

import java.math.BigDecimal;
import java.math.RoundingMode;

public class Bigdecimal {
    public static boolean isEmpty (String st) {
        return st == null || st.length() < 1; 
    }
    public static BigDecimal bigDecimalFormat(String Preis){        
        //MathContext   mi = new MathContext(2);
        BigDecimal bd = new BigDecimal(0.00);

                         bd = new BigDecimal(Preis);


            return bd.setScale(2, RoundingMode.HALF_UP);

        }
    public static void main(String[] args) {
        String cost = "12.12";
        if (!isEmpty(cost) ){
            try {
               BigDecimal intCost = bigDecimalFormat(cost);
               System.out.println(intCost);
               List<Book> books = bookService.findBooksCheaperThan(intCost);  
            } catch (NumberFormatException e) {
               System.out.println("This is not a number");
               System.out.println(e.getMessage());
            }
        }

}
}

Ответ 11

Я не знаю о недостатках во время выполнения, но вы можете запустить регулярное выражение в своей строке, чтобы убедиться, что это число, прежде чем пытаться его проанализировать, тем самым

cost.matches("-?\\d+\\.?\\d+")

для поплавка

и

cost.matches("-?\\d+")

для целого числа

ИЗМЕНИТЬ

Пожалуйста, отметьте комментарий @Voo о max int

Ответ 12

В Java, к сожалению, вы не можете избежать использования функции parseInt и просто перехватывать исключение. Хорошо, что вы могли бы теоретически написать собственный синтаксический анализатор, который проверяет, является ли это числом, но тогда вам больше не нужен parseInt.

Метод regex проблематичен, потому что ничто не мешает кому-то включать число > INTEGER.MAX_VALUE, которое пройдет тест регулярных выражений, но все равно сработает.

Ответ 13

Это зависит от вашей среды. Например, JSF взял бы на себя ответственность за ручную проверку и преобразование строк и lt; → Numbers из вас, Bean Валидация - это еще одна опция.

Что вы можете сделать сразу в предоставленном фрагменте:

  • Извлечь метод getAsInt(String param), в нем:
  • Используйте String.isEmpty() (Поскольку Java 6),
  • surround с try / catch

Что вы должны определенно думать о том, что вам приходится писать много кода следующим образом:

public void myBusinessMethod(@ValidNumber String numberInput) {
// ...    
}

(Это будет основано на перехватчике).

И последнее, но не менее важное: Сохраните работу и попытайтесь перейти к структуре, которая дает вам поддержку для этих общих задач...