1

私は現在、サーブレットとSpringFrameworkを使用してWebサイトを開発しています。いつものように、それはたくさんのファイル(jsp、js、css、画像、さまざまなリソースなど)を含んでいます。ハードコードされたパスやドメインをファイルに書き込まないようにしています...

たとえば、リクエストがいつ処理されるかを知っているかもしれませんが、それをjspページに「転送」します(パスはおそらくハードコーディングされます)。他の例は、jspファイルへのimages / css/jsなどのインポートです...

リファクタリングによって問題が発生しないように、ハードコードされたパス/ URLを回避する一般的な方法(またはツール)はありますか?

編集
私はnetbeans7.1.2を使用しています...残念ながら、netbeansは純粋なJavaコードでのみ役立ちます。jspファイルを操作する場合は制限があり、カスタムタグファイルとJsp 2.0 ELを追加すると、コンソールモードでのプログラミングに似ています:p

4

4 に答える 4

1

JSPファイル自体では、を使用して、ハードコードされたドメイン/URLのほぼすべてを回避できます。JSTL

たとえば、別のページへのリンクを作成する場合は、次のようにします。

<a href="<c:url value="/referrals/send.html"/>" target="_blank">Refer an Entrepreneur!</a>

これは、Webアプリがどこにあるかに関係なく、リンクには常に正しいURLが含まれることを意味します。たとえば、私の開発ボックスでは、このリンクは次のようになります。

http://localhost:8080/accounts/referrals/send.html

しかし、私の実稼働サーバーでは、次のように正しく解決されます。

http://wwww.mydomain.com/referrals/send.html

私の開発サーバーでは、webappコンテキストは/ accountsの下にありますが、本番マシンでは、webappがルートコンテキストの下にあるため、/のすぐ下にあります。

ここで小さなチュートリアルを読むことができます

于 2013-01-14T12:47:58.917 に答える
1

静的コンテンツ(js、画像、cssなど)を参照している場合は、ファイルパス全体をハードコーディングする必要はありません。代わりに、これを行うことができます:-

<img src="${pageContext.request.contextPath}/resources/images/test.jpg"/>

残りのファイルパス(Hibernateドメインマッピング、Springコントローラーの転送ページなど)はプロジェクト構造に関連している必要があり、ほとんどのIDEは問題なくリファクタリングできるほど賢いです...または少なくとも私の場合、IntelliJは私のためにすべてを処理します。

ある時点で、ハードコーディングのどれだけが許容できるのか、許容できないのかを自問する必要があります。さらに、Spring/Hibernateが推奨するソリューションから離れすぎないようにします。すべてを抽象化しすぎると、対処すべき別の問題が発生し、将来プロジェクトを継承する可能性のある他のピアにとって逆効果になります。

于 2013-01-14T12:49:00.547 に答える
1

プロパティファイルは常に適切なオプションであるため、ある時点でのみ変更を加える必要があります。

于 2013-01-14T12:52:45.193 に答える
0

実は私はちょうどアイデアを思いついた。netbeansは分析を行い、Javaコードへの依存関係を示すため、すべてのパスとドメインをJava変数として処理する方がよい場合があります。

FileResolverという名前のパッケージをプロジェクトに作成しました。その中には、プロジェクトのファイルタイプごとに1つのクラスがあります(たとえば、Jspファイル用に1つのクラス、Cssファイル用に1つのクラスなど)。これらのファイル内で、すべてのファイルのすべてのパスをpublic staticfinalString変数に記録してハードコーディングします。サンプル:

public class Jsps {

    public class layouts{
        public static final String main =       "layouts/main.jsp";
    }

    public class pages{
        public static final String error =      "pages/error.jsp";
        public static final String login =      "pages/login.jsp";
        public static final String register =   "pages/register.jsp";
    }
    ...
}

プロジェクト全体で、パスの代わりに変数を使用する必要があります。次に、ファイルをリファクタリングするときはいつでも、変更するファイルは1つだけです。これらの変数のマッピング値です...そして、変数を変更する必要がある場合、netbeansはプロジェクト内のすべてのファイルを一度にリファクタリングします...プロジェクトをファイルパスからクリーンに保つので、これは問題なく機能すると思います。心配する必要があるのは、そのファイル内の変数の適切なファイルパスへのマッピングだけです。

編集
すべてのファイルを手作業で作成するのではなく、これらのJavaファイルを作成するための簡単なパーサーを作成します...終了したら更新します


更新
これが私のFileResolverGeneratorです

public class FileResolverGenerator {

    private static final String newFilePath = "C:/Users/Foo/Desktop/Jsps.java";
    private static final String scanRootFolder = "C:/Users/Foo/Desktop/myProject/web/WEB-INF/jsp";

