java - ReSTLet 路由器相对路径错误

标签 java http rest restlet

我遇到了与所写内容相反的错误 here .

我只是尝试在 Eclipse 中运行一个非常简单的 ReSTLet 示例应用程序。

MailServerApplication.java

public class MailServerApplication extends Application {

    /**
     * Launches the application with an HTTP server.
     * 
     * @param args
     *            The arguments.
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        Server mailServer = new Server(Protocol.HTTP, 8111);
        mailServer.setNext(new MailServerApplication());
        mailServer.start();
    }

    /**
     * Constructor.
     */
    public MailServerApplication() {
        setName("RESTful Mail Server");
        setDescription("Example for 'Restlet in Action' book");
        setOwner("Restlet S.A.S.");
        setAuthor("The Restlet Team");
    }

    /**
     * Creates a root Router to dispatch call to server resources.
     */
    @Override
    public Restlet createInboundRoot() {
        Router router = new Router(getContext());
        router.attach("http://localhost:8111/", 
                RootServerResource.class);
        router.attach("http://localhost:8111/accounts/",
                AccountsServerResource.class);
        router.attach("http://localhost:8111/accounts/{accountId}",
                AccountServerResource.class);
        return router;
    }
}

RootServerResource.java

public class RootServerResource 
    extends ServerResource implements RootResource {

    public String represent() {
        return "This is the root resource";
    }

    public String describe() {
        throw new RuntimeException("Not yet implemented");
    }
}

RootResource.java

/**
 * Root resource.
 */
public interface RootResource {

    /**
     * Represents the application root with a welcome message.
     * 
     * @return The root representation.
     */
    @Get("txt")
    public String represent();

}

如果我在本地运行服务器并且在浏览器“localhost:8111”上键入包括本地主机的完整 uri,则代码可以正常工作。但是,一旦我将路由器声明更改为路由器,页面总是会抛出 404 错误。

@Override
public Restlet createInboundRoot() {
    Router router = new Router(getContext());
    router.attach("/", RootServerResource.class); 
    router.attach("/accounts/", AccountsServerResource.class);
    router.attach("/accounts/{accountId}", AccountServerResource.class);
    return router;
}

换句话说,如果我将包含 http 和 IP 地址的完整路径附加到路由器,它可以正常工作,但相对路径则不能。

这实在是太奇怪了。如果出现任何错误,我会假设相对定义应该起作用,而本地主机定义不应该起作用,但我遇到的情况恰恰相反。有什么建议吗?

编辑:

根据要求,我将添加我的 AccountServerResource.class

/**
 * Implementation of a mail account resource.
 */
public class AccountServerResource extends ServerResource implements
        AccountResource {

    /** The account identifier. */
    private int accountId;

    /**
     * Retrieve the account identifier based on the URI path variable
     * "accountId" declared in the URI template attached to the application
     * router.
     */
    @Override
    protected void doInit() throws ResourceException {
        this.accountId = Integer.parseInt(getAttribute("accountId"));
    }

    public String represent() {
        return AccountsServerResource.getAccounts().get(this.accountId);
    }

    public void store(String account) {
        AccountsServerResource.getAccounts().set(this.accountId, account);
    }

    public void remove() {
        AccountsServerResource.getAccounts().remove(this.accountId);
    }
}

以及AccountResource接口(interface):

/**
 * User account resource.
 */
public interface AccountResource {

    /**
     * Represents the account as a simple string with the owner name for now.
     * 
     * @return The account representation.
     */
    @Get("txt")
    public String represent();

    /**
     * Stores the new value for the identified account.
     * 
     * @param account
     *            The identified account.
     */
    @Put("txt")
    public void store(String account);

    /**
     * Deletes the identified account by setting its value to null.
     */
    @Delete
    public void remove();

}

最佳答案

这是因为您正在独立模式下运行reSTLet。更具体地说,MailServerApplication 有 main-method,您可以从中运行 ReSTLet。

要解决此问题,您需要让 Web 容器了解应用程序的详细信息。

这是您运行所需的代码的骨架版本。这样,您不需要在url绑定(bind)中提及IPPort详细信息(本例使用Jetty,您也可以使用tomcat ):

MyApplication.java:

package com.sample;

import org.restlet.Application;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.MediaType;
import org.restlet.representation.StringRepresentation;
import org.restlet.routing.Router;

public class MyApplication extends Application {

    public MyApplication() {
        super();
    }

    public MyApplication(Context parentContext) {
        super(parentContext);
    }

    public Restlet createInboundRoot() {
        Router router = new Router(getContext());

        router.attach("/hello", HelloResource.class);

  Restlet mainpage = new Restlet() {
            @Override
            public void handle(Request request, Response response) {
                StringBuilder stringBuilder = new StringBuilder();

                stringBuilder.append("<html>");
                stringBuilder.append("<head><title>Hello Application " +
                        "Servlet Page</title></head>");
                stringBuilder.append("<body bgcolor=white>");
                stringBuilder.append("<a href=\"app/hello\">hello</a> --> returns hello world message " +
                        "and date string");
                stringBuilder.append("</body>");
                stringBuilder.append("</html>");
                response.setEntity(new StringRepresentation(
                        stringBuilder.toString(),
                        MediaType.TEXT_HTML));
            }
        };
        router.attach("", mainpage);

        return router;
    }

}

web.xml:

<?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" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
    id="WebApp_ID" version="2.5">
  <display-name>Archetype Created Web Application</display-name>

         <servlet>
                 <servlet-name>Restlet</servlet-name>
                 <servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
                 <init-param>
                         <param-name>org.restlet.application</param-name>
                         <param-value>com.sample.MyApplication</param-value>
                 </init-param>
         </servlet>

    <servlet-mapping>
        <servlet-name>Restlet</servlet-name>
        <url-pattern>/app/*</url-pattern>
    </servlet-mapping>  
</web-app>

HelloResource.java:

package com.sample;

import java.util.Calendar;

import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.MediaType;
import org.restlet.representation.Representation;
import org.restlet.representation.StringRepresentation;
import org.restlet.representation.Variant;
import org.restlet.resource.ResourceException;
import org.restlet.resource.ServerResource;

public class HelloResource extends ServerResource {

    public HelloResource() {
        super();
    }
    public HelloResource(Context context,
                          Request request,
                          Response response) {     
        getVariants().add(new Variant(MediaType.TEXT_PLAIN));
    }

    @Override
    protected Representation get() throws ResourceException {
        String message = "Hello World!" +
        " \n\nTime of request is:"
        + Calendar.getInstance()
        .getTime().toString();

        return new StringRepresentation(message,
        MediaType.TEXT_PLAIN);
    }

}

pom.xml:

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.sample</groupId>
    <artifactId>testwar</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>war</packaging>
    <repositories>
        <repository>
           <id>maven-restlet</id>
           <name>Public online Restlet repository</name>
           <url>http://maven.restlet.org</url>
        </repository>
    </repositories>

    <pluginRepositories>
      <pluginRepository>
        <id>numberformat-releases</id>
        <url>https://raw.github.com/numberformat/20130213/master/repo</url>
      </pluginRepository>
    </pluginRepositories>

  <dependencies>

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
            <version>2.5</version>
            <scope>provided</scope>
        </dependency>

    <dependency>
       <groupId>org.restlet.jse</groupId>
       <artifactId>org.restlet</artifactId>
       <version>2.0.0</version>
    </dependency>
    <dependency>
       <groupId>org.restlet.jse</groupId>
       <artifactId>org.restlet.ext.simple</artifactId>
       <version>2.0.0</version>
    </dependency>
    <dependency>
       <groupId>org.restlet.jee</groupId>
       <artifactId>org.restlet.ext.servlet</artifactId>
       <version>2.0.0</version>
    </dependency>
        <dependency>
            <groupId>org.apache.geronimo.specs</groupId>
            <artifactId>geronimo-servlet_2.5_spec</artifactId>
            <version>1.2</version>
            <scope>provided</scope>
        </dependency>
  </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.5</source>
                    <target>1.5</target>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mortbay.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>7.0.0.v20091005</version>
                <configuration>
                    <scanIntervalSeconds>2</scanIntervalSeconds>
                </configuration>
            </plugin>
            <plugin>        
                <groupId>github.numberformat</groupId>
                <artifactId>blog-plugin</artifactId>
                <version>1.0-SNAPSHOT</version>
                <configuration>
                <gitUrl>https://github.com/numberformat/20110220</gitUrl>
                </configuration>
            <executions>
              <execution>
                <id>1</id>
                <phase>site</phase>
                <goals>
                  <goal>generate</goal>
                </goals>            
              </execution>
            </executions>
            </plugin>
        </plugins>

        <finalName>testwar</finalName>
    </build>

</project>

转到项目的根文件夹并使用以下命令执行:mvn cleancompilejetty:run

希望这有帮助

关于java - ReSTLet 路由器相对路径错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17001242/

相关文章:

java - 根据 toMap 集合中的值过滤流

java - ActiveMQ 内存消耗通过屋顶(页面文件)...该怎么办?

asp.net-mvc - 返回在 HttpStatusCode 枚举中找不到的状态代码

http - 在 AWS-IoT 中使用 http 列出事物 api?

web-services - ServiceStack 客户端和二义性路由

scala - scala 中的 RESTful http DELETE 方法(玩 2.0)

java - 在 OpenShift 上使用 JPA 时出现奇怪的错误

java - 为什么 javax.xml.xpath.XPath 对克隆节点的行为不同?

Flash - FileReference,一次上传多个文件

node.js - express 服务器在 5 个 POST 后没有响应