2009-07-14 22 views
1

実際の質問は次のとおりです。XmlWebApplicationContextにコンテキストの相対パスを使用してリソースを読み込ませる方法はありますか?わかりやすくするため、「コンテキストの場所」はsetConfigLocation()メソッドで指定された最初のファイルの場所です。Springによる相対リソースパスの指定XmlWebApplicationContext

詳細な説明は次のとおりです。
私は中間層のWeb層とSpring IOCでSpring MVCを使用しています。適切なコンテキストは、Spring Documentationに記載されているように階層的に定義されています。ウェブの内容はmy-servlet.xmlで定義され、servicesなどはContextLoaderListenerによってロードされるservices.xmlで定義されます。中間層は、Web層(例えば、すべてがServletContainer内で実行される)または別個に展開することもできます(この場合、services.xmlは、リモートスタブを定義するremote-services.xmlに置き換えられます)。

services.xmlと同じフォルダに、特定のリソース(追加のXMLファイル、何を持っていますか)があり、上記のサービスからアクセスできる必要があります。これらのリソースは、相対パスを使用してservices.xmlの依存関係として指定されています。中間層がデプロイされている場合、スタンドアロンでは正常に動作しますが、サーブレットコンテナ内にデプロイされている場合は動作しません。後者の場合、中間層コンテキストはXmlWebApplicationContextとしてインスタンス化され、サーブレットコンテキストのルートに基づいてすべてのリソースがロードされます。つまり、プレフィックスにはすべて/WEB-INF/とする必要があります。 PropertyPlaceholderConfigurerを使用しても同様の問題が発生します。

私はクラスパスからリソースをロードすることでこれを多少回避できますが、それは理想的ではありません - スタンドアロンデプロイメントでは、クラスパスにコンフィグレーションフォルダを追加する必要があり、 WEB-INF/classes。

アイデア?

答えて

3

私は、SpringのXmlWebApplicationContextを拡張し、相対リソースパスを許可しました。これは、私が望むことを行います。つまり、Webアプリケーションの一部として配備されているかスタンドアロンで配備されていても、同じcontext.xmlファイルを使用できます。

興味のある情報源は以下のとおりです。これは、SOV(スタックオーバーフロー投票)あなたは限り、あなたは

import java.io.IOException; 

import org.springframework.core.io.Resource; 
import org.springframework.util.StringUtils; 
import org.springframework.web.context.support.XmlWebApplicationContext; 

/** 
* Extends Spring's default web application context to allow relative 
* resource paths. Resources without explicitly specified URL protocol 
* and/or leading slash are loaded relative to the first location 
* from getConfigLocations(). 
*/ 

public class SpringApplicationContext extends XmlWebApplicationContext { 

    @Override 
    protected Resource getResourceByPath(String path) { 
    path = StringUtils.cleanPath(path); 
    if (path.startsWith("/") || (path.indexOf(':')>0)) { 
     return super.getResourceByPath(path); 
    } 
    try { 
     return super.getResourceByPath(getConfigLocations()[0]) 
     .createRelative(path); 
    } catch (IOException E) { 
     // failed to create relative resource - default to standard implementation 
     return super.getResourceByPath(path); 
    } 
    } // getResourceByPath() 
} 
1

私はそれがむしろ迷惑であることに同意します。私はあなたの提案を行うことでこれを回避しています。これはクラスパスに私の春の設定を入れているので、私はまだ完全修飾されたインポートを使用していても、どの環境下でも動作します。

あなたのクラスパス設定がなぜ複雑である必要があるのか​​分かりません。これらのファイルは、javaファイルの横にあるjavaソースフォルダの下に置くことができるので、同じように処理されます。

+0

ありがとうございます。リソースをJavaファイルと一緒に置くことは、いくつかのケースでは完全にうまくいきます(私はHibernateクエリなどでそれを行います)。しかし、デプロイ時に変更できるもの(PropertyPlaceholderConfigurerによって使用されるプロパティファイルなど)ではむしろ不便です。それはアクセス可能でなければなりません(例えば、jarファイル内などではありません)。したがって、/ WEB-INF/classesに入れるか、スタンドアロン展開時にクラスパスに 'conf'フォルダを追加する必要があります。 – ChssPly76

1

奇妙な:-)この答えをupvoteとしてそれでやりたいのは自由です意味:-)ライセンスを使用して公開しています。あなたの解決策は私のためには機能しません。ここに私です:

package dmp.springframework.web.context; 

import java.io.IOException; 
import org.springframework.core.io.FileSystemResource; 
import org.springframework.core.io.Resource; 
import org.springframework.util.StringUtils; 
import org.springframework.web.context.support.XmlWebApplicationContext; 

public class RelativeResourceXmlWebApplicationContext extends XmlWebApplicationContext { 

    @Override 
    protected Resource getResourceByPath(String path) { 
     path = StringUtils.cleanPath(path); 
     if (path.startsWith("/") || (path.contains(":"))) { 
      return super.getResourceByPath(path); 
     } 
     try { 
      String newFilename = super.getResourceByPath(getConfigLocations()[0]).getFile().getParentFile().getAbsolutePath(); 
      newFilename = newFilename + "/" + path; 
      return new FileSystemResource(newFilename); 
     } catch (IOException E) { 
      // failed to create relative resource - default to standard implementation 
      return super.getResourceByPath(path); 
     } 
    } // getResourceByPath() 
} 
関連する問題