Is there a way to get the HttpServletRequest object in Noir?

178 views
Skip to first unread message

Yixun Fang

unread,
Nov 1, 2011, 5:51:15 AM11/1/11
to clj-noir
Is there a way to get the HttpServletRequest object in Noir?
I need to get the HttpServletRequest obj when handling a URI. So I use
the (noir.request.ring-request) function to get back the ring request
map which contains :servlet-request key, but the value is nil. Is this
the right way to do it or do I miss something?

following is the code:

(ns my-app
(:use noir.request))
(defpage [:get "/app"] []
(str (ring-request)))

the result:

{:remote-addr "127.0.0.1", :scheme :http, :query-params
{}, :session {}, :form-params {}, :multipart-params {}, :servlet
#, :request-method :get, :query-string nil, :content-type
nil, :cookies {"ring-session" {:value "eb509a65-d33a-40d2-9646-
e2ff785428b0"}}, :uri "/app", :server-name "127.0.0.1", :params
{}, :headers {"cookie" "ring-session=eb509a65-d33a-40d2-9646-
e2ff785428b0", "accept-charset" "GBK,utf-8;q=0.7,*;q=0.3", "accept-
language" "en-US,en;q=0.8,zh-CN;q=0.6,zh;q=0.4", "accept-encoding"
"gzip,deflate,sdch", "accept" "text/html,application/xhtml
+xml,application/xml;q=0.9,*/*;q=0.8", "user-agent" "Mozilla/5.0
(Windows NT 5.1) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/
15.0.874.106 Safari/535.2", "connection" "keep-alive", "host"
"127.0.0.1:8080"}, :servlet-request #, :content-length nil, :server-
port 8080, :character-encoding nil, :servlet-response #, :body
#, :servlet-context #}

James Reeves

unread,
Nov 1, 2011, 6:01:54 AM11/1/11
to clj-...@googlegroups.com
On 1 November 2011 09:51, Yixun Fang <fang...@gmail.com> wrote:
> Is there a way to get the HttpServletRequest object in Noir?
> I need to get the HttpServletRequest obj when handling a URI. So I use
> the (noir.request.ring-request) function to get back the ring request
> map which contains :servlet-request key, but the value is nil.

It doesn't look like it's nil from the output you provide. Your output
shows the :servlet-request key value as being "#".

Try running "view source" in your browser when you access the page. I
suspect you're only seeing a "#" because anything within <> is eaten
by the browser.

- James

Chris Granger

unread,
Nov 1, 2011, 11:25:41 PM11/1/11
to clj-...@googlegroups.com
Unless I'm mistaken, those keys aren't part of the ring spec, and are actually provided only in certain contexts... namely when actually deployed as a servlet. As such, if you're running Noir with Jetty, they won't be there.


A more important question, however, is why you need the HttpServletRequest?

Cheers,
Chris.

Yixun Fang

unread,
Nov 2, 2011, 1:25:23 AM11/2/11
to clj-...@googlegroups.com
Thanks Chris. 

Actually I need to integrate some legacy code which use Spring into my noir app. I want to get some beans from the Spring WebApplicationContext. 
So I use  (WebApplicationContextUtils/getWebApplicationContext (:servlet-context (ring-request))).
The strange things is I can use the getWebApplicationContext method to get the WebApplicationContext object and then get bean from it, but the console also show the following exception each time I call the it:

java.lang.IllegalArgumentException: ServletContext must not be null
        at org.springframework.util.Assert.notNull(Assert.java:112)
        at org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:109)
        at org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext(WebApplicationContextUtils.java:99)

Yixun Fang

unread,
Nov 2, 2011, 1:37:18 AM11/2/11
to clj-...@googlegroups.com
Thanks, James.

You are right. When I run with lein run, the :servlet-request is not nil. The code I start Jetty is as follow:

(ns foo.server
  (:require [noir.server :as server]))

(server/load-views-ns 'foo.views)
(server/load-views-ns 'foo.svc)

(defn- boot-spring [server handler context-config-location]
    (let [servlet (doto (org.mortbay.jetty.servlet.ServletHolder. (ring.util.servlet/servlet handler)) (.setName "default"))
          context (doto (org.mortbay.jetty.servlet.Context. server "/") (.addServlet servlet "/")
                        (.addEventListener (org.springframework.web.context.ContextLoaderListener.)))]
        (when context-config-location
            (.setInitParams context {"contextConfigLocation" context-config-location}))
        (.addHandler server context)))

(def handler (server/gen-handler {:mode :dev
                                  :ns 'foo}))

(defn -main [& m]
  (let [mode (keyword (or (first m) :dev))
        port (Integer. (get (System/getenv) "PORT" "8080"))
        configurator (fn [server] (boot-spring server handler "classpath:applicationContext.xml"))]
    (server/start port {:mode mode
                        :jetty-options {:configurator configurator}
                        :ns 'foo})))


But when I use lein ring uberwar to generate a war and deploy to Resin, the :servlet-request is nil. May I miss something in order to deploy the app to a container. I'll dig further.


John Kurkowski

unread,
Nov 24, 2012, 5:50:12 AM11/24/12
to clj-...@googlegroups.com
Find anything in your dig?

Chris, I'm interested in the original HttpServletRequest for interop with a Java library, wro4j, whose major entry point is a javax.servlet.Filter. I've got pretty far proxying between the ring-request map and HttpServletRequest per this SO answer, but it's getting janky. Some fields I'm unsure what I should be returning, particularly behavioral ones like getRequestDispatcher. What is that supposed to be in the Noir ecosystem? Anyway the deeper I go down this rabbit hole the more I just want a ready HttpServletRequest.

Chris Granger

unread,
Nov 24, 2012, 12:01:19 PM11/24/12
to clj-noir
This is something better asked on the ring list since I'm not a java guy by any stretch of the imagination and this is all handled at that level :)

Cheers,
Chris.
Reply all
Reply to author
Forward
0 new messages