简单 REST API returns HTTP 500

Simple REST API returns HTTP 500

我正在尝试制作一个简单的 Hello World REST API。我正在使用 IntelliJ IDEA 作为我的 IDE。我已经下载了 Tomcat 8.5.4 作为我的本地测试服务器。如果重要的话,我正在 Mac 上开发。我导入了 Jersey 库:

这是我的 web.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>HelloWorld</display-name>
    <servlet>
        <servlet-name>com.jamesshinevar.HelloWorld</servlet-name>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.jamesshinevar</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>com.jamesshinevar.HelloWorld</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
</web-app>

这是我的 class 代码:

package com.jamesshinevar;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/test")
public class HelloWorld {
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String hello(){
        return "Hello";
    }
}

我然后 运行 这个我得到指示它是 运行 如下:

/Users/james/apache-tomcat-8.5.4/bin/catalina.sh run
[2016-08-16 09:33:11,573] Artifact helloworldREST:war exploded: Server is not connected. Deploy is not available.
16-Aug-2016 09:33:12.907 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server version:        Apache Tomcat/8.5.4
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server built:          Jul 6 2016 08:43:30 UTC
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Server number:         8.5.4.0
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Name:               Mac OS X
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log OS Version:            10.11.6
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Architecture:          x86_64
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Java Home:             /Library/Java/JavaVirtualMachines/jdk1.8.0_101.jdk/Contents/Home/jre
16-Aug-2016 09:33:12.909 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Version:           1.8.0_101-b13
16-Aug-2016 09:33:12.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log JVM Vendor:            Oracle Corporation
16-Aug-2016 09:33:12.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_BASE:         /Users/james/Library/Caches/IntelliJIdea2016.2/tomcat/Tomcat_8_5_4_helloworldREST_4
16-Aug-2016 09:33:12.910 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log CATALINA_HOME:         /Users/james/apache-tomcat-8.5.4
16-Aug-2016 09:33:12.911 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.config.file=/Users/james/Library/Caches/IntelliJIdea2016.2/tomcat/Tomcat_8_5_4_helloworldREST_4/conf/logging.properties
16-Aug-2016 09:33:12.911 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
16-Aug-2016 09:33:12.911 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote=
16-Aug-2016 09:33:12.911 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.port=1099
16-Aug-2016 09:33:12.911 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.ssl=false
16-Aug-2016 09:33:12.911 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcom.sun.management.jmxremote.authenticate=false
16-Aug-2016 09:33:12.912 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.rmi.server.hostname=127.0.0.1
16-Aug-2016 09:33:12.912 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djdk.tls.ephemeralDHKeySize=2048
16-Aug-2016 09:33:12.912 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.base=/Users/james/Library/Caches/IntelliJIdea2016.2/tomcat/Tomcat_8_5_4_helloworldREST_4
16-Aug-2016 09:33:12.912 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Dcatalina.home=/Users/james/apache-tomcat-8.5.4
16-Aug-2016 09:33:12.912 INFO [main] org.apache.catalina.startup.VersionLoggerListener.log Command line argument: -Djava.io.tmpdir=/Users/james/apache-tomcat-8.5.4/temp
16-Aug-2016 09:33:12.912 INFO [main] org.apache.catalina.core.AprLifecycleListener.lifecycleEvent The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: /Users/james/Library/Java/Extensions:/Library/Java/Extensions:/Network/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java:.
16-Aug-2016 09:33:13.174 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["http-nio-8080"]
16-Aug-2016 09:33:13.210 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
16-Aug-2016 09:33:13.214 INFO [main] org.apache.coyote.AbstractProtocol.init Initializing ProtocolHandler ["ajp-nio-8009"]
16-Aug-2016 09:33:13.216 INFO [main] org.apache.tomcat.util.net.NioSelectorPool.getSharedSelector Using a shared selector for servlet write/read
16-Aug-2016 09:33:13.216 INFO [main] org.apache.catalina.startup.Catalina.load Initialization processed in 802 ms
16-Aug-2016 09:33:13.250 INFO [main] org.apache.catalina.core.StandardService.startInternal Starting service Catalina
16-Aug-2016 09:33:13.250 INFO [main] org.apache.catalina.core.StandardEngine.startInternal Starting Servlet Engine: Apache Tomcat/8.5.4
16-Aug-2016 09:33:13.259 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler [http-nio-8080]
16-Aug-2016 09:33:13.267 INFO [main] org.apache.coyote.AbstractProtocol.start Starting ProtocolHandler [ajp-nio-8009]
16-Aug-2016 09:33:13.268 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in 51 ms
Connected to server
[2016-08-16 09:33:13,571] Artifact helloworldREST:war exploded: Artifact is being deployed, please wait...
[2016-08-16 09:33:14,065] Artifact helloworldREST:war exploded: Artifact is deployed successfully
[2016-08-16 09:33:14,066] Artifact helloworldREST:war exploded: Deploy took 494 milliseconds
16-Aug-2016 09:33:23.264 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deploying web application directory /Users/james/apache-tomcat-8.5.4/webapps/manager
16-Aug-2016 09:33:23.292 INFO [localhost-startStop-1] org.apache.catalina.startup.HostConfig.deployDirectory Deployment of web application directory /Users/james/apache-tomcat-8.5.4/webapps/manager has finished in 28 ms

当我尝试前往 URL 时,我得到:

在 IntelliJ 的 Tomcat Localhost 登录中,我有:

16-Aug-2016 09:35:39.773 SEVERE [http-nio-8080-exec-8] org.apache.catalina.core.StandardHostValve.invoke Exception Processing /helloworld/api/test
 java.lang.NullPointerException
    at java.util.concurrent.ConcurrentHashMap.putVal(ConcurrentHashMap.java:1011)
    at java.util.concurrent.ConcurrentHashMap.putIfAbsent(ConcurrentHashMap.java:1535)
    at java.lang.ClassLoader.getClassLoadingLock(ClassLoader.java:463)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1151)
    at org.apache.catalina.loader.WebappClassLoaderBase.loadClass(WebappClassLoaderBase.java:1118)
    at org.apache.catalina.core.StandardWrapper.servletSecurityAnnotationScan(StandardWrapper.java:1139)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:510)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:620)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

我不明白是什么导致了导致 500 错误的 NullPointerException。我确定它就在我眼前,但我只是不理解我所看到的。任何人都可以给我一些关于如何使这项工作的指示吗?这看起来应该很简单。我想要一个 API 只是 returns "Hello" 字符串,但显然我遇到了困难。

我认为错误在 web.xml 中。如图所示 mkyong:

<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Restful Web Application</display-name>

    <servlet>
        <servlet-name>jersey-serlvet</servlet-name>
        <servlet-class>
                     com.sun.jersey.spi.container.servlet.ServletContainer
                </servlet-class>
        <init-param>
             <param-name>com.sun.jersey.config.property.packages</param-name>
             <param-value>com.jamesshinevar</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>jersey-serlvet</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>

</web-app>

您指定的 class 不是 servlet。 jersey 的工作是提供 servlet 并将请求映射到带注释的 classes。

您缺少 servlet-class 条目

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         version="3.1">
    <display-name>HelloWorld</display-name>
    <servlet>
        <servlet-name>com.jamesshinevar.HelloWorld</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>com.jamesshinevar</param-value>
        </init-param>
    </servlet>

    <servlet-mapping>
        <servlet-name>com.jamesshinevar.HelloWorld</servlet-name>
        <url-pattern>/api/*</url-pattern>
    </servlet-mapping>
</web-app>

您需要将 <servlet-class> 条目添加到 web.xml,如 com.sun.jersey.spi.container.servlet.ServletContainer

有关详细信息,请查看本教程:https://www.ibm.com/developerworks/library/wa-aj-tomcat/