2013-06-24 42 views
6

我正在使用Spring MVC和Groovy將已經存在的Java Web應用程序轉換爲REST風格的Web應用程序。 我想實現的一個主要特點是熱部署。 我之所以選擇groovy是因爲我不想對已經實現的業務邏輯(處理程序)進行更改,並且如果在部署之後必須更改groovy代碼,我可以輕鬆地在不重新啓動服務器的情況下(即在運行)。 可以這樣做,因爲Spring支持動態重載groovy腳本(bean)。如果它們被更改,它將重新加載動態語言的類。使用HOT部署的Spring/REST應用程序:Groovy腳本不在tomcat啓動時的applicationContext.xml中動態加載

我使用Spring註釋來將請求URL映射到控制器方法,並且應用程序部署在tomcat 6.0.35中。

這是web.xml文件

//web.xml 

     <?xml version = "1.0" encoding = "UTF-8"?> 
     <web-app xmlns="http://java.sun.com/xml/ns/javaee" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" version="2.5"> 

     <!-- Spring Dispatcher --> 
     <servlet> 
       <servlet-name>rest</servlet-name> 
       <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> 
       <load-on-startup>1</load-on-startup> 
     </servlet> 
     <servlet-mapping> 
       <servlet-name>rest</servlet-name> 
       <url-pattern>/service/*</url-pattern> 
     </servlet-mapping> 
     <!-- Loads application context files in addition to ${contextConfigLocation} --> 
     <listener> 
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
     </listener>  

      <!-- Set session timeout to 30 minutes --> 
     <session-config> 
      <session-timeout>30</session-timeout> 
     </session-config> 
    </web-app> 

此常規文件是其中的DispatcherServlet將請求映射控制器。

// UserController.groovy 

@Controller 
class UserController 
{ 
    // This is the method to which the HTTP request is submitted to based on the mapping of the 
    // action field of the form ie. /service/user/login/auth.json 
    @RequestMapping(value="/user/login/auth.{extension:[a-zA-Z]+}", method=RequestMethod.POST) 
    @ResponseBody 
    public String authenticate(
    @PathVariable String extension, 
    @RequestParam(value="username", required=true) String username, 
    @RequestParam(value="password", required=true) String password) 
    { 
     // UserResource makes the backend calls, authenticates a user and returns the result. 
     def user = new UserResource() 
     def result = user.login(name:username, userPassword:password) 

     // Output the result of the query. Method makeView makes a JSON response of the result 
     // and sends to the client(browser) 
     def builder = makeView(extension) 
     { 
      it.login(action:result.action, message:result.message) 
     } 
    } 
    } 

Spring配置文件如下,我使用了支持動態語言的「lang:groovy」標籤。我還提到刷新時間爲5秒,以便每運行1秒就可以看到在運行時對這些groovy文件所做的任何更改,並重新加載這些類。

//applicationContext.xml 

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:lang="http://www.springframework.org/schema/lang" 
    xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:c="http://www.springframework.org/schema/c" 
    xmlns:util="http://www.springframework.org/schema/util" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
     http://www.springframework.org/schema/beans/spring-beans-3.1.xsd 
     http://www.springframework.org/schema/context 
     http://www.springframework.org/schema/context/spring-context-3.1.xsd 
     http://www.springframework.org/schema/util 
     http://www.springframework.org/schema/util/spring-util-3.1.xsd 
     http://www.springframework.org/schema/lang 
     http://www.springframework.org/schema/lang/spring-lang-3.1.xsd"> 

    <context:annotation-config/> 
    <context:component-scan base-package="app.controller,app.resource" /> 

    <lang:groovy id="user" script-source="classpath:controller/UserController.groovy" refresh-check-delay="1000"></lang:groovy> 

    <!-- To enable @RequestMapping process on type level and method level --> 
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> 
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> 

    <!-- Resolves view names to template resources within the directory --> 
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> 
     <property name="prefix" value="/"/> 
     <property name="suffix" value=".html"/> 
    </bean> 

</beans> 

我已經配置我的Buildpath,因此常規的編譯器,讓所有的Groovy腳本直接被複制到目標文件夾,而不是領編譯成class文件。

的主要問題
當我部署在Tomcat服務器這個項目,它加載所需的所有的Spring beans包括ScriptProcessor。現在,當我去我的瀏覽器,加載窗體,並嘗試提交認證形式,我得到的Tomcat以下錯誤日誌:

15:20:09 WARN - No mapping found for HTTP request with URI [/service/user/login/auth.json] in DispatcherServlet with name 'rest' 

我也曾在$ TOMCAT_DIR/conf目錄/背景下所做的更改.XML到防抱死資源和罐子

<Context antiResourceLocking="true" antiJARLocking="true" reloadable="true" privileged="true"> 
. 
. 
.</Context> 

但是,如果配置我的項目編譯那些Groovy腳本成字節碼類,註釋掉「郎鹹平:常規」標籤中applicationContext.xml中,然後重新啓動服務器, Groovy腳本被編譯成類文件,並且請求被完美地處理。身份驗證發生。另外,如果我使用以下兩行代替標籤在applicationContet.xml中配置動態bean,那麼我的bean將在運行時動態創建,並且由於註釋的原因,URL會映射到相應的控制器方法。

<bean class="org.springframework.scripting.support.ScriptFactoryPostProcessor" /> 

<bean id ="User" class="org.springframework.scripting.groovy.GroovyScriptFactory"> 
    <constructor-arg value="classpath:controller/UserController.groovy" /> 
</bean> 

但我不知道如何創建這種風格的bean刷新功能。所以我猜想標籤處理groovy腳本的方式存在問題。

我真的很感謝這方面的幫助。我在互聯網上搜索並閱讀了無數的教程,並按照上面提到的確切步驟進行操作。但我無法找出最新的錯誤。

請幫我解決這個問題。

謝謝。

回答

0

嘗試使用編譯好的Java/Groovy創建控制器,並讓它將Groovy'腳本'注入爲實現工作的依賴項。我似乎記得之前這樣做過,它可能是註釋或Spring加載控制器的方式,導致'腳本'無法正常工作。

相關問題