    private static final String varValueReplaceSource = "C:/Users/Foo/Desktop/myProject/web/WEB-INF/jsp/";
    private static final String varValueReplaceTarget = "";

    private static final boolean valueAlign = true;
    private static final int varNameSpaces = 15;


    public static void main(String[] args){
        try {
            // Create file and a writer
            File f = new File(newFilePath);
            f.createNewFile();
            bw = new BufferedWriter( new FileWriter(f) );
            // Execute
            filesParser( new File(scanRootFolder) );
            // 'Burn' file
            bw.close();
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ResolverGenerator.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ResolverGenerator.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    // ================================================================================================ //
    // ============================================= WORK ============================================= //
    // ================================================================================================ //

    private static void filesParser(File rootFolder) throws FileNotFoundException, IOException{

        folderIn(rootFolder);
        // Files first
        if(!rootFolder.exists()) throw new FileNotFoundException();
        for(File f : rootFolder.listFiles()){
            if(f==null){ return; }
            if(f.isDirectory()){ continue; }
            else if(f.isFile()){ writeFileVariable(f); }
        }
        // Folders next
        for(File f : rootFolder.listFiles()){
            if(f==null){ return; }
            if(f.isDirectory()){ filesParser(f); }
            else if(f.isFile()){ continue; }
        }
        folderOut(rootFolder);
    }


    // ================================================================================================ //
    // ============================================ PRINTS ============================================ //
    // ================================================================================================ //
    private static BufferedWriter bw;
    private static int tabCount = 0;


    private static void folderIn(File f) throws IOException{
        bw.append("\n\n");
        for(int i=0; i<tabCount; i++)
            bw.append("\t");
        bw.append("public class "+f.getName()+"{\n");
        tabCount++;
    }

    private static void folderOut(File f) throws IOException{
        tabCount--;
        for(int i=0; i<tabCount; i++)
            bw.append("\t");
        bw.append("}\n");
    }

    private static void writeFileVariable(File f) throws IOException{
        String varName = f.getName().split("\\.")[0].replaceAll("-", "");
        String varValue = f.getPath().replaceAll("\\\\","/")
           .replace(varValueReplaceSource.replaceAll("\\\\","/"),varValueReplaceTarget.replaceAll("\\\\","/"));

        for(int i=0; i<tabCount; i++)
            bw.append("\t");
        bw.append("public static final String "+varName+" = ");
        if(valueAlign){
            for(int i=0; i<varNameSpaces-varName.length(); i++) bw.append(" ");
            bw.append("\t"); }
        bw.append("\""+varValue+"\";\n");
    }


}

具体的には...これは「/WEB-INF/ jsp /」の下のすべてのファイルをスキャンし、すべてのjspファイルが各パスのパブリック静的最終文字列変数に「登録」されたJavaファイルを作成します...アイデアは使用することですすべてのjspの参照として生成されたJavaファイルはプロジェクト内にあります...ハードコードされたパスの代わりに常にこれらの変数を使用してください.. これはプロジェクトまたはプロジェクトとは関係ありません。これは、プロジェクト内のすべてのファイルに対して手動でこれを行うのではなく、時間を節約する単なるツールです。

また、別のクラスResolverConsistencyCheckerを作成しました。これは、すべての変数を受け取り、ファイルパスが正しいかどうか(ファイルが存在するかどうか)をチェックします...ファイル名とファイルパスに変更を加えていないため、すべてのテストに合格します。
このメソッドは、プロジェクトの「エラー」をテストするときに実行する必要があります

public class ResolverConsistencyChecker {

    private static Class checkClass = Jsps.class;
    private static String fullPathPrefix = "C:/Users/Foo/Desktop/myProject/web/WEB-INF/jsp/";


    public static void main(String[] args){
        try {
            filesChecker( checkClass );
            System.out.println( "Tests passed. All files locations are valid" );
        } catch (FileNotFoundException ex) {
            Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    // ================================================================================================ //
    // ============================================= WORK ============================================= //
    // ================================================================================================ //

    private static void filesChecker(Class rootClass) throws FileNotFoundException, IOException{

        // Check file paths in current class depth
        for(Field f : rootClass.getFields()){
            try {
                String fullFilePath = fullPathPrefix+f.get(f.getName()).toString();
                File file = new File( fullFilePath );
                if( !file.exists() )
                    throw new FileNotFoundException("Variable: '"+f.getName()+"'\nFile "+fullFilePath);
            } catch (IllegalArgumentException ex) {
                Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
            } catch (IllegalAccessException ex) {
                Logger.getLogger(ResolverConsistencyChecker.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        // Check for embedded classes
        for(Class c : rootClass.getClasses()){
            filesChecker(c);
        }
    }

}
于 2013-01-14T13:19:25.713 に答える