我正在加载.war文件,并将其作为Web应用程序添加到嵌入式Tomcat服务器。
.war
@Bean public EmbeddedServletContainerFactory servletContainerFactory() { LOGGER.info("Adding web app"); return new TomcatEmbeddedServletContainerFactory() { @Override protected TomcatEmbeddedServletContainer getTomcatEmbeddedServletContainer(Tomcat tomcat) { String appHome = System.getProperty(Environment.APP_HOME); String targetFileName = "web-0.0.1-SNAPSHOT.war"; InputStream resourceAsStream = getClass().getClassLoader().getResourceAsStream(targetFileName); LOGGER.info(System.getProperty("user.name")); LOGGER.debug("Loading WAR from " + appHome); File target = new File(Paths.get(appHome, targetFileName).toString()); try { LOGGER.info(String.format("Copy %s to %s", targetFileName, target.getAbsoluteFile().toPath())); java.nio.file.Files.copy(resourceAsStream, target.getAbsoluteFile().toPath(), StandardCopyOption.REPLACE_EXISTING); Context context = tomcat.addWebapp("/", target.getAbsolutePath()); context.setParentClassLoader(getClass().getClassLoader()); } catch (ServletException ex) { throw new IllegalStateException("Failed to add webapp.", ex); } catch (Exception e) { throw new IllegalStateException("Unknown error while trying to load webapp.", e); } return super.getTomcatEmbeddedServletContainer(tomcat); } }; }
到目前为止,这是可行的,但是如果我访问http:// localhost:8080 / web,我会得到
2017-03-04 11:18:59.588 WARN 29234 --- [nio-8080-exec-2] o.s.web.servlet.PageNotFound : Request method 'GET' not supported
和回应
Allow: POST Content-Length: 0 Date: Sat, 04 Mar 2017 10:26:16 GMT
我敢肯定,我所要做的就是允许该GET方法启用,/web并希望war可以通过Web浏览器访问从加载的文件提供的静态Web内容。
GET
/web
war
如何/在何处配置端点以允许GET请求?
我想介绍一个WebController在描述本教程。
WebController
@Controller public class WebController { private final static Logger LOGGER = Logger.getLogger(WebController.class); @RequestMapping(value = "/web", method = RequestMethod.GET) public String index() { LOGGER.info("INDEX !"); return "index"; } }
在日志输出中,我可以看到它已正确映射:
RequestMappingHandlerMapping : Mapped "{[/web],methods=[GET]}" onto public java.lang.String org.ema.server.spring.controller.dl4j.WebController.index()
但这并不能改变我无法访问该网站的事实。
我还配置了InternalResourceViewResolver:
InternalResourceViewResolver
@Configuration @EnableWebMvc public class MvcConfiguration extends WebMvcConfigurerAdapter { private final static Logger LOGGER = Logger.getLogger(MvcConfiguration.class); @Override public void configureViewResolvers(ViewResolverRegistry registry) { LOGGER.info("configureViewResolvers()"); InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setSuffix(".html"); registry.viewResolver(resolver); } @Override public void configureDefaultServletHandling( DefaultServletHandlerConfigurer configurer) { configurer.enable(); } }
web.xml
由于我使用纯Java配置所有内容,因此该文件定义不多:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Easy Model Access Server</display-name> <listener> <listener-class>org.ema.server.ServerEntryPoint</listener-class> </listener> <context-param> <param-name>log4j-config-location</param-name> <param-value>WEB-INF/classes/log4j.properties</param-value> </context-param> <servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/web/*.html</url-pattern> </servlet-mapping> </web-app>
如果要重现此代码,则可以从github签出整个代码。您需要执行的所有操作:
mkdir ~/.ema git clone https://github.com/silentsnooc/easy-model-access cd easy-model-access/ema-server mvn clean install java -jar server/target/server-*.jar
这将克隆,构建并运行服务器。
目前~/.ema需要目录目录。服务器启动时将在其中复制WAR。
~/.ema
我的猜测是您的web.xml将任何路径映射到Spring DispatcherServlet,例如:
<servlet> <servlet-name>app</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>app</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
由于<url-pattern>/</url- pattern>任何请求都必须由Spring控制器处理,因此,Tomcat不提供静态文件。同样的模式/*.html也会有相同的效果。
<url-pattern>/</url- pattern>
/*.html
如果只有几个页面,则可以在Spring的映射 之前* (如果使用的话,在Spring Security 之前) ,向它们的预定义默认servlet添加一个或多个映射: *
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>index.html</url-pattern> </servlet-mapping>
您也可以使用,<url-pattern>*.html</url-pattern>或者,如果您的资源在web路径下并且那里只有静态资源:<url- pattern>/web/*</url-pattern>
<url-pattern>*.html</url-pattern>
web
<url- pattern>/web/*</url-pattern>
也许所有这些操作都可以在Java代码中完成,而org.ema.server.ServerEntryPoint您在web.xml中具有侦听器
org.ema.server.ServerEntryPoint
我认为我写的映射web.xml是在您的情况下在getServletMappingsclass 方法中完成的org.ema.server.spring.config.AppInitializer,我将其更改为使用比 更加严格的模式 ,不确定模式是否正确并且其他所有方法都可以正常工作,但现在可以正常工作/rest- api/*``/``http://127.0.0.1:8080/index.html
getServletMappings
org.ema.server.spring.config.AppInitializer
/rest- api/*``/``http://127.0.0.1:8080/index.html
@Override protected String[] getServletMappings() { return new String[] { "/rest-api/*" }; }