我在某培训班学java,最近想稍微深究一下 “手写spring boot” 的内容。
在实现 “重定向” 部分的时候,教给我们的方式是,状态行设置好状态代码302,状态原因balabala
然后只需要在响应头里面添加 “Location", 值设置成一个html文件路径就好了。貌似剩下的HTML会自动搞定。(是否其他地方有额外操作被我忽视了?)
问题出现在Location的路径这里,我们在学着写代码的时候,并没有给定上级路径,直接给定了相对路径: "/文件路径"。
貌似工作的时,java会在编译后的target/classes/static目录下自动找到这个指定的文件。
我自己重写的时候,因为算是盲写,没有怎么看老实(天啦怎么会有这种屏蔽词)教的版本,所以我用PrintWriter生成一个临时html文件的时候,思路是生成在target/classes/dynamic目录下,然后再把这个路径添加到响应头的Locatin里面去。
然后我发现工作不了,貌似是404.
```java
public void sendRedirect(String path){
//重定向的状态代码为302
statusCode = 302;
statusReason = "MovedTemporarily";
//响应头Location
addHeader("Location",path);
}
if(username==null||username.isEmpty()||password==null||password.isEmpty()){
response.sendRedirect("/login_info_error.html"); // 这里只给了斜杠和文件名,文件在static目录下
return;
}
###### 我的部分代码
```java
// 这里的 dirDynamic目录就是 和 static目录同级的 dynamic 目录
File tmpDynamicHtml = new File(dirDynamic, "/tmp.html");
try (PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(new FileOutputStream(tmpDynamicHtml), StandardCharsets.UTF_8)), true)) {
pw.println("");
pw.println("");
pw.println("");
pw.println("");
pw.println("用户列表 ");
pw.println("");
pw.println("");
pw.println("");
pw.println("用户列表
");
pw.println("");
pw.println("");
pw.println("");
pw.println("");
pw.println("");
pw.println("");
pw.println("");
for (User u : users) {
pw.println("");
pw.println("");
pw.println("");
pw.println("");
pw.println("");
pw.println("");
}
pw.println("用户名 昵称 年龄 操作 " + u.getUsername() + " " + u.getNickname() + " " + u.getAge() + " " + "删除" + "
");
pw.println(" ");
pw.println("");
response.sendDirectory("/tmp.html"); // 这里我也试过"../dynamic/tmp.html",访问的时候都是404。我用File类这样生成文件夹就没问题
} catch (FileNotFoundException e) {
e.printStackTrace();
}
我想问下,用java写服务器,重定向时候的"Location"响应头,是否只能访问static目录下的文件吗?还是我忽视了哪个可能出现的简单的问题?
首先访问的是url,其次是跳转的地址没有限制,哪里都行(比如百度,没有地址限制,前提是接口能被访问)
默认配置:Spring Boot默认提供静态资源目录位置需置于classpath下,目录名需符合如下规则:
/static
/public
/resources
/META-INF/resources
举例:我们可以在src/main/resources/目录下创建static,在该位置放置一个图片文件。启动程序后,尝试访问http://localhost:8080/D.jpg。如能显示图片,配置成功。
相应 /dynamic/tmp.html 也能访问需要把/dynamic添加为自定义静态资源文件目录。
需要在pom.xml 中添加:<resources> <!-- 扫描resources下所有资源 --> <resource> <directory>src/main/resources/</directory> </resource> </resources>
在配置文件里加上:
spring:
resources:
static-locations: classpath:/dynamic
先感谢@qb_sheng和楼上上的回答
首先我说明一下,我没有“用”Spring Boot,只是在练习用java原生代码实现Spring Boot的一些基本功能。所以我的pom.xml里面没有springboot的配置,只有一些maven配置。
我已经定位到问题所在的位置了,但是现象对我来说还是有点诡异:
是设置响应头Location 的值会出现我无法理解的问题, 我做了个实验:
在target/classes 、target/classes/static 、target/classes/dynamic三个目录下面各拷贝一个静态页面tmp.html,页面里面稍作文本标记以区分。
在response发送响应头的Location值时,分别设置如下值,运行结果一并给出:
1,"/tmp.html"
//实现重定向,根据html里留的标记,重定向的static下的目录的文件(即target/classes/static/tmp.html)
2,"../tmp.html"
//实现重定向,但与预期不太一致(我的理解是上级目录即target/classes/tmp.html,但是根据我留的文本标记,依然是target/classes/static/tmp.html)
3,"../dynamic/tmp.html"
//应该没有找到这个页面,跳转到了static目录下的404页面
4,"../static/tmp.html"
//也没有找到这个页面,跳转到了static目录下的404页面
5,写要跳转的页面文件完整的 绝对路径
//浏览器给出了ERR_UNSAFE_REDIRECT错误
我不知道是否哪里犯了没察觉的低级错误,否则我的理解就是:
A,用"../”来获取上级目录在HTTP里面貌似行不通;
B,没有简单的办法进行target/classes/static目录外的页面跳转。
不知道是否有遇到过同样问题的人,或者有这方面经验的程序员来解答这个问题。
当然,这个问题其实不致命也不重要,在我们学的下一个迭代版本中,不用生成动态页面的本地文件再重定向,而是用字节数组输出流直接发出去。
我估计这也是这个问题没什么人遇到过的原因把。