我目前正在开发一个使用servlets& amp;弹簧框架。像往常一样,它包含大量文件(jsp,js,css,图像,各种资源等)。 我试图避免在任何文件中编写任何硬编码路径或域...
例如,您可能知道何时处理请求,您将其“转发”到jsp页面(它的路径可能会被硬编码)。其他示例是在jsp文件中导入images / css / js等...
是否有任何通用方法(或工具)来避免硬编码路径/网址,因此任何重构都不会造成麻烦?
修改
我使用netbeans 7.1.2 ...不幸的是netbeans只对纯java代码有帮助。当使用jsp文件时,事情是有限的,如果你添加自定义标记文件和Jsp 2.0 EL就像在控制台模式下编程:p
答案 0 :(得分:1)
在JSP文件本身中,您可以使用JSTL
例如,在创建指向其他页面的链接时,您可以这样做:
<a href="<c:url value="/referrals/send.html"/>" target="_blank">Refer an Entrepreneur!</a>
这意味着,无论您的webapp在哪里,链接都将始终具有正确的URL。例如,在我的开发框中,此链接将是:
http://localhost:8080/accounts/referrals/send.html
但是在我的生产服务器上,它正确解析为:
http://wwww.mydomain.com/referrals/send.html
你可以看到,在我的开发服务器中,webapp上下文位于/ accounts下,但是在生产机器上,它位于/根据webapp在根上下文中。
您可以阅读一个小教程here
答案 1 :(得分:1)
如果要引用任何静态内容(js,images,css等),则不必对整个文件路径进行硬编码。相反,你可以这样做: -
<img src="${pageContext.request.contextPath}/resources/images/test.jpg"/>
其余的文件路径(Hibernate域映射,Spring控制器中的转发页面等)应该与您的项目结构相关,并且大多数IDE都足够聪明,可以毫无问题地重构它们......或者至少在我的情况下,IntelliJ似乎为我处理了所有这些。
在某些时候,您需要问自己,有多少硬编码是可以接受的而不是可接受的?此外,我不会试图偏离Spring / Hibernate推荐的解决方案。如果你使一切都过于抽象,你就会遇到一系列不同的问题,这对于将来可能继承你的项目的其他同行来说会适得其反。
答案 2 :(得分:1)
属性文件始终是一个不错的选择,因此您只需要在一个点上进行更改。
答案 3 :(得分:0)
其实我刚想出了一个主意。由于netbeans进行分析并显示对java代码的依赖性,因此可能最好处理所有路径&amp;域作为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("\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 /”下的所有文件,并创建一个java文件,其中所有jsp文件'已注册'为公共静态最终字符串变量与每个路径...的想法是使用生成的java文件作为项目中所有jsps的参考...总是使用这些变量而不是硬编码路径.. 这与项目或任何项目无关。它只是一个拯救你的工具 时间,而不是手动为项目中的每个文件执行此操作。
我还创建了另一个类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);
}
}
}