users@jersey.java.net

Re: [Jersey] Resource and XML Schema versioning...

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 26 Feb 2009 21:50:22 +0100

Hi Mark,

You have not configured your web.xml correctly to use your own
extension of PackagesResourceConfig.

I do not know what the package name of your class
CnodbRestResourceConfig is, but for the sake of example and clarity i
am going to assume it is "mil.cnodb.rs". The servlet declaration
requires just the following init-param:

     <init-param>
         <param-
name>com.sun.jersey.config.property.resourceConfigClass</param-name>
         <param-value>mil.cnodb.rs.CnodbRestResourceConfig</param-value>
     </init-param>

Plus in your CnodbRestResourceConfig you do not require all the WADL
configuration stuff as copied from the camel web example, i dunno if
you are using that or not. You just require the following:

     public class CnodbRestResourceConfig extends
PackagesResourceConfig {

        public CnodbRestResourceConfig() {
                super("mil.cnodb.rs.resources.v1");
        }
        
        public Map<String, MediaType> getMediaTypeMappings() {
             Map<String, MediaType> m = new HashMap<String,
MediaType>();
             m.put("v1-xml", CnodbMediaType.APPLICATION_V1XML_TYPE);
             m.put("v1-json", CnodbMediaType.APPLICATION_V1JSON_TYPE);
             return m;
         }
    }

Paul.

On Feb 26, 2009, at 9:27 PM, Rabick, Mark A (MS) wrote:

