maven java文件路径问题_java中的路径问题(getResourceAsStream/tomcat/maven/getContextpath)等各种路径问题...

1. File, FileInputStream等路径问题

@Test

public void testFile1(){

//在src的当前文件夹下

File file = new File("config.properties");

File absoluteFile = file.getAbsoluteFile();

System.out.println(absoluteFile);

System.out.println(file.exists());

}

@Test

public void testFile2(){

//盘符目录

File file = new File("/config.properties");

File absoluteFile = file.getAbsoluteFile();

System.out.println(absoluteFile);

}

@Test

public void testFile3(){

//绝对路径

File file = new File("F:\\ide\\PathTest\\config.properties");

File absoluteFile = file.getAbsoluteFile();

System.out.println(absoluteFile);

System.out.println(file.exists());

}

2.class.getResourceAsStream与class.getClassLoader() .getResourceAsStream以及class.getResource

1)基于eclipse

@Test//PathTest的当前目录(与PathTest同包下)

public void testClassGetResourceAsStream1(){

InputStream is = PathTest.class.getResourceAsStream("config.properties");

System.out.println(is);

}

@Test//src目录下

public void testClassGetResourceAsStream2(){

InputStream is = PathTest.class.getResourceAsStream("/config.properties");

System.out.println(is);

}

@Test//src目录下

public void testClassLoaderGetResourceAsStream1(){

InputStream is = PathTest.class.getClassLoader().getResourceAsStream("config.properties");

System.out.println(is);

}

@Test//PathTest的当前目录

public void testClassGetResourceAsStream12() throws Exception {

URL resource = PathTest.class.getResource("");

System.out.println(resource.getPath());

}

2)基于eclispe的maven

@Test/*在resouces文件夹下,假如在test环境下,那么首先查找test下resouces下相应位置的文件,假如没有会去main下resources

下寻找相应位置的文件,但是在main环境下只能在main的resources中寻找相应位置的文件,eclispe与idea都有这个特点(maven自身的特点)*/

public void testClassGetResourceAsStream() throws Exception {

InputStream is = PathTest.class.getResourceAsStream("/config.properties");

System.out.println(is);

}

@Test /*在resouces文件夹下,假如在test环境下,那么首先查找test下resouces下相应位置的文件,假如没有会去main下resources

下寻找相应位置的文件,但是在main环境下只能在main的resources中寻找相应位置的文件,在eclispe与idea下一样,eclispe与idea都有这个特点(maven自身的特点)*/

public void testClassLoaderGetResourceAsStream() throws Exception {

InputStream is = PathTest.class.getClassLoader().getResourceAsStream("config.properties");

System.out.println(is);

}

@Test//PathTest的当前目录

public void testClassGetResource() throws Exception {

URL resource = PathTest.class.getResource("");

System.out.println(resource.getPath());

}

3)总结(实质原因)

a)源码分析

/*由以下可以得出,class.getResourceAsStream是经过处理后(假如没有/,就会加上class的全类名,所以在同包下),

然后通过class.getClassLoader() .getResourceAsStream相同的处理*/

private String resolveName(String name) {

if (name == null) {

return name;

}

if (!name.startsWith("/")) {

Class> c = this;

while (c.isArray()) {

c = c.getComponentType();

}

String baseName = c.getName();

int index = baseName.lastIndexOf('.');

if (index != -1) {

name = baseName.substring(0, index).replace('.', '/')

+"/"+name;

}

} else {

name = name.substring(1);

}

return name;

}

public InputStream getResourceAsStream(String name) {

name = resolveName(name);

ClassLoader cl = getClassLoader0();

if (cl==null) {

// A system class.

return ClassLoader.getSystemResourceAsStream(name);

}

return cl.getResourceAsStream(name);

}

public InputStream getResourceAsStream(String name) {

URL url = getResource(name);

try {

return url != null ? url.openStream() : null;

} catch (IOException e) {

return null;

}

}

b)结论:

class.getResourceAsStream的实际路径为:解析后的根目录(eclipse(bin(默认)),idea略不同(默认为out/production/project名称),eclipse基于maven的目录为classes目录,本质是java与javac的关系,运行的是解析后的文件)加上经过上述源码处理后的name,就是我们的实际地址;

class.getClassLoader() .getResourceAsStream的实际路径为:解析后的根目录+我们填入的path;

3.eclipse/idea/maven的java路径与javac

1)eclipse(可以自己设置)

1c6b101ec3aa5919e53a6d6aa49d8761.png

备注:src下的java文件解析成class文件保存在bin目录相应的位置下,其他文件不会解析直接放入bin目录相应的位置下

2)基于eclipse的maven的java路径与javac

cbbaa5504a7592c2861be7a28e3756fb.png

maven的文件结构

d51a243c558347cb359ce6ce40ff5fe9.png

备注:

