关于欢迎页面和访问Web服务方法

时间:2017-10-13 08:48:08

标签: java rest servlets intellij-idea

我遇到配置问题(或基本了解事情在后台工作的方式)。我通过检查Web应用程序和ReSt api复选框创建了一个JAVAEE项目(在intellij中使用glassfish 5.0)。我有下面的示例代码,Web方法可以工作,但欢迎页面不起作用。我的web.xml和示例Web服务方法如下所示。

<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>test</param-value>
    </init-param>
    <init-param>
        <param-name>com.sun.jersey.api.json.POJOMappingFeature</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    **<url-pattern>/ *</url-pattern>**
</servlet-mapping>



@Path("/RestTest")
public class TestString {

@Context
ServletContext context;

@GET
@Path("insertdb/{param1}/{param2}")
@Produces(MediaType.APPLICATION_JSON)
public Object writeToDb( @PathParam("param1") String param1
                        ,@PathParam("param2") String param2){
     try{
        String password=  context.getInitParameter("DbPassword");
        Class.forName("org.mariadb.jdbc.Driver");
        Connection dbCon = DriverManager.getConnection(
                 "jdbc:mariadb://xxx/testdb", "root", password);
        PreparedStatement stmt=dbCon.prepareStatement(
                "INSERT INTO TestTable VALUES(?,?)");
        stmt.setString(1,param1);
        stmt.setString(2,param2);
        stmt.executeUpdate();

        dbCon.close();

        return "Success";
    }catch(SQLException | ClassNotFoundException ex){
        return  ex.toString();
    }

}

@GET
@Path("sum/{sum1}/{sum2}")
@Produces(MediaType.TEXT_HTML)
public String calculateSum(@PathParam("sum1") int param1
        ,@PathParam("sum2") int param2){
    return ""+(param1 + param2);
}

如果我将此行 url-pattern“/ *”更改为“/” 那么欢迎页面是可访问的,但不是方法。

因此,我想要的是,有一个欢迎页面,我将用于我的Web服务的文档(我不想要SOAP)和Web方法必须通过添加/到基本URL。我怎样才能实现这一点以及/ *和/

之间的区别

4 个答案:

答案 0 :(得分:3)

请点击此处查看差异说明: What is url-pattern in web.xml and how to configure servlet

通常对于休息api,最好使用特定于所有其他呼叫的路径,例如http://localhost/mywebapp/rest/ ...

类似的东西:

<servlet-mapping>
    <servlet-name>jersey-servlet/servlet-name>
    <url-pattern>/rest/*</url-pattern>
</servlet-mapping>

您只希望球衣在包含在包含html网页的WAR中捆绑特定网址时提供服务。

答案 1 :(得分:1)

Servlet配置和url-pattern

正如您所强调的那样,您的问题围绕着这四行:

<servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

Jim Weaver所述,这是url-pattern的问题。

将(S)

您可以考虑三种解决方案(从最优选到最不优选):

  1. 专用REST网址:最简单的方法是为您的网络服务设置专用的url-pattern,例如/rest/*。您可以使某些资产(例如URL层次结构)受益,或者您可以轻松地在其上实现安全框架。
  2. 网址重写可能是一个选项,this answer建议使用某些库。我自己没有测试过这些库
  3. Page redirection可以选择围绕REST过滤,但在url-pattern /*的特定情况下,我不得不说我不确定它是否适用于我将在下一节解释的原因
  4. 现在对发生的事情

    进行了一些解释

    为什么在url-pattern设置/*会阻止访问欢迎页面?

    实际上,不仅是欢迎页面不可访问:它是定义的url-pattern下的所有资源。无论与REST保持联系还是使用REST ...以下是从JSR 339 Appendix C获取的模式: JSR 339 Appendix C

    使用GlassFish 5.0,我猜你正在使用JAX-RS 2.1(JSR 370),但我引用的部分内容相同

    如果不详细说明,可以看到在此过程中只执行了ContainerRequest Filters特别值得注意的是,在Request Matching之后,请求不会转发到任何servlet ,因为标准资源是无法访问的,除非REST方法指定。

    值得强调的是事先执行servlet过滤器(例如,利用这一点对于管理安全性至关重要)。 我没有找到证明这一点的来源,但我知道它在网上的某个地方^^

    Request matching3.7.2部分定义。简而言之,它分为三个步骤,第一步对您的问题最重要,特别是在步骤D:

      
        
    1. 标识与请求匹配的一组候选根资源类

           

      ℃。 ...

           

      d。如果[路径与请求URL匹配的类集合]为空,则找不到匹配的资源,算法终止,实现必须生成NotFoundException(404 status)且没有实体

           

      即...

    2.   

    要点是我的。

    最后两步是

      
        
    1. 获取请求的一组候选资源方法
    2.   
    3. 确定将处理请求的方法
    4.   

    TL; DR

    当您设置<url-pattern>/*<url-pattern>并尝试访问您的欢迎页面(或实际的任何页面)时发生了什么:

    1. 您的服务器收到GET请求
    2. 如果有过滤器(例如来自安全框架的过滤器),则执行
    3. REST进入场景
    4. 执行预匹配过滤器(如果您的情况,则为无)
    5. 获取根资源类(在您的示例中,test包中的所有类)
    6. 查找其中一个类是否与请求网址匹配
    7. 找不到任何内容,返回404状态
    8. 为避免不必要的URL冲突,最好的选择是为REST方法提供专用URL

答案 2 :(得分:1)

要回答您的问题,"/"和“/*

之间存在差异

如果没有其他模式匹配,则包含模式"/"的映射会匹配请求。这是默认映射。映射到此模式的servlet称为默认servlet。默认映射通常指向应用程序的第一页。示例:

这两个请求都会显示index.jsp

中的相同内容
http://myhost.com/index.jsp

http://myhost.com/

现在,包含"/*" 的映射会覆盖所有其他servlet,包括servlet容器提供的所有servlet,例如缺省servlet和JSP servlet 。无论你发出什么样的请求,它都会在那个servlet中结束。因此,这是servlet的错误URL模式。

您的问题的可能解决方案

将网址格式更改为特定格式而非默认格式。

<servlet>
    <servlet-name>webservice</servlet-name>  //servlet name
    <servlet-class>com.rest.MyRestServlet</servlet-class>  //servlet class
</servlet>
 <servlet-mapping>
    <servlet-name>webservice</servlet-name>   //servlet name
    <url-pattern>/RestTest/*</url-pattern>  //all webservice request
</servlet-mapping>

可以通过

访问所有Web服务请求
http://myhost.com/RestTest/

您可能也有兴趣看

What is URL-pattern in web.xml and how to configure servlet

Basics of Java Servlet

答案 3 :(得分:0)

如果您在web xml中提及,请遵循泽西网络应用程序&#39;泽西网络应用程序的所有请求。 servlet的。所以对index.jsp的请求也会重定向到泽西网络应用程序&#39;小服务程序

<servlet-mapping>
  <servlet-name>Jersey Web Application</servlet-name>
  <url-pattern>/*</url-pattern>
</servlet-mapping>

为避免这种情况,请在网址中添加一些前缀以分隔休息请求,如下所示

<servlet-mapping>
  <servlet-name>Jersey Web Application</servlet-name>
  <url-pattern>rs/*</url-pattern>
</servlet-mapping>