Java 如何让 Jetty 动态加载“静态”页面
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/184312/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to make Jetty dynamically load "static" pages
提问by mcherm
I am building Java web applications, and I hate the traditional "code-compile-deploy-test" cycle. I want to type in one tiny change, then see the result INSTANTLY, without having to compile and deploy.
我正在构建 Java Web 应用程序,我讨厌传统的“代码-编译-部署-测试”循环。我想输入一个微小的更改,然后立即查看结果,而无需编译和部署。
Fortunately, Jettyis great for this. It is a pure-java web server. It comes with a really nice maven pluginwhich lets you launch Jetty reading directly from your build tree -- no need to package a war file or deploy. It even has a scanInterval setting: put this to a non-zero value and it will watch your java files and various config files for changes and automatically re-deploy a few seconds after you make a change.
幸运的是,Jetty非常适合这一点。它是一个纯 Java 网络服务器。它带有一个非常好的maven 插件,它允许您直接从构建树启动 Jetty 读取——无需打包或部署 war 文件。它甚至有一个 scanInterval 设置:将它设置为非零值,它会监视您的 java 文件和各种配置文件的更改,并在您进行更改几秒钟后自动重新部署。
There's just one thing keeping me from nirvana. I have javascript and css files in my src/main/webapp directory which just get served up by Jetty. I would like to be able to edit theseand have the changes show up when I refresh the page in the browser. Unfortunately, Jetty holds these files open so I can't (on Windows) modify them while it is running.
只有一件事让我远离涅槃。我的 src/main/webapp 目录中有 javascript 和 css 文件,它们刚由 Jetty 提供。我希望能够编辑这些并在浏览器中刷新页面时显示更改。不幸的是,Jetty 将这些文件保持打开状态,因此我无法(在 Windows 上)在它运行时修改它们。
Does anyone know how to make Jetty let go of these files so I can edit them, then serve up the edited files for subsequent requests?
有谁知道如何让 Jetty 放开这些文件,以便我可以编辑它们,然后为后续请求提供编辑过的文件?
采纳答案by Athena
Jetty uses memory-mapped files to buffer static content, which causes the file-locking in Windows. Try setting useFileMappedBuffer for DefaultServlet to false.
Jetty 使用内存映射文件来缓冲静态内容,这会导致 Windows 中的文件锁定。尝试将 DefaultServlet 的 useFileMappedBuffer 设置为 false。
Troubleshooting Locked files on Windows (from the Jetty wiki)has instructions.
回答by anjanb
It is probably the browser that is holding on to it.
它可能是坚持它的浏览器。
inside I.E : Tools | Internet Options | Temporary Internet Files > Settings, click the Radio button "Every visit to the page". press OK.
IE 内部:工具 | 互联网选项 | Internet 临时文件 > 设置,单击单选按钮“每次访问该页面”。按确定。
Before you do that, Delete all the temporary internet files.
在此之前,请删除所有临时 Internet 文件。
回答by kybernetikos
While one of the answers above is exactly right for configuring jetty by xml, if you want to configure this option in code (for an embedded server) the answer is different and not found on that page.
虽然上面的答案之一完全适用于通过 xml 配置码头,但如果您想在代码中配置此选项(对于嵌入式服务器),答案是不同的,并且在该页面上找不到。
You'll find a number of suggestions online including
您会在网上找到许多建议,包括
context.getInitParams().put("useFileMappedBuffer", "false");
context.getInitParams().put("useFileMappedBuffer", "false");
Or overriding the WebAppContext, or using a fully qualified name for the init parameter. None of these suggestions worked for me (using Jetty 7.2.2). Part of the problem was that the useFileMappedBuffer option needs to be set on the servlet that the WebAppContext is using to serve the static files, rather than on the context.
或者覆盖 WebAppContext,或者对 init 参数使用完全限定的名称。这些建议都不适合我(使用 Jetty 7.2.2)。部分问题是需要在 WebAppContext 用于提供静态文件的 servlet 上设置 useFileMappedBuffer 选项,而不是在上下文上设置。
In the end I did something like this on a straightforward ServletContextHandler
最后我在一个简单的 ServletContextHandler 上做了这样的事情
// Startup stuff
final Server server = new Server(port);
ServletContextHandler handler = new ServletContextHandler();
handler.setResourceBase(path);
SessionManager sm = new HashSessionManager();
SessionHandler sh = new SessionHandler(sm);
handler.setSessionHandler(sh);
DefaultServlet defaultServlet = new DefaultServlet();
ServletHolder holder = new ServletHolder(defaultServlet);
holder.setInitParameter("useFileMappedBuffer", "false");
handler.addServlet(holder, "/");
server.setHandler(handler);
server.start();
server.join();
回答by FUD
Although this is a Old problem but i found thispost very helpful, in short just change your config to
虽然这是一个老问题,但我发现这篇文章非常有帮助,简而言之,只需将您的配置更改为
<plugin>
<groupId>org.mortbay.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<connectors>
<connector implementation="org.eclipse.jetty.server.bio.SocketConnector">
<port>8080</port>
</connector>
</connectors>
</configuration>
</plugin>
This disables the NIO support in Jetty ( but it should not be problem for debug puropse for simple cases ).
这会禁用 Jetty 中的 NIO 支持(但对于简单情况下的调试目的应该不会有问题)。
回答by David Roussel
When using embedded Jetty 8.1.10, the 'useFileMappedBuffer=false' setting doesn't work any mode. I read the code for DefaultServlet
, and it reads the property but it's not used for anything.
使用嵌入式 Jetty 8.1.10 时,“useFileMappedBuffer=false”设置在任何模式下都不起作用。我阅读了 的代码DefaultServlet
,它读取了属性,但没有用于任何用途。
Instead I looked at where the buffer creation was configured, and found I could subclass SelectChannelConnector
to get the benefits of Continuation, but without locking files on windows. If you simply use org.mortbay.jetty.bio.SocketConnector
, then you will not get continuation support.
相反,我查看了缓冲区创建的配置位置,发现我可以创建子类SelectChannelConnector
以获得 Continuation 的好处,但无需在 Windows 上锁定文件。如果您只是使用org.mortbay.jetty.bio.SocketConnector
,那么您将无法获得延续支持。
Here is my example:
这是我的例子:
import org.eclipse.jetty.io.Buffers.Type;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
/**
* A Connector that has the advantages NIO, but doesn't lock files in Windows by
* avoiding memory mapped buffers.
* <p>
* It used to be that you could avoid this problem by setting "useFileMappedBuffer" as described in
* http://stackoverflow.com/questions/184312/how-to-make-jetty-dynamically-load-static-pages
* However that approach doesn't seem to work in newer versions of jetty.
*
* @author David Roussel
*
*/
public class SelectChannelConnectorNonLocking extends SelectChannelConnector {
public SelectChannelConnectorNonLocking() {
super();
// Override AbstractNIOConnector and use all indirect buffers
_buffers.setRequestBufferType(Type.INDIRECT);
_buffers.setRequestHeaderType(Type.INDIRECT);
_buffers.setResponseBufferType(Type.INDIRECT);
_buffers.setResponseHeaderType(Type.INDIRECT);
}
}
I've tested this for the locking problem, and it fixes the problem. I've not tested that it works with Continuations yet.
我已经测试了这个锁定问题,它解决了这个问题。我还没有测试过它是否适用于 Continuations。
回答by Jakub Torbicki
Setting false to useFileMappedBuffer in webdefault.xml did NOTwork for me (Jetty 8.1.10.v20130312). Fortunately setting maxCachedFiles to 0 (also in webdefault.xml) did the trick.
在webdefault.xml设置假以useFileMappedBuffer根本不是为我工作(码头8.1.10.v20130312)。幸运的是,将 maxCachedFiles 设置为 0(也在 webdefault.xml 中)可以解决问题。
回答by Johannes Brodwall
Similar to @kybernetikos answer, but without having to recreate the DefaultServlet:
类似于@kybernetikos 的回答,但无需重新创建 DefaultServlet:
// Startup stuff
final Server server = new Server(port);
WebAppContext webAppContext = new WebAppContext(path, "/")
webAppContext.setInitParam(
"org.eclipse.jetty.servlet.Default.useFileMappedBuffer", "false");
server.setHandler(webAppContext);
server.start();
server.join();
DefaultServlet will look for it's own copy of useFileMappedBuffer, which seems to be set deep inside of Jetty. But by prefixing the property name with as above, this value is preferred.
DefaultServlet 将寻找它自己的 useFileMappedBuffer 副本,它似乎设置在 Jetty 的深处。但是通过在属性名称前面加上如上的前缀,这个值是首选的。
回答by Julien Kronegg
Jetty 9.2 documentationgives a Jetty Embedded example to serve static files using a ResourceHandler
instead of a servlet :
Jetty 9.2 文档提供了一个 Jetty Embedded 示例来使用ResourceHandler
servlet 代替 servlet来提供静态文件:
// Create a basic Jetty server object that will listen on port 8080. Note that if you set this to port 0
// then a randomly available port will be assigned that you can either look in the logs for the port,
// or programmatically obtain it for use in test cases.
Server server = new Server(8080);
// Create the ResourceHandler. It is the object that will actually handle the request for a given file. It is
// a Jetty Handler object so it is suitable for chaining with other handlers as you will see in other examples.
ResourceHandler resource_handler = new ResourceHandler();
// Configure the ResourceHandler. Setting the resource base indicates where the files should be served out of.
// In this example it is the current directory but it can be configured to anything that the jvm has access to.
resource_handler.setDirectoriesListed(true);
resource_handler.setWelcomeFiles(new String[]{ "index.html" });
resource_handler.setResourceBase(".");
// Add the ResourceHandler to the server.
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { resource_handler, new DefaultHandler() });
server.setHandler(handlers);
// Start things up! By using the server.join() the server thread will join with the current thread.
// See "http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Thread.html#join()" for more details.
server.start();
server.join();
Jetty uses NIO (in-memory file mapping) and thus locks files on Windows operating systems. This is a known issue and many workarounds can be found for servlets.
Jetty 使用 NIO(内存文件映射)并因此锁定 Windows 操作系统上的文件。这是一个已知问题,可以为 servlet 找到许多解决方法。
However, as this example does not rely on servlets, the associated answers based on webapp parameters (useFileMappedBuffer, maxCachedFiles) do not work.
但是,由于此示例不依赖于 servlet,因此基于 webapp 参数(useFileMappedBuffer、maxCachedFiles)的相关答案不起作用。
In order to prevent in-memory file mapping, you need to add the following configuration line:
为了防止内存文件映射,你需要添加以下配置行:
resource_handler.setMinMemoryMappedContentLength(-1);
Note: as written in the Javadoc (and noticed by nimrodm) : the minimum size in bytes of a file resource that will be served using a memory mapped buffer, or -1 for no memory mapped buffers
. I however got the same behavior with value Integer.MAX_VALUE
.
注:写在的Javadoc(和注意到了nimrodm) the minimum size in bytes of a file resource that will be served using a memory mapped buffer, or -1 for no memory mapped buffers
。然而,我得到了与 value 相同的行为Integer.MAX_VALUE
。
Once this parameter is set, your Jetty can serve static files on Windows AND you can edit them.
设置此参数后,您的 Jetty 就可以在 Windows 上提供静态文件并且您可以编辑它们。
回答by Wojtek
When using IntelliJ and Jetty 9 with a ResourceHandler one of the solutions is to edit the static content in the target directory, instead of the source file.
将 IntelliJ 和 Jetty 9 与 ResourceHandler 一起使用时,解决方案之一是编辑目标目录中的静态内容,而不是源文件。
回答by Yurii Bondarenko
I also had this problem.
我也有这个问题。
And I didn't want to create any additional classes and messing with web.xml
而且我不想创建任何额外的类并弄乱 web.xml
So here is what you can do:
因此,您可以执行以下操作:
Assuming you project is maven based and (lets say) called 'my-web-app'
假设您的项目是基于 maven 的,并且(可以说)称为“my-web-app”
1) create a file my-web-app/jetty/jetty-config.xml
1) 创建一个文件 my-web-app/jetty/jetty-config.xml
2) put this stuff inside:
2)把这个东西放在里面:
<?xml version="1.0" encoding="UTF-8"?>
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
<Call name="setInitParameter">
<Arg>org.eclipse.jetty.servlet.Default.useFileMappedBuffer</Arg>
<Arg>false</Arg>
</Call>
</Configure>
3) Here is your jetty config:
3)这是您的码头配置:
<plugin>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-maven-plugin</artifactId>
<configuration>
<httpConnector>
<host>localhost</host>
<port>8801</port>
</httpConnector>
<webApp>
<contextPath>/${project.artifactId}</contextPath>
</webApp>
<contextXml>${project.basedir}/jetty/jetty-config.xml</contextXml>
</configuration>
</plugin>
This solution will add an attribute to you servlet-context which will disable static resources locking.
此解决方案将为您的 servlet-context 添加一个属性,该属性将禁用静态资源锁定。
Have fun :)
玩得开心 :)