Reputation: 7030
I am having an opposite error of what's written here.
I'm just trying to run a very simple sample application of Restlet in Eclipse.
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();
}
The code works perfectly as is if I'm running the server locally and if I type the full uri including the localhost on my browser "localhost:8111". However, as soon as I change my router declaration to be router, the page always throws a 404 error.
@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;
}
So in other words, if I attach a full path including the http and the ip address to the router, it works correctly but the relative path doesn't.
This is pretty bizzare. If there's any error, I would've assumed that the relative definition should work and the localhost definition shouldn't, but what I'm experiencing is the exact opposite. Any suggestions?
Edit:
Upon request, I'm including my 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);
}
}
And the 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();
}
Upvotes: 2
Views: 1766
Reputation: 5654
This is because you are running restlet in standalone
mode. To be more specific MailServerApplication
has main-method from which you are running restlet.
To fix the issue, you need to make your web-container understand the details of your Application
.
Here is a skeleton version of the code needed for you to run. This way, you need not mention the IP
, Port
details in the url-binding (this example uses Jetty, you could as well use 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>
Goto the project's root folder and execute using: mvn clean compile jetty:run
Hope this helps
Upvotes: 2