Разбор целых чисел из строк при проверке составных запросов в Clojure

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

(defn get-int [str]
  "Returns nil if str is not a number"
  (try (Integer/parseInt str)
    (catch NumberFormatException _)))

(defn some-request [request]
    (let [some-number (get-int (get-in request [:route-params :some-number])
         other-number (get-int (get-in request [:route-params :other-number])]
    (if (every? identity [some-number other-number])
        (process-the-request)
        (bad-request "The request was malformed")))

Есть ли лучший способ сделать преобразование строки -> числа?

Есть ли лучший способ сделать проверку запроса?


person Odinodin    schedule 29.08.2012    source источник


Ответы (2)


Этот вопрос содержит хорошие примеры для анализа чисел в Clojure . Если вы не уверены, что строка содержит действительное число, ваш подход выглядит хорошо.

Если вы можете передать параметры как часть строки запроса, вы можете использовать маршрут с регулярным выражением для получения значения, например.

(GET ["/user/:id", :id #"[0-9]+"] [id] 
  (let [num (read-string id)]
    (str "The number is: " num)))

Маршрут будет соответствовать только в том случае, если будут выполнены условия регулярного выражения, поэтому вы можете пропустить проверку Integer/parseInt.

person raju-bitter    schedule 29.08.2012
comment
Возможно, вы захотите привязать *read-eval* к false, если вы используете read-string для пользовательского ввода. - person Hugh; 30.08.2012
comment
@Huw Разве того факта, что строка id здесь соответствует регулярному выражению [0-9]+, не будет достаточно, чтобы предотвратить какой-либо вред в этом случае? - person Alex Jasmin; 30.08.2012
comment
Готов поклясться, что этого не было, когда я писал свой комментарий :) - person Hugh; 30.08.2012
comment
теперь есть встроенная поддержка принуждения, [id :<< as-int], см. github.com/weavejester/compojure/wiki /Деструктуризация-Синтаксис - person Feng; 10.01.2016

Используйте Long/parseLong вместо Integer/parseInteger. Последний поддерживает только 32 бита, чего часто бывает недостаточно; например, идентификаторы объектов Datomic не вписываются в Integer.

Никогда не используйте read-string для пользовательского ввода. Кроме того, вы должны дезинфицировать пользовательский ввод, удаляя внедряемые скрипты и тому подобное. https://github.com/alxlit/autoclave — хорошее начало, хотя значения по умолчанию, возможно, слишком агрессивный.

person Nelo Mitranim    schedule 28.09.2017