Spring MVC と Groovy を使用して、既存の Java Web アプリケーションを RESTful Web アプリケーションに変換しようとしています。私が達成したかった主な機能の 1 つは、HOT DEPLOYMENT でした。既に実装されているビジネス ロジック (ハンドラー) を変更したくなかったため、groovy を選択しました。また、展開後に Groovy コードを変更する必要がある場合は、サーバーを再起動せずに (つまり、実行時に) 簡単に変更できます。 )。これは、Spring が Groovy スクリプト (Bean) の動的リロードをサポートしているため可能です。動的言語のクラスが変更された場合、それらのクラスを再読み込みします。
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>
この groovy ファイルは、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 秒であると述べました。これにより、実行時にこれらの groovy ファイルに加えられた変更が 1 秒ごとに表示され、クラスがリロードされます。
//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 コンパイラを構成し、すべての groovy スクリプトがクラス ファイルにコンパイルされるのではなく、ターゲット フォルダーに直接コピーされるようにしました。
主な問題
このプロジェクトを Tomcat サーバーにデプロイすると、ScriptProcessor を含む必要なすべての Spring Bean がロードされます。ここで、ブラウザにアクセスしてフォームをロードし、認証フォームを送信しようとすると、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/context.xml にも変更を加えて、アンチロック リソースと JARS を作成しました。
<Context antiResourceLocking="true" antiJARLocking="true" reloadable="true" privileged="true">
.
.
.</Context>
ただし、これらの Groovy スクリプトをバイトコード クラスにコンパイルするようにプロジェクトを構成し、applicationContext.xml の「lang:groovy」タグをコメント アウトしてからサーバーを再起動すると、Groovy スクリプトがクラス ファイルにコンパイルされ、要求が完全に処理されます。 . 認証が行われます。
また、タグの代わりに次の 2 行を使用して 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 スクリプトを処理する方法に問題があると思います。
これについて何か助けていただければ幸いです。私はインターネット全体を検索し、無数のチュートリアルを読み、そこに記載されている正確な手順に従いました. しかし、何が問題なのかわかりません。
この問題を解決するのを手伝ってください。
ありがとうございました。