You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@cxf.apache.org by Christian Lipp <Ch...@xion.at> on 2012/06/29 07:54:35 UTC

URL structure

Hello!

I am implementing a REST service with CXF and I want to have the following URL structure:

-  dog/34
- dog/current/34
- cat/34
- index.html

So I registered CXFServlet with url-pattern /*, but provided a static-resources-list:

	<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
		<init-param>
			<param-name>static-resources-list</param-name>
			<param-value>/(\w)+.html</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>

	<servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

My service is a single class with
@Path("/")
public class AnimalService
{
	@GET
	@Path("/dog/current/{idnr}")
	public Response getCurrentBoneForDog(
	...

The service works fine, I can reach index.html by http://server/app/index.html, but I would also like to get it with http://server/app
I tried to provide
	<welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>

but this doesn't work either.

In the logs I find
o.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request path "/app/" is found, Relative Path: /, HTTP Method: GET, ContentType: */*

Is it able to set a "default handler", so when no operation matching request path is set then it delegates to standard mechanism?
Is it possible to solve my requirement with CXF mechanism? The only thing I can think of is to provide two servlet mappings with "/dog/*" and /cat/*" which would mean that I also had to split my service class into two parts.

Kind regards,
Christian

Re: URL structure

Posted by Sergey Beryozkin <sb...@gmail.com>.
Hi

On 29/06/12 06:54, Christian Lipp wrote:
> Hello!
>
> I am implementing a REST service with CXF and I want to have the following URL structure:
>
> -  dog/34
> - dog/current/34
> - cat/34
> - index.html
>
> So I registered CXFServlet with url-pattern /*, but provided a static-resources-list:
>
> 	<servlet>
> 		<servlet-name>CXFServlet</servlet-name>
> 		<servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
> 		<init-param>
> 			<param-name>static-resources-list</param-name>
> 			<param-value>/(\w)+.html</param-value>
> 		</init-param>
> 		<load-on-startup>1</load-on-startup>
> 	</servlet>
>
> 	<servlet-mapping>
> 		<servlet-name>CXFServlet</servlet-name>
> 		<url-pattern>/*</url-pattern>
> 	</servlet-mapping>
>
> My service is a single class with
> @Path("/")
> public class AnimalService
> {
> 	@GET
> 	@Path("/dog/current/{idnr}")
> 	public Response getCurrentBoneForDog(
> 	...
>
> The service works fine, I can reach index.html by http://server/app/index.html, but I would also like to get it with http://server/app
> I tried to provide
> 	<welcome-file-list>
> 		<welcome-file>index.html</welcome-file>
> 	</welcome-file-list>
>
> but this doesn't work either.
>
> In the logs I find
> o.apache.cxf.jaxrs.utils.JAXRSUtils - No operation matching request path "/app/" is found, Relative Path: /, HTTP Method: GET, ContentType: */*
>
> Is it able to set a "default handler", so when no operation matching request path is set then it delegates to standard mechanism?
> Is it possible to solve my requirement with CXF mechanism? The only thing I can think of is to provide two servlet mappings with "/dog/*" and /cat/*" which would mean that I also had to split my service class into two parts.
>
It appears the only workaround at the moment is to register a custom 
filter which will read and return index.html in case of 
http://server/app requests

However I've worked on enhancing CXFServlet and cases like this one will 
be possible to manage quite easily.

Here is option 1 (using redirects):

<servlet>
		<servlet-name>CXFServlet</servlet-name>
		<display-name>CXF Servlet</display-name>
		<servlet-class>
			org.apache.cxf.transport.servlet.CXFServlet
		</servlet-class>
		<init-param>
     		<param-name>redirects-list</param-name>
	    	<param-value>
	    	  /
                   /index.html
	    	</param-value>
	    </init-param>
	    <init-param>
     		<param-name>redirect-attributes</param-name>
	    	<param-value>
	    	  javax.servlet.include.request_uri
	    	</param-value>
	    </init-param>
	    <init-param>
     		<param-name>redirect-servlet-name</param-name>
	    	<param-value>default</param-value>
	    </init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
         <servlet-mapping>
		<servlet-name>CXFServlet</servlet-name>
		<url-pattern>/*</url-pattern>
	</servlet-mapping>

         <welcome-file-list>
		<welcome-file>index.html</welcome-file>
	</welcome-file-list>

Note that the redirects-list parameter has two space separated values, 
"/" and "index.html" - as usual these are actually regex expressions, 
using specific "index.html" for the simplicity only.

so say '/service/webapp' and '/service/webapp/index.html' will be served 
by the redirect.

"redirect-attributes" includes an empty 
javax.servlet.include.request_uri - I had to add it to make Jetty 
actually read and return index.html as opposed to looping indefinitely.
It may or may not be required for Tomcat.

Other attributes may be referenced as needed

Option 2.

Instead of redirect parameters, use the following two:

'/service/webapp':
<init-param>
     		<param-name>static-welcome-file</param-name>
	    	<param-value>/index.html</param-value>
	    </init-param>

and your original static-resource-list (to cover 
'/service/webapp/index.html')

I think this makes CXFServlet much more capable of acting as the central 
facade into the web application which may host soap, rs, amd other 
resources.

I'll document it all

Thanks, Sergey

> Kind regards,
> Christian


-- 
Sergey Beryozkin

Talend Community Coders
http://coders.talend.com/

Blog: http://sberyozkin.blogspot.com