我目前正在将我的企业Java应用程序从Java 7迁移到Java 8,从Java EE 6迁移到Java EE 8和Glassfish 3.1.2.2再到Glassfish 5.0。因此,我遇到了Servlet中重定向的问题。
应用程序在docker compose环境中的Docker for Mac上的docker容器中运行。当我尝试使用例如访问应用程序时https://localhost:58181/myapp/secure
应用程序将检查有效的身份验证,并且由于用户未经过身份验证,应用程序应重定向到https://localhost:58181/myapp/public/login
。
这在Glassfish 3.1.2.2中运行良好,但是对于Glassfish 5.0,重定向将转到https://mayapp:8181/myapp/public/login
,而myapp是docker主机名,而8181是Glassfish的端口,它暴露在外面,如58181所以它是使用docker主机名和端口而不是请求的主机名和端口。
在应用程序中,重定向通过以下方式触发:
httpServletResponse.sendRedirect("/myapp/public/login");
我对这个问题有了更深入的了解。与Glassfish 3.1.2.2相比httpServletRequest.getServerName()
返回myapp
而不是localhost
,httpServletRequest.getServerPort()
(8181与58181)的情况相同。这些方法在httpServletResponse.sendRedirect(...)
内调用,以设置完整的重定向网址。
我还创建了一个小项目(https://github.com/gessnerfl/glassfish-servlet-test),证明这个项目随Glassfish 5.0而改变。该项目只包含一个小servlet,它从HttpServletRequest中提取一些细节:
@WebServlet(urlPatterns = "/test")
public class TestServlet extends HttpServlet{
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Writer writer = resp.getWriter();
writer.append("Request URL: "+req.getRequestURL().toString()+"\n");
writer.append("Request URI: "+req.getRequestURI()+"\n");
writer.append("Server Name: "+req.getServerName()+"\n");
writer.append("Server Port: "+req.getServerPort()+"\n");
writer.append("Local Name: "+req.getLocalName()+"\n");
writer.append("Local Port: "+req.getLocalPort()+"\n");
writer.append("Remote Host: "+req.getRemoteHost()+"\n");
writer.append("Remote Port: "+req.getRemotePort());
writer.flush();
}
}
使用Glassfish 3.1.2.2(Java 7)和Glassfish 4.1.2(Java 7和Java 8),结果是(端口号和本地/远程名称因docker设置而不同,但在这种情况下无关紧要):
Request URL: https://localhost:38181/test-servlet/test
Request URI: /test-servlet/test
Server Name: localhost
Server Port: 38181
Local Name: 7a786606bfac
Local Port: 8181
Remote Host: 172.19.0.1
Remote Port: 40136
使用Glassfish 5.0,这将更改为:
Request URL: https://3eb4cbbf3a08:8181/test-servlet/test
Request URI: /test-servlet/test
Server Name: 3eb4cbbf3a08
Server Port: 8181
Local Name: 3eb4cbbf3a08
Local Port: 8181
Remote Host: 172.19.0.1
Remote Port: 52318
正如您所见,请求URL以及服务器名称和端口已更改为与本地名称相同。
新行为是否正确?它是servlet规范的变化(没有发现与此相关的任何内容)?
我知道作为替代方案,我可以从HTTP标头HOST
获取请求主机。但由于这是Java EE标准的一部分,我不会期望这样的改变。