main下的java文件夹中文件解析成class文件放入classes目录相应的位置下,其他文件不会放入classes目录;main下的resources文件中文件不会解析直接放入classes目录相应的位置下;

test下的java文件夹中文件解析成class文件放入test-classes目录相应的位置下,其他文件不会放入test-classes目录;test下的resources文件中文件不会解析直接放入test-classes目录相应的位置下;

3)idea的java路径与javac

833d13885401869b8b93642aa132b864.png

b867221f7cf236d17eb5e0d2648209ca.png

备注:sources对应eclispe的main的java,tests对应eclispe的test的java,resources对应eclispe的main的resources,test resources对应eclispe的test的resources,其它一致

4.web中的路径问题

1)req.getRequestDispatcher("/index").forward(req, resp)带‘/’与不带“/”的区别

a)源码分析

public RequestDispatcher getRequestDispatcher(String path) {

Context context = this.getContext();

if (context == null) {

return null;

} else if (path == null) {

return null;

} else if (path.startsWith("/")) {

return context.getServletContext().getRequestDispatcher(path);//带/

} else {//不带/

String servletPath = (String)this.getAttribute("javax.servlet.include.servlet_path");

if (servletPath == null) {

servletPath = this.getServletPath();

}

String pathInfo = this.getPathInfo();

String requestPath = null;

if (pathInfo == null) {

requestPath = servletPath;

} else {

requestPath = servletPath + pathInfo;

}

int pos = requestPath.lastIndexOf(47);//以下是对相对路径进行处理,处理成与/一致

String relative = null;

if (context.getDispatchersUseEncodedPaths()) {

if (pos >= 0) {

relative = URLEncoder.DEFAULT.encode(requestPath.substring(0, pos + 1), StandardCharsets.UTF_8) + path;

} else {

relative = URLEncoder.DEFAULT.encode(requestPath, StandardCharsets.UTF_8) + path;

}

} else if (pos >= 0) {

relative = requestPath.substring(0, pos + 1) + path;

} else {

relative = requestPath + path;

}

return context.getServletContext().getRequestDispatcher(relative);//交给带/的处理

}

}

if (this.getContext().getDispatchersUseEncodedPaths()) {

String decodedPath;

try {

decodedPath = URLDecoder.decode(normalizedPath, "UTF-8");

} catch (UnsupportedEncodingException var14) {

return null;

}

normalizedPath = RequestUtil.normalize(decodedPath);

if (!decodedPath.equals(normalizedPath)) {

this.getContext().getLogger().warn(sm.getString("applicationContext.illegalDispatchPath", new Object[]{path}), new IllegalArgumentException());

return null;

}

uri = URLEncoder.DEFAULT.encode(this.getContextPath(), StandardCharsets.UTF_8) + uri;//getContextPath+uri(path)

} else {

uri = URLEncoder.DEFAULT.encode(this.getContextPath() + uri, StandardCharsets.UTF_8);//getContextPath+uri(path)

}

b)总结:由以上可知,不论是带/还是不带/,最后还是转换成带/处理,转换成getContextPath+uri(path),一般我们都是使用绝对路径,不使用相对路径,防止相对路径转换后不是我们需要的路径,eclispe的/默认表示当前项目的根目录,idea默认是代表站点目录

212195298e80d526d16f1f73a66c05cb.png

备注:需要进入tomcat源码,需要导入如下依赖

org.apache.tomcat

tomcat-catalina

9.0.1

provided

2)response.sendRedirect(path)带/与不带/的区别

路径处理源码基本和上述类似,但是response.sendRedirect(path)带/表示站点目录(主机地址:例如localhost:8080)

3)@WebServlet("/login")等路径

必须带/表示getRealPath(path),不带会抛出异常,/与/*的区别,/不会拦截jsp页面,/*会拦截所有页面

5. tomcat的路径问题

当使用Tomcat作为Web服务器,项目一般部署在Tomcat下的webapps的目录下。具体来说主要用两种部署的路径:

方式1:将web项目中的webRoot下的文件直接拷贝到webapps/ROOT下(删除ROOT下的原有文件),request.getContextPath()的返回值为空(即:"",中间无空格,注意区分null)。

方式2:在Tomcat下的webapps中创建以项目名称命名(当然也可以用其他的名称)的文件夹,并将webRoot下的文件直接拷贝到该文件夹下,其返回值为:/创建的文件夹的名称。

总结:所以在IntelliJ IDEA中的request.getContextPath()在没有设置Application Context的时候request.getContextPath()的返回值为空(即:"",中间无空格,注意区分null)。

6.getContextpath的问题

getContextpath在IntelliJ IDEA中尽量的少用,加在IntelliJ IDEA中没有设置Application Context的时候那么没什么问题,假如设置了之后会造成Application Context的时候的名称重复,在eclispe中并没有这个问题,所以在web环境下我们需要建立文件夹,不要使用getContextpath,否则会出现路径可能与你的需要的路径不匹配。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值