如何以编程方式允许端点的 GET 方法? [英] How to allow GET method for endpoint programmatically?

查看:32
本文介绍了如何以编程方式允许端点的 GET 方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在加载一个 .war 文件并将其作为 Web 应用程序添加到嵌入式 Tomcat 服务器.

I am loading a .war file and add it as web app to the embedded Tomcat server.

@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 我得到

This is working so far but if I access http://localhost:8080/web I am getting

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

我确信我所要做的就是允许 /web 上的 GET 方法,并希望从加载的 war 文件可通过网络浏览器访问.

I am sure all I have to do is to allow the GET method on /web and hopefully the static web content provided from the loaded war file will be accessible via web browser.

如何/在何处配置端点以允许 GET 请求?

How/where can I configure the endpoint such that it allows GET requests?

我尝试引入一个 WebController,如本教程中所述.

I tried to introduce a WebController as described in this tutorial.

@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";
   }
}

在日志输出中,我可以看到这是正确映射的:

In the log output I can see that this is getting mapped correctly:

RequestMappingHandlerMapping : Mapped "{[/web],methods=[GET]}" onto public java.lang.String org.ema.server.spring.controller.dl4j.WebController.index()

但这并没有改变我无法访问该网站的事实.

but it does not change the fact that I cannot visit the website.

我还配置了一个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配置的,所以这个文件没有定义很多:

Since I configure everything in pure Java, this file does not define a lot:

<?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

这将克隆、构建和运行服务器.

This will clone, build and run the server.

目前需要目录~/.ema 目录.这是服务器启动时复制 WAR 的地方.

The directory ~/.ema directory is required at the moment. It is where the WAR is being copied as the server starts.

推荐答案

我的猜测是您的 web.xml 将任何路径映射到 Spring DispatcherServlet,例如:

My guess is that your web.xml maps any path to the Spring DispatcherServlet, something like:

<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>

由于 / 任何请求都必须由 Spring 控制器处理,因此您的静态文件不会由 Tomcat 提供服务.像 /*.html 这样的模式也会有同样的效果.

Because of <url-pattern>/</url-pattern> any request must be handled by a Spring controller, for this reason your static files are not served by Tomcat. Also a pattern like /*.html would have same effect.

如果您只有几页,您可以将一个或多个映射添加到预定义的 默认servlet之前 Spring 的映射(如果你使用它,也可以在 Spring Security 之前):

If you have only a few pages you might add one or more mapping to the predefined default servlet for them, before the mapping of Spring (and also before Spring Security if you use it):

 <servlet-mapping>
  <servlet-name>default</servlet-name>
  <url-pattern>index.html</url-pattern>
 </servlet-mapping>

您也可以使用 <url-pattern>*.html</url-pattern> 或者,如果您的资源位于 web 路径下并且只有那里的静态资源:/web/*

You may also use <url-pattern>*.html</url-pattern> or, if your resources are under the web path and there are only static resources there: <url-pattern>/web/*</url-pattern>

也许所有这些都是在 org.ema.server.ServerEntryPoint 中的 Java 代码中完成的,您在 web.xml 中作为侦听器

Maybe all this is done instead in Java code in the org.ema.server.ServerEntryPoint that you have as a listener in web.xml

我认为我在 web.xml 中写的映射是在你的情况下在 org.ema.server.spring.config 类的方法 getServletMappings 中完成的.AppInitializer,我将其更改为使用更严格的模式 /rest-api/* 而不是 /,不确定模式是正确的,其他一切正常,但现在 http://127.0.0.1:8080/index.html 有效

I think the mapping I wrote up in web.xml is done in your case in method getServletMappings of class org.ema.server.spring.config.AppInitializer, I changed it to use a more strict pattern /rest-api/* instead than /, not sure pattern is correct and everything else works, but now http://127.0.0.1:8080/index.html works

   @Override
protected String[] getServletMappings() {
    return new String[] { "/rest-api/*" };
}

这篇关于如何以编程方式允许端点的 GET 方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