SpringMVC + Velocity ToolBox 環境での ParameterTool の使い方
Struts1 + Velocity のWebアプリを SpringMVC + Velocity に書き換えようとしています。
SpringMVC + Velocityのサンプルプログラムを作っている際に問題が発生しました。
以下をベースとして、ToolBoxを追加しています。
https://o7planning.org/10309/spring-mvc-and-velocity
ToolBoxに定義したorg.apache.velocity.tools.view.ParameterToolをテンプレートから呼び出すと、以下のエラーが発生してしまいました。
ParameterToolの使い方を教えていただけないでしょうか。よろしくお願いいたします。
発生している問題・エラーメッセージ
重大: Servlet.service() for servlet [spring-mvc] in context with path [/SpringMVCVelocity] threw exception [Method invocation failed during rendering of Velocity view with name 'index': Invocation of method 'get' in class org.apache.velocity.tools.view.ParameterTool threw exception java.lang.UnsupportedOperationException: Request is null. ParameterTool must be initialized first! at /WEB-INF/layouts/layout.vm[line 18, column 17]; reference [Params], method 'get'; nested exception is java.lang.UnsupportedOperationException: Request is null. ParameterTool must be initialized first!] with root cause [水 6 09 23:21:51 JST 2021]
該当のソースコード
・spring-mvc-servlet.xml抜粋
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver"> <property name="cache" value="true" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="layoutUrl" value="/WEB-INF/layouts/layout.vm" /> <property name="suffix" value=".vm" /> <property name="exposeSpringMacroHelpers" value="true"/> <property name="viewClass" value="org.springframework.web.servlet.view.velocity.VelocityLayoutView" /> <property name="toolboxConfigLocation" value="/WEB-INF/classes/velocity-toolbox.xml" /> </bean>
・layout.vm抜粋
#if($Params.xxx) $Params.xxx #else hoge #end
・velocity-toolbox.xml抜粋
<?xml version="1.0" encoding="UTF-8"?> <toolbox> <tool> <key>Params</key> <scope>request</scope> <class>org.apache.velocity.tools.view.ParameterTool</class> </tool> </toolbox>
試したこと1(ToolBoxの確認)
org.apache.velocity.tools.generic.MathToolを呼び出したところ、正常に動作しました。ToolBoxそのものは問題ないのではと考えています。
・layout.vm抜粋
#set($testVal = $Math.toInteger('100')) $testVal ##↑正常に100を表示
・velocity-toolbox.xml抜粋
<?xml version="1.0" encoding="UTF-8"?> <toolbox> <tool> <key>Math</key> <scope>application</scope> <class>org.apache.velocity.tools.generic.MathTool</class> </tool> </toolbox>
・spring-mvc-servlet.xmlは変更なし
試したこと2(類似事象の調査)
ParameterToolの類似事象として以下がありました。
https://stackoverflow.com/questions/5033541/velocity-spring
回答のリンク先からViewクラスを自作する必要があるように見受けられました(理解が間違っていたら申し訳ありません)。
https://stackoverflow.com/questions/4074484/using-velocity-tools-with-spring-3-0-3/
https://gist.github.com/bendilley/4549746
上記のクラスを作成してviewClassに設定したところ、ParameterToolのエラーは発生しなくなりましたが、(ToolBoxがうまく読み込めていないのか)定義したMathが動作せずに変数がそのまま出力($testVal)されるようになってしまいました。
・spring-mvc-servlet.xml抜粋
<bean id="viewResolver" class="org.springframework.web.servlet.view.velocity.VelocityLayoutViewResolver"> <property name="cache" value="true" /> <property name="prefix" value="/WEB-INF/views/" /> <property name="layoutUrl" value="/WEB-INF/layouts/layout.vm" /> <property name="suffix" value=".vm" /> <property name="exposeSpringMacroHelpers" value="true"/> <!-- ↓自作のクラス --> <property name="viewClass" value="org.o7planning.tutorial.springmvcvelocity.velocity.VelocityTools2View" /> <property name="toolboxConfigLocation" value="/WEB-INF/classes/velocity-toolbox.xml" /> </bean>
・layout.vm抜粋
#if($Params.xxx) $Params.xxx #else hoge #end ##↑hogeを表示(エラーにならなくなった)↓変数をそのまま表示($testVal) #set($testVal = $Math.toInteger('100')) $testVal
・velocity-toolbox.xml抜粋
<?xml version="1.0" encoding="UTF-8"?> <toolbox> <tool> <key>Params</key> <scope>request</scope> <class>org.apache.velocity.tools.view.ParameterTool</class> </tool> <tool> <key>Math</key> <scope>application</scope> <class>org.apache.velocity.tools.generic.MathTool</class> </tool> </toolbox>
・VelocityTools2View.java抜粋
private static final String TOOL_MANAGER_KEY = ViewToolManager.class.getName(); @Override protected Context createVelocityContext( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) { ServletContext application = getServletContext(); // use a shared instance of ViewToolManager ViewToolManager toolManager = (ViewToolManager)application.getAttribute(TOOL_MANAGER_KEY); if(toolManager == null) { toolManager = createToolManager(getVelocityEngine(), getToolboxConfigLocation(), application); application.setAttribute(TOOL_MANAGER_KEY, toolManager); } ViewToolContext toolContext = toolManager.createContext(request, response); if(model != null) { toolContext.putAll(model); } return toolContext; } private ViewToolManager createToolManager(VelocityEngine velocity, String toolFile, ServletContext application) { ViewToolManager toolManager = new ViewToolManager(application, false, false); toolManager.setVelocityEngine(velocity); // generic & view tools config FactoryConfiguration config = ConfigurationUtils.getVelocityView(); // user defined tools config if(toolFile != null) { FactoryConfiguration userConfig = ConfigurationUtils.load(application.getRealPath(toolFile)); config.addConfiguration(userConfig); } toolManager.configure(config); return toolManager; }
補足情報
ライブラリは以下を使っております。
・spring-core-3.2.0.M1.jar
・velocity-1.6.4.jar
・velocity-tools-2.0.jar
長文失礼しました。
springやvelocityの知識があまり無いので、
見当違いな部分もあるかもしれませんが、ご意見いただけると嬉しいです。
よろしくお願いいたします。
あなたの回答
tips
プレビュー