Исключение формата числа в compojure

Как полный новичок в clojure, я пытаюсь запустить небольшое обучающее приложение, чтобы познакомиться с compojure. Это небольшое приложение, которое позволяет пользователю складывать два числа, а после нажатия кнопки их сумма отображается на другой странице. Я следовал инструкциям из блога McGranaghan. Кажется, все в порядке, пока я не пытаюсь получить сумму двух введенных чисел, вместо получения результата меня перенаправляют на ту же страницу (так что в основном я застрял на первом шаге этого урока). После проверки кода кажется, что NumberFormatException срабатывает, когда происходит разбор ввода (по какой-то причине). Во всех своих тестах я пытался вводить все виды числового формата, но безуспешно. Вот самая простая версия кода, которая, по словам автора, должна работать (я пробовал последнюю версию с сайта github- тот же сценарий: NFE):

    (ns adder.core
  (:use compojure.core)
  (:use hiccup.core)
  (:use hiccup.page-helpers))

(defn view-layout [& content]
  (html
    (doctype :xhtml-strict)
    (xhtml-tag "en"
      [:head
        [:meta {:http-equiv "Content-type"
                :content "text/html; charset=utf-8"}]
        [:title "adder"]]
      [:body content])))

(defn view-input []
  (view-layout
    [:h2 "add two numbers"]
    [:form {:method "post" :action "/"}
      [:input.math {:type "text" :name "a"}] [:span.math " + "]
      [:input.math {:type "text" :name "b"}] [:br]
      [:input.action {:type "submit" :value "add"}]]))

(defn view-output [a b sum]
  (view-layout
    [:h2 "two numbers added"]
    [:p.math a " + " b " = " sum]
    [:a.action {:href "/"} "add more numbers"]))

(defn parse-input [a b] ;; this is the place where problem occures
  [(Integer/parseInt a) (Integer/parseInt b)])

(defroutes app
  (GET "/" []
    (view-input))

  (POST "/" [a b]
    (let [[a b] (parse-input a b)
          sum   (+ a b)]
      (view-output a b sum)))

Может ли кто-нибудь сказать мне, как лучше анализировать входные значения, чтобы избежать этого исключения? Я пробовал несколько методов, но у меня ничего не получалось. Я использую Ленинген v1.7.1 с clojure 1.3 на машине с Win 7.

Вот содержимое моего файла project.clj:

(defproject adder "0.0.1"
  :description "Add two numbers."
  :dependencies
    [[org.clojure/clojure "1.3.0"]
     [org.clojure/clojure-contrib "1.1.0"]
     [ring/ring-core "1.0.2"]
     [ring/ring-devel "1.0.2"]
     [ring/ring-jetty-adapter "1.0.2"]
     [compojure "1.0.1"]
     [hiccup "0.3.8"]]
  :dev-dependencies
    [[lein-run "1.0.0"]])

и запустите скрипт .clj:

(use 'ring.adapter.jetty)
(require 'adder.core)

(let [port (Integer/parseInt (get (System/getenv) "PORT" "8080"))]
  (run-jetty #'adder.core/app {:port port}))

Спасибо.


person Мitke    schedule 01.04.2012    source источник


Ответы (1)


Вы используете compojure 1.0.1, пример в блоге, за которым вы следите, использует compojure 0.4.0.

Начиная с версии 0.6.0, Compojure больше не добавляет промежуточное ПО по умолчанию в маршруты. Это означает, что вы должны явно добавить в свои маршруты промежуточное ПО wrap-params и wrap-cookies.

Источник: https://github.com/weavejester/compojure

Поэтому вам нужно явно добавить промежуточное ПО wrap-params. Поэтому необходимы следующие изменения...

(ns adder.core
  (:use                    ; change to idiomatic usage of :use
    [compojure.core] 
    [hiccup.core]
    [hiccup.page-helpers]
    [ring.middleware.params :only [wrap-params]])) ; add middleware for params

(defn view-layout [& content]
  (html
    (doctype :xhtml-strict)
    (xhtml-tag "en"
          [:head
           [:meta {:http-equiv "Content-type"
                   :content "text/html; charset=utf-8"}]
           [:title "adder"]]
          [:body content])))

(defn view-input []
    (view-layout
     [:h2 "add two numbers"]
     [:form {:method "post" :action "/"}
     [:input.math {:type "text" :name "a" :id "a"}] [:span.math " + "]
     [:input.math {:type "text" :name "b" :id "a"}] [:br]
     [:input.action {:type "submit" :value "add"}]]))

(defn view-output [a b sum]
  (view-layout
   [:h2 "two numbers added"]
   [:p.math a " + " b " = " sum]
   [:a.action {:href "/"} "add more numbers"]))

(defn parse-input [a b]
  [(Integer/parseInt a) (Integer/parseInt b)])

(defroutes main-routes             ; needs to be renamed
   (GET "/" []
      (view-input))

   (POST "/" [a b]
      (let [[a b] (parse-input a b)
          sum   (+ a b)]
      (view-output a b sum))))

(def app (wrap-params main-routes)) ; wrap the params to allow destructuring to work
person sw1nn    schedule 02.04.2012
comment
Спасибо за ваш ответ, я попробую это, как только смогу. - person Мitke; 02.04.2012