coding a server on using restlet 2.0 - restlet-2.0

I am coding a server for a project of mine using restlet 2.0. I have a java class which starts the server (starting it on a port and all those stuff). I am stuck at a point where i need to map the uri's of different services i intend to offer. If i were to include uri mapping part in a servlet how do i go about it. what are the changes i need to make in the web.xml. i have found very little documentation regarding this.
Any help appreciated

In fact, the routing configuration must be done in your Restlet application class. You need to override the createInboundRoot method to attach your resources to paths, as described below:
public class MyRestletApplication extends Application {
public Restlet createInboundRoot() {
Router router = new Router(getContext());
router.attach("/path/{id}", MyServerResource.class);
(...)
return router;
}
}
The configured resources can be then reached through the configured Restlet server. For example, with the address http://localhost:8082/path/12 if you implement your Restlet server as following:
public static void main(String[] args) {
try {
Server server = new Server(Protocol.HTTP, 8182);
server.setNext(new MyRestletApplication());
server.start();
(...)
} catch(Exception ex) {}
}
Restlet also provides a servlet adapter with its org.restlet.ext.servlet extension. The latter allows using the ServerServlet servlet in order to access the configured resources. When configuring this servlet you need to specify the application class to use (the application contains the paths for your resources) through the org.restlet.application context parameter. The servlet can be configured as every servlet and be mapped on the /* pattern, as described below:
<web-app>
<context-param>
<param-name>org.restlet.application</param-name>
<param-value>org.restlet.example.MyApplication</param-value>
</context-param>
<servlet>
<servlet-name>ServerServlet</servlet-name>
<servlet-class>org.restlet.ext.servlet.ServerServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServerServlet</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
</web-app>
In this case, your RESTful application implemented with Restlet will be accessed through a servlet container. In this case, your application needs to be packaged as a Java EE web application and will be reached with address: http://localhost:8080/mywebapp/path/12.
Hope it'll help you.
Thierry

Related

spring mvc4 http 404 not found error

I have seen other similar posts here on stackoverflow - mostly the poster is hitting a link different than what the serving method in the RESTController resolves to. I am making sure (explained below) i am not doing that mistake but still its not working for me..
I am writing a Spring MVC4 based REST controller for a Servlet 2.5 container (weblogic 10.3.6) and I was suggested to follow this sample web.xml for my web app project
I have followed this web.xml but I am not sure what the contextAttribute with value (shown below) in this piece does ..
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextAttribute</param-name>
<param-value>org.springframework.web.context.WebApplicationContext.ROOT</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
When I am running my webapp and hitting it with REST client, I keep getting http 404 not found error. The complete error is posted here
http://paste.ubuntu.com/13966788/
Here's the error snippet
08:44:34.368 [main] DEBUG o.s.web.client.RestTemplate - GET request for "http://localhost:7001/demo-0.0.1-SNAPSHOT/customers/2" resulted in 404 (Not Found); inv
oking error handlerTests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.402 sec <<< FAILURE! - in demo.DemoApplicationTests
contextLoaded(demo.DemoApplicationTests) Time elapsed: 0.042 sec <<< ERROR!
org.springframework.web.client.HttpClientErrorException: 404 Not Found
at org.springframework.web.client.DefaultResponseErrorHandler.handleError(DefaultResponseErrorHandler.java:91)
at org.springframework.web.client.RestTemplate.handleResponse(RestTemplate.java:641)
at org.springframework.web.client.RestTemplate.doExecute(RestTemplate.java:597)
at org.springframework.web.client.RestTemplate.execute(RestTemplate.java:557)
at org.springframework.web.client.RestTemplate.getForEntity(RestTemplate.java:289)
at demo.DemoApplicationTests.contextLoaded(DemoApplicationTests.java:45)
i am not sure what should be my context root, The deployed webapp in the weblogic console shows the value 'demo-0.0.1-SNAPSHOT'
and my REST controller's method's #RequestMapping is /customers/{id}.
#RestController
public class CustomerRestController {
#Autowired
private CustomerRepository customerRepository;
#RequestMapping("/customers/{id}")
CustomerProtos.Customer customer(#PathVariable Integer id) {
return this.customerRepository.findById(id);
}
So I assume my url path should look like
localhost:7001/demo-0.0.1-SNAPSHOT/customers/2
but when I hit this URL (both in browser and in spring based test client)
I keep getting http 404 not found error.
Here's my spring test client..
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration
public class DemoApplicationTests {
#Configuration
public static class RestClientConfiguration {
#Bean
RestTemplate restTemplate(ProtobufHttpMessageConverter hmc) {
return new RestTemplate(Arrays.asList(hmc));
}
#Bean
ProtobufHttpMessageConverter protobufHttpMessageConverter() {
return new ProtobufHttpMessageConverter();
}
}
#Autowired
private RestTemplate restTemplate;
#Test
public void contextLoaded() {
ResponseEntity<CustomerProtos.Customer> customer = restTemplate.getForEntity(
"http://localhost:7001/demo-0.0.1-SNAPSHOT/customers/2", CustomerProtos.Customer.class);
System.out.println("customer retrieved: " + customer.toString());
}
I wonder if the contextAttribute is doing something here. Any ideas ?
The only other thing i am doing different here is instead of httpMessageConverter, I am registering Spring MVC4's ProtoBufHttpMessageConverter. But shouldn't be making a difference in this case.
My code is shared (on github) here https://goo.gl/cVNEPT
Do you have servletMapping defined as in the web.xml?
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Also, have public for your method
#RequestMapping("/customers/{id}")
public CustomerProtos.Customer customer(#PathVariable Integer id)
Do you see the request mapping path being registered in the log?

Apache Camel + Spring (war) + Tomcat + REST

I am trying to develp a rest service using apache camel. My project is a spring mvc war deployed on tomcat.
I dont want to use apache cxf (cxf servlet).
public class SampleRouter extends RouteBuilder {
#override
public void configure() throws Exception {
from("cxfrs://http://localhost:1234/sample")
.process (new Processor() {
public void process(Exchange exchange) throws Exception {
System.out.println("test");
}
})).setBody(constant("SUCCESS"));
}
}
#Path("/sample")
public class SampleResource {
#GET
public void test() {
}
}
web.xml has dispatcherservlet, contextloaderlistener.
dispatcher-servlet.xml has mvc:annotation-drivem, context:component-scan,
<camelContext id="server" trace="true" xmlns="http://camel.apache.org/schema/spring">
<contextScan />
</camelContext>
pom.xml has camel-core, camel-cxf, camel-stream, cxf-rt-transports-http-jetty, cxf-rs-frontend-jaxrs, camel-spring, spring-webmvc, spring-web, spring-context.
Tomcat runs on 8080, there seems to be no exception when server comes up. But, I tried hitting the url (http://localhost:1234/sample), nothing seems to be happening.
What am i missing? I would eventually extend this to REST to Spring DSL or REST to Java DSL with authentication, filters and interceptors.
I also tried cxf:rsServer and referred that in router class.
Also, in the future if i have to use https instead of http? or how do i have the url not hard-coded?
It may be too late, but to consume HTTP requests, one may use Apache Camel Servlet component
http://camel.apache.org/servlet.html
You need to setup the resourceClass option on the cxfrs endpoint. Here is an example
from("cxfrs://http://localhost:1234/sample?resourceClasses=my.pachage.SampleResource")
You can find some example in camel-cxfrs component page.
If you want to export a CXF service through servlet transport, you need to do some work as it said.
If you want to change the address dynamically, you can take look at the camel properties component.
If you are looking to start a camel route by a consuming cxf rest service which uses the servlet transport then you need to :
Clean up your pom.xml and remove any references to jetty.
Add the CXF servlet to your web.xml
<servlet>
<servlet-name>CXFServlet</servlet-name>
<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<!-- all our webservices are mapped under this URI pattern -->
<servlet-mapping>
<servlet-name>CXFServlet</servlet-name>
<url-pattern>/services/*</url-pattern>
</servlet-mapping>
Add the servlet-transport dependency:
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http</artifactId>
<version>${cxf-version}</version>
</dependency>
In your spring/camel configuration
<import resource="classpath:META-INF/cxf/cxf.xml"/>
<import resource="classpath:META-INF/cxf/cxf-servlet.xml" />
<cxf:rsServer id="rsServer" address="/restService"
serviceClass="com.something.test.SimpleServiceImpl"
loggingFeatureEnabled="true" loggingSizeLimit="20" />
Build a route from this consumer endpoint as:
from("cxfrs:bean:rsServer?bindingStyle=SimpleConsumer")
.to("log:TEST?showAll=true")
You can now view/(invoke with a method) the endpoint using : http://host:port/context/services/restService?_wadl

Mixing REST and JSP in Spring MVC, Cannot find JSP

I'm sure this is a noob question, and I've spent the better part of an hour trawling stackoverflow for an answer but nobody seems to have my case so here we go...
I have a new webapp that uses Spring MVC. Most of the app (99%) is pure REST, so it doesn't have a "view" as such but rather simply sends JSON back down the wire, or sends an alternate HTTP Status for errors etc.
The exception is the login page which needs to be an actual JSP, but somehow the configuration I am using to map my REST controllers is leaving me in a state where normal JSP mappings fail.
Here's what I've got:
In my dispatcher servlet config, the relevant portions are:
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
In my attempts to get it working, I have also added a mapping to the "HomeController" which currently just redirects to my login JSP:
<bean name="/" class="com.somepackage.HomeController"/>
Now, in the web.xml I have:
<servlet>
<servlet-name>spring-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
<listener>
<listener-class>
org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/spring-dispatcher-servlet.xml
</param-value>
</context-param>
This works fine for my RESTful controllers, which look like this:
#Controller
#RequestMapping(value = "/api/user")
public class BlahBlahController {...
My "HomeController", which just looks like this:
#Controller
#RequestMapping(value = "/")
public class HomeController extends AbstractController {
#Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("login");
}
}
IS triggered when I hit the "/" url, but I get this error in the logs:
WARNING: No mapping found for HTTP request with URI [/WEB-INF/pages/login.jsp] in DispatcherServlet with name 'spring-dispatcher'
Now I get what it's saying, it doesn't know how to resolve /WEB-INF/pages/login.jsp (this page does exist btw), but I'm stuck as to how I need to alter things to get this to work.
I'm a little confused on how it's supposed to work. Anyone got any clues?
Thanks.
OK.. I found the answer, it's the url-pattern in the dispatcher config.
Instead of:
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/*</url-pattern>
</servlet-mapping>
It should be
<servlet-mapping>
<servlet-name>spring-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
I had actually found this answer elsewhere and tried it but "thought" it wasn't working, then realized the reason I thought this was unrelated to the root cause.
No idea why this would work and the other wouldn't.. but one problem at a time...
Put RequestMapping at the method level, I tried at my code and it worked. You don't need to define HomeController bean if you are using #Controller and having a proper "context:component-scan"
#Override
#RequestMapping(value = "/")
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
return new ModelAndView("login");
}
you can also use below code if you just want to redirect a login view for all "/" access.
<mvc:view-controller path="/" view-name="login"/>
Checkout the mvc show case project from github for a helpful reference.

How to check JBoss deployers are working

I am trying to get resteasy working on JBoss AS6 Final (SEAM 2 app), but I cant seem the get the most basic example working, as I understand it, resteasy should be ready to go, I have tried the following example from here but the urls simply result in 404 errors with no response
package uk.co.rest.test;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.core.Application;
public class Library extends Application {
#GET
#Path("/books")
public String getBooks() {
System.out.println("Check");
return "done";
}
}
with the following added to my web.xml
<context-param>
<param-name>resteasy.servlet.mapping.prefix</param-name>
<param-value>/rest</param-value>
</context-param>
<servlet>
<servlet-name>resteasy-servlet</servlet-name>
<servlet-class>org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher</servlet-class>
<init-param>
<param-name>javax.ws.rs.Application</param-name>
<param-value>uk.co.rest.test.Library</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>resteasy-servlet</servlet-name>
<url-pattern>/rest/*</url-pattern>
</servlet-mapping>
I get the feeling that the resteasy.deployer that is bundled with JBoss is not doing its job, but im not sure how to go about debugging it
Any help would be great im pulling my hair out over this one!!
RESTEasy must be configured in order to be exposed as a service. You can do it either directly or via Seam's resource servlet.
To use RESTEasy directly, I find the easiest way is configuring it as a Servlet filter. There's little to do other than adding the filter to your web.xml as documented in http://docs.jboss.org/resteasy/docs/2.3.0.GA/userguide/html/Installation_Configuration.html#filter.
When using Seam this is however unnecessary, as Seam is capable of deploying RESTEasy services via its resource servlet quite simply (documented in http://docs.jboss.org/seam/2.2.0.GA/reference/en-US/html/webservices.html#d0e22093). You first declare RESTEasy's application component like this:
<resteasy:application resource-path-prefix="/rest" />
And create your providers that will be automatically deployed into the configured path, for example:
#Name("libraryService")
#Path("/library")
public class Library implements Serializable {
#In(create=true) private transient BookHome bookHome;
#GET #Path("/{book}")
#Produces("text/plain")
public String getBooks(#PathParam("book") String id) {
bookHome.setId(id);
return bookHome.getInstance().getTitle();
}
}
You can then access the RESTEasy service via:
http://localhost:8080/yourapp/seam/resource/rest/library/1
The advantage of going the Seam way is mostly ease of use. You do need to include an extra jar: jboss-seam-resteasy.jar.
You seem to have misunderstood the role of javax.ws.rs.Application. Your Library class does not have to extend javax.ws.rs.Application in order to expose the getBooks()-method.
Create a class that extends javax.ws.rs.Application. Override the getSingletons()-methods and return a set of instances that has methods you wish to expose:
public class MyApplication extends javax.ws.rs.Application {
#Override public Set<Object> getSingletons(){
return Collections.<Object>singleton(new Library());
}
}
In your web.xml, change the javax.ws.rs.Application init-param, so that it points to the MyApplication class.

Shorten path of REST service in JBoss Seam application

I'm pretty new to JBoss and Seam. My project has a REST service of the style
#Path("/media")
#Name("mediaService")
public class MediaService {
#GET()
#Path("/test")
public Response getTest() throws Exception {
String result = "this works";
ResponseBuilder builder = Response.ok(result);
return builder.build();
}
}
I can reach this at http://localhost:8080/application/resource/rest/media/test. However, I don't like this URL at all and would prefer something much shorter like http://localhost:8080/application/test.
Can you please point me in the right direction on how to configure the application correctly? (Developing using Eclipse)
web.xml will contain seam resource servlet mapping , this should be modified to /*, and if you have more configuration to the path it will be in components.xml ,if it is resteasy seam is configured to use, it will look like the following
<resteasy:application resource-path-prefix="/rest"/>