在web开发中消除硬编码的文件路径和url



我目前正在使用servlet开发一个网站&spring框架。像往常一样,它包含许多文件(jsp, js, css,图像,各种资源等)。我试图避免在任何文件中写入任何硬编码路径或域…

例如,你可能知道当一个请求被处理时,你把它"转发"到一个jsp页面(它的路径可能是硬编码的)。其他的例子是导入图像/css/js等在jsp文件…

有没有什么通用的方法(或工具)来避免硬编码路径/url,这样任何重构都不会造成麻烦?

编辑
我使用netbeans 7.1.2…不幸的是,netbeans只对纯java代码有帮助。当使用jsp文件时,事情是有限的,如果您添加自定义标记文件和jsp 2.0 EL就像在控制台模式下编程:p

在JSP文件本身中,您可以通过使用JSTL

来避免几乎所有硬编码的域/url

例如,当创建到另一个页面的链接时,您可以这样做:

<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在根上下文下。

你可以在这里阅读一个小教程

属性文件总是一个很好的选择,这样您只需要在一个点上进行更改。

如果您引用任何静态内容(js, images, css等),则不必硬编码整个文件路径。相反,你可以这样做:-

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

其余的文件路径(Hibernate域映射,Spring控制器中转发的页面等)应该与你的项目结构相关,大多数ide都足够聪明,可以毫无问题地重构它们。或者至少在我的情况下,IntelliJ似乎为我处理了所有这些。

在某些时候,你需要问自己,多少硬编码是可以接受的,多少是不可接受的?此外,我不会试图偏离Spring/Hibernate推荐的解决方案太远。如果你把每件事都做得太抽象,你就会有一组不同的问题需要处理,这会对将来可能继承你的项目的其他同事产生反效果。

其实我刚想到一个主意。由于netbeans会分析并显示对java代码的依赖关系,因此最好处理所有路径&域作为Java变量。

我已经在我的项目上创建了一个名为FileResolver的包,并且在我的项目中有一个类用于每个文件类型(例如一个类用于Jsp文件,一个用于Css文件等)。在这些文件中,我会记录&在public static final String变量中硬编码所有文件的所有路径。示例:

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";
    }
    ...
}

在我的项目中,我应该使用变量而不是路径。然后,每当我重构一个文件时,我只需要更改一个文件,即这些变量中的映射值……如果我需要更改变量,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("nn");
        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/"下的所有文件,并创建一个java文件,其中所有jsp文件"注册"到每个路径的公共静态final String变量…我们的想法是使用生成的java文件作为项目中所有jsp的参考。总是使用这些变量而不是硬编码的路径。这与项目或任何项目无关。它只是一个拯救你的工具

我还创建了另一个类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);
        }
    }
}

相关内容

  • 没有找到相关文章

最新更新