> Thanks Marc. I just changed the media type to application/v1+xml
> and if
> I enter the URL:
>
> http://host/nodes1
>
> IE asks me to open a file 'nodes1' and pick an 'open-with' program for
> file of type 'application/v1+xml'... So far so good, but if I change
> the
> URI and add the suffix mapped in the PackagesResourceConfig ("v1-xml",
> "v1-json"),
>
> http://host/nodes1/nodes1.v1-xml
>
> I get back an empty page??? Same with .v1-json
>
> I'm trying to use the suffix to specify both a schema version and
> media
> type to return. Is that trying too much?
>
> -m
>
>
>> -----Original Message-----
>> From: Marc.Hadley_at_Sun.COM [mailto:Marc.Hadley_at_Sun.COM]
>> Sent: Thursday, February 26, 2009 2:19 PM
>> To: users_at_jersey.dev.java.net
>> Subject: Re: [Jersey] Resource and XML Schema versioning...
>>
>> There are a couple of things you could try:
>>
>> (i) Simplest. Change your media type to application/v1+xml.
>> JAX-RS requires the JAXB message body writer to support
>> application/xml, text/ xml and application/*+xml but its
>> allowed to ignore other media types.
>>
>> (ii) More complex. Write your own message body writer that
>> defers to the built-in JAXB one. You'll need to implement
>> MessageBodyWriter<NodeV1>, have javax.ws.rs.ext.Providers
>> injected and use the getMessageBodyWriter method to get
>> yourself a reference to the built-in JAXB writer that you can
>> then call.
>>
>> Marc.
>>
>> On Feb 26, 2009, at 2:58 PM, Rabick, Mark A (MS) wrote:
>>
>>> I'm getting an exception trying to configure a custom media type:
>>>
>>> SEVERE: A message body writer for Java type, class
>>> mil.cnodb.rs.model.v1.NodeV1, and MIME media type,
>> application/v1-xml,
>>> was not found Feb 26, 2009 1:50:35 PM
>>> com.sun.jersey.server.impl.application.WebApplicationImpl
>> onException
>>> SEVERE: Internal server error
>>> javax.ws.rs.WebApplicationException
>>> at
>>> com
>>>
>> .sun.jersey.spi.container.ContainerResponse.write(ContainerResponse.j
>>> ava:241)
>>> at
>>> com
>>>
>> .sun.jersey.server.impl.application.WebApplicationImpl._handleRequest
>>> (WebApplicationImpl.java:578)
>>> at
>>> com
>>>
>> .sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(
>>> WebApplicationImpl.java:502)
>>> at
>>> com
>>>
>> .sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(
>>> WebApplicationImpl.java:493)
>>> at
>>> com
>>>
>> .sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.j
>>> ava:308)
>>> at
>>> com
>>>
>> .sun.jersey.spi.container.servlet.ServletContainer.service(ServletCon
>>> tainer.java:314)
>>>
>>> How can I map application/v1-xml to application/xml?
>> Similarly with
>>> application/v1-json. Is there a way to avoid writing a custom
>>> messageWriter for the media type?
>>>
>>> I've configured a context resolver:
>>>
>>> /**
>>> *
>>> */
>>> @Provider
>>> @Produces({"application/v1-xml","application/v1-json"})
>>> public final class Version1ContextResolver implements
>>> ContextResolver<JAXBContext> {
>>>
>>> private final JAXBContext context;
>>>
>>> private final Set<Class> types;
>>>
>>> /*
>>> * The list of JAXB class types (top-level) need to be
>> listed here.
>>> */
>>> private final Class[] cTypes = {NodeV1.class};
>>>
>>> public Version1ContextResolver() throws Exception {
>>>
>>> this.types = new HashSet(Arrays.asList(cTypes));
>>> this.context = new JSONJAXBContext(
>>> JSONConfiguration.natural().build(), cTypes);
>>> }
>>>
>>> public JAXBContext getContext(Class<?> objectType) {
>>> return (types.contains(objectType)) ? context : null;
>>> }
>>> }
>>>
>>> Created a Resource that
>>> Produces("application/v1-xml","application/v1-json")
>>>
>>> @GET
>>> @Produces({"application/v1-xml","application/v1-json"})
>>> public NodeV1 getNode(
>>> @QueryParam("id") String nodeId,
>>> @QueryParam("name") String nodeName,
>>> @QueryParam("level") String nodeLevel,
>>> @QueryParam("allegiance") String allegiance,
>>> @QueryParam("cc") String cc,
>>> @QueryParam("typeGeneral") String
>>> nodeTypeGeneral,
>>> @QueryParam("typeSpecific") String
>>> nodeTypeSpecific) {
>>>
>>>
>>> NodeV1 nodeV1 = new NodeV1();
>>> nodeV1.setNodeName("Nodes Name is");
>>>
>>> return nodeV1;
>>> }
>>>
>>> Extended PackagesResourceConfig:
>>>
>>> public class CnodbRestResourceConfig extends
>> PackagesResourceConfig {
>>>
>>> public CnodbRestResourceConfig() {
>>> super(createProperties());
>>> }
>>>
>>> public Map<String, MediaType> getMediaTypeMappings() {
>>> Map<String, MediaType> m = new HashMap<String, MediaType>();
>>> m.put("v1-xml", CnodbMediaType.APPLICATION_V1XML_TYPE);
>>> m.put("v1-json", CnodbMediaType.APPLICATION_V1JSON_TYPE);
>>> return m;
>>> }
>>>
>>> protected static Map<String,Object> createProperties() {
>>> Map<String, Object> properties = new HashMap<String,
>>> Object>();
>>>
>>> properties.put(PackagesResourceConfig.PROPERTY_PACKAGES,
>>> "mil.cnodb.rs.resources.v1");
>>>
>>> WadlGeneratorConfig config = WadlGeneratorConfig
>>> .generator(WadlGeneratorApplicationDoc.class)
>>> .prop("applicationDocsFile",
>>> "classpath:/application-doc.xml")
>>> .generator(WadlGeneratorGrammarsSupport.class)
>>> .prop("grammarsFile",
>>> "classpath:/application-grammars.xml")
>>> .generator(WadlGeneratorResourceDocSupport.class)
>>> .prop("resourceDocFile",
>> "classpath:/resourcedoc.xml")
>>> .build();
>>>
>>> properties.put(ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG,
>>> config);
>>> return properties;
>>> }
>>>
>>> }
>>>
>>> And edited web.xml
>>>
>>> <servlet>
>>> <servlet-name>CNODB Web Application</servlet-name>
>>>
>>> <servlet-
>>> class>com.sun.jersey.spi.container.servlet.ServletContainer</se
>>> rvlet-class>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.property.resourceConfigClass</
>>> param-na
>>> me>
>>>
>>> <param-value>com.sun.jersey.api.core.PackagesResourceConfig</param-
>>> value
>>>>
>>> </init-param>
>>> <init-param>
>>>
>>> <param-name>com.sun.jersey.config.property.packages</param-name>
>>> <param-value>mil.cnodb.rs</param-value>
>>> </init-param>
>>> <load-on-startup>1</load-on-startup>
>>> </servlet>
>>>
>>>> -----Original Message-----
>>>> From: Paul.Sandoz_at_Sun.COM [mailto:Paul.Sandoz_at_Sun.COM]
>>>> Sent: Thursday, February 26, 2009 11:12 AM
>>>> To: users_at_jersey.dev.java.net
>>>> Subject: Re: [Jersey] Resource and XML Schema versioning...
>>>>
>>>>
>>>> On Feb 26, 2009, at 5:51 PM, Rabick, Mark A (MS) wrote:
>>>>
>>>>>> On Feb 25, 2009, at 6:08 PM, Rabick, Mark A (MS) wrote:
>>>
>>>>>> A suffix at the end of the URI path, but not part of the
>>>> application
>>>>>> and @Path.
>>>>>
>>>>> Not part of the application I assume would be not in the
>> 'context-
>>>>> root'
>>>>> of the web app. Sorry to belabor this but how can a suffix
>>>> be at the
>>>>> end of the URI path, but NOT Included in an @Path?
>>>>> Can you give an example?
>>>>
>>>> Here is a specific example from the camel web component:
>>>>
>>>> https://svn.apache.org/repos/asf/camel/trunk/components/camel-
>>>>
>> web/src/main/java/org/apache/camel/web/util/CamelResourceConfig.java
>>>>
>>>> public class CamelResourceConfig extends PackagesResourceConfig {
>>>> public CamelResourceConfig() {
>>>> super(createProperties());
>>>> }
>>>>
>>>> protected static Map<String, Object> createProperties() {
>>>> Map<String, Object> properties = new HashMap<String,
>>>> Object>();
>>>>
>>>> properties.put(PackagesResourceConfig.PROPERTY_PACKAGES,
>>>> "org.apache.camel.web");
>>>>
>>>> WadlGeneratorConfig config = WadlGeneratorConfig
>>>> .generator(WadlGeneratorApplicationDoc.class)
>>>> .prop("applicationDocsFile",
>> "classpath:/application-
>>>> doc.xml")
>>>> .generator(WadlGeneratorGrammarsSupport.class)
>>>> .prop("grammarsFile", "classpath:/application-
>>>> grammars.xml")
>>>> .generator(WadlGeneratorResourceDocSupport.class)
>>>> .prop("resourceDocFile",
>>>> "classpath:/resourcedoc.xml")
>>>> .build();
>>>>
>>>>
>> properties.put(ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG,
>>>> config);
>>>> return properties;
>>>> }
>>>>
>>>> public Map<String, MediaType> getMediaTypeMappings() {
>>>> Map<String, MediaType> m = new HashMap<String,
>> MediaType>();
>>>> m.put("html", MediaType.TEXT_HTML_TYPE);
>>>> m.put("xml", MediaType.APPLICATION_XML_TYPE);
>>>> m.put("json", MediaType.APPLICATION_JSON_TYPE);
>>>> m.put("dot", MediaType.valueOf(Constants.DOT_MIMETYPE));
>>>> return m;
>>>> }
>>>> }
>>>>
>>>> See the method "getMediaTypeMappings". Notice that it declares a
>>>> mapping of suffix to media type.
>>>>
>>>> Thus whenever there is say a request URI:
>>>>
>>>> http://localhost:8080/path/foo.html
>>>>
>>>> Jersey will modify the request URI to be:
>>>>
>>>> http://localhost:8080/path/foo
>>>>
>>>> and modify the Accept header to be:
>>>>
>>>> Accept: text/html
>>>>
>>>> The above modifications will occur *before* Jersey processes the
>>>> request and dispatches to a methods on a resource class.
>>>> It is essentially a request filter.
>>>>
>>>> Hope that helps,
>>>> Paul.
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>
>>>>>
>>>>>
>>>>>
>>>>>>> Ie. http://host:8080/fooapplication/foo.foo-v1/
>>>>>>>
>>>>>>> public class FooV1Resource {
>>>>>>>
>>>>>>> @GET @Path("/foo.foo-v1/{id}")
>>>>>>> @Produces("application/foo-v1")
>>>>>>> public FooV1(String @PathParam("id") String fooId) {
>>>>>>>
>>>>>>> FooV2 foo2 = FooDatabase.getFooById(fooId);
>>>>>>> FooV1 foo1 = convertFoo2ToFoo1(foo2)
>>>>>>> return foo1;
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> Ie. http://host:8080/fooapplication/foo.foo-v2/
>>>>>>>
>>>>>>> public class FooV2Resource {
>>>>>>>
>>>>>>> @GET @Path("/foo.foo-v2/{id}")
>>>>>>> @Produces("application/foo-v2")
>>>>>>> public FooV2(String @PathParam("id") String fooId) {
>>>>>>> FooV2 foo2 = FooDatabase.getFooById(fooId);
>>>>>>> return foo2;
>>>>>>> }
>>>>>>> }
>>>>>>>
>>>>>>> With the appropriate ContextResolvers based on the media
>>>> types, of
>>>>>>> course...
>>>>>>>
>>>>>>> What 'existing Jersey functionality' are you referring to that
>>>>>>> suffixes would help with?
>>>>>>>
>>>>>>
>>>>>> See:
>>>>>>
>>>>>>
>>>>>
>>>> https://jersey.dev.java.net/source/browse/*checkout*/jersey/tags/
>>>> jerse
>>>>> y- 1.0.2/api/jersey/com/sun/jersey/api/core/
>>>>> ResourceConfig.html#getMediaTyp
>>>>> eMappings()
>>>>>>
>>>>>> Paul.
>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>
>> ---------------------------------------------------------------------
>>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>>
>>>>
>>>>
>>>>
>> ---------------------------------------------------------------------
>>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>>
>>>>
>>>>
>>>
>>>
>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>