users@jersey.java.net

Re: [Jersey] Hello World! and Welcome to jersey-multipart

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Wed, 05 Nov 2008 11:10:39 +0100

On Nov 4, 2008, at 9:17 PM, Paul Sandoz wrote:

> Hi Craig,
>
> Ah! drat forgot to do this in the Client constructor:
>
> injectableFactory.configure(providerServices);
>
> which processes use-registered providers. I will fix that tomorrow.
>

Fixed in the trunk.

Since your InjectableProvider is providing Singleton instances the
getInstance method should return the same instance of MultiPartConfig
every time it is called.


> + /**
> + * <p>Return the size (in bytes) of the entity of an incoming
> + * {_at_link BodyPart} before it will be buffered to disk.</p>
> + */
> + public int getBufferThreshold() {
> + return 4096; // FIXME - configure this from a properties
> file or something
> + }
> +

One approach is to inject @Context FeaturesAndProperties on the
InjectableProvider and that instance can be passed to the
MultiPartConfig constructor from which values can be obtained. Note
that for Servlet the init-params are automatically copied as properies
and features (if a string value represents a boolean value).

Paul.

> Paul.
>
> On Nov 4, 2008, at 8:53 PM, Craig McClanahan wrote:
>
>> Paul Sandoz wrote:
>>>
>>>> Paul, the InjectableProvider stuff[1] in Jersey would support
>>>> this, right?
>>>
>>> Possibly... :-)
>>>
>>>
>> Until now I hadn't actually tried building my own injectable
>> provider. It turns out to be pretty straightforward, but with only
>> one bit of grief ... it doesn't work for me on the client side :-
>> (. The complete diff (from the current trunk) that I am playing
>> with is attached, but here's the highlights:
>>
>> * A new JavaBean (MultiPartConfig) that represents the
>> configuration data. Right now it's just a dummy with a
>> hard coded value, but if this experiment works out we can
>> easily make it look up the parameters in a properties file
>> or something.
>>
>> * A new provider annotation (MultiPartConfigParam) to
>> declare the injectable type.
>>
>> * A new provider (MultiPartConfigProvider) that serves as
>> a factory for MultiPartConfig instances. I declared the
>> scope to be singleton because there only needs to be
>> one of these things around.
>>
>> * Modifications to MultiPartReader to accept injection of the
>> configuration parameter bean in the constructor:
>>
>> public MultiPartReader(@MultiPartConfigParam MultiPartConfig
>> config) {
>> this.config = config;
>> }
>>
>> and modifications to call the getThresholdValue() method on
>> the config bean when constructing a new BodyPartEntity
>> (instead of the hard coded 4096 value).
>>
>> * Modified unit test (MultiPartReaderWriterTest) to declare this
>> additional provider in the configuration of the Jersey client.
>> (Side question -- why do I have to configure these at all?
>> I'm trying to use the package resources scanner.)
>>
>> Things seem to work fine on the server side ... the new provider is
>> recognized, and a proper injection takes place. But on the client
>> side, it injects null (and therefore triggers NPEs in the tests
>> that try to parse a multipart response in the client).
>>
>> Any ideas? Full diff is attached.
>>
>> Craig
>>
>> PS: Separately, an important implication of making this change is
>> that the jersey-multipart support would indeed by tied specifically
>> to Jersey, and not portable to other JAX-RS environments.
>>
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =
>> =====================================================================
>>
>> Index: src/test/java/com/sun/jersey/impl/multipart/
>> MultiPartReaderWriterTest.java
>> ===================================================================
>> --- src/test/java/com/sun/jersey/impl/multipart/
>> MultiPartReaderWriterTest.java (revision 1663)
>> +++ src/test/java/com/sun/jersey/impl/multipart/
>> MultiPartReaderWriterTest.java (working copy)
>> @@ -88,6 +88,7 @@
>> config.getClasses().add(MultiPartReader.class);
>> config.getClasses().add(MultiPartWriter.class);
>> config.getClasses().add(MultiPartBeanProvider.class);
>> + config.getClasses().add(MultiPartConfigProvider.class);
>> client = Client.create(config);
>> }
>>
>> Index: src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartConfigProvider.java
>> ===================================================================
>> --- src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartConfigProvider.java (revision 0)
>> +++ src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartConfigProvider.java (revision 0)
>> @@ -0,0 +1,76 @@
>> +/*
>> + *
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + *
>> + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + *
>> + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the
>> "License"). You
>> + * may not use this file except in compliance with the License.
>> You can obtain
>> + * a copy of the License at https://jersey.dev.java.net/CDDL
>> +GPL.html
>> + * or jersey/legal/LICENSE.txt. See the License for the specific
>> + * language governing permissions and limitations under the License.
>> + *
>> + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at jersey/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the
>> "Classpath" exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by
>> your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + *
>> + * Contributor(s):
>> + *
>> + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this
>> file under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL
>> Version 2 code
>> + * and therefore, elected the GPL Version 2 license, then the
>> option applies
>> + * only if the new code is made subject to such option by the
>> copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.jersey.impl.multipart;
>> +
>> +import com.sun.jersey.api.multipart.MultiPartConfigParam;
>> +import com.sun.jersey.api.multipart.MultiPartConfig;
>> +import com.sun.jersey.core.spi.component.ComponentContext;
>> +import com.sun.jersey.core.spi.component.ComponentScope;
>> +import com.sun.jersey.spi.inject.Injectable;
>> +import com.sun.jersey.spi.inject.InjectableProvider;
>> +import java.lang.reflect.Type;
>> +import javax.ws.rs.ext.Provider;
>> +
>> +/**
>> + * <p>Jersey-specific injectable provider that supplies a
>> configured instance
>> + * of {_at_link MultiPartConfig} for this application.</p>
>> + */
>> +_at_Provider
>> +public class MultiPartConfigProvider implements
>> InjectableProvider<MultiPartConfigParam, Type> {
>> +
>> + public ComponentScope getScope() {
>> + return ComponentScope.Singleton;
>> + }
>> +
>> + public Injectable getInjectable(ComponentContext ic,
>> MultiPartConfigParam a, Type t) {
>> + if (!(t instanceof Class)) {
>> + System.out.println("Type " + t.toString() + " is not a
>> Class"); // FIXME - remove debug statement
>> + return null;
>> + }
>> + if (((Class) t).isPrimitive()) {
>> + System.out.println("Type " + t.toString() + " is a
>> primitive"); // FIXME - remove debug statement
>> + return null;
>> + }
>> + return new Injectable<Object>() {
>> + public Object getValue() {
>> + return new MultiPartConfig();
>> + }
>> + };
>> + }
>> +
>> +}
>>
>> Property changes on: src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartConfigProvider.java
>> ___________________________________________________________________
>> Added: svn:keywords
>> + Date Author Id Revision HeadURL
>> Added: svn:eol-style
>> + native
>>
>> Index: src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartReader.java
>> ===================================================================
>> --- src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartReader.java (revision 1663)
>> +++ src/main/java/com/sun/jersey/impl/multipart/
>> MultiPartReader.java (working copy)
>> @@ -40,6 +40,8 @@
>> import com.sun.jersey.api.multipart.BodyPart;
>> import com.sun.jersey.api.multipart.BodyPartEntity;
>> import com.sun.jersey.api.multipart.MultiPart;
>> +import com.sun.jersey.api.multipart.MultiPartConfigParam;
>> +import com.sun.jersey.api.multipart.MultiPartConfig;
>> import java.io.IOException;
>> import java.io.InputStream;
>> import java.io.OutputStream;
>> @@ -69,6 +71,22 @@
>> public class MultiPartReader implements
>> MessageBodyReader<MultiPart> {
>>
>> /**
>> + * <p>Accept constructor injection of the configuration
>> parameters for this
>> + * application.</p>
>> + */
>> + public MultiPartReader(@MultiPartConfigParam MultiPartConfig
>> config) {
>> + System.out.println("MultiPartConfigBean = " + config);
>> + this.config = config;
>> + }
>> +
>> +
>> + /**
>> + * <p>Injected configuration parameters for this application.</
>> p>
>> + */
>> + private MultiPartConfig config = null;
>> +
>> +
>> + /**
>> * <P>Injectable helper to look up appropriate {_at_link Provider}s
>> * for our body parts.</p>
>> */
>> @@ -138,8 +156,7 @@
>> MediaType bpMediaType =
>> MediaType.valueOf(bp.getContentType());
>> bodyPart.setMediaType(bpMediaType);
>> // Copy data into a BodyPartEntity structure
>> - // FIXME - how to make in-memory threshold value
>> configurable
>> - bodyPart.setEntity(new
>> BodyPartEntity(bp.getInputStream(), 4096));
>> + bodyPart.setEntity(new
>> BodyPartEntity(bp.getInputStream(), config.getBufferThreshold()));
>> // Add this BodyPart to our MultiPart
>> multiPart.getBodyParts().add(bodyPart);
>> }
>> Index: src/main/java/com/sun/jersey/api/multipart/
>> MultiPartConfig.java
>> ===================================================================
>> --- src/main/java/com/sun/jersey/api/multipart/MultiPartConfig.java
>> (revision 0)
>> +++ src/main/java/com/sun/jersey/api/multipart/MultiPartConfig.java
>> (revision 0)
>> @@ -0,0 +1,56 @@
>> +/*
>> + *
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + *
>> + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + *
>> + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the
>> "License"). You
>> + * may not use this file except in compliance with the License.
>> You can obtain
>> + * a copy of the License at https://jersey.dev.java.net/CDDL
>> +GPL.html
>> + * or jersey/legal/LICENSE.txt. See the License for the specific
>> + * language governing permissions and limitations under the License.
>> + *
>> + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at jersey/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the
>> "Classpath" exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by
>> your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + *
>> + * Contributor(s):
>> + *
>> + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this
>> file under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL
>> Version 2 code
>> + * and therefore, elected the GPL Version 2 license, then the
>> option applies
>> + * only if the new code is made subject to such option by the
>> copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.jersey.api.multipart;
>> +
>> +/**
>> + * <p>Injectable JavaBean containing the configuration parameters
>> for
>> + * <code>jersey-multipart</code> as used in this particular
>> application.</p>
>> + */
>> +public class MultiPartConfig {
>> +
>> +
>> + /**
>> + * <p>Return the size (in bytes) of the entity of an incoming
>> + * {_at_link BodyPart} before it will be buffered to disk.</p>
>> + */
>> + public int getBufferThreshold() {
>> + return 4096; // FIXME - configure this from a properties
>> file or something
>> + }
>> +
>> +
>> +}
>>
>> Property changes on: src/main/java/com/sun/jersey/api/multipart/
>> MultiPartConfig.java
>> ___________________________________________________________________
>> Added: svn:keywords
>> + Date Author Id Revision HeadURL
>> Added: svn:eol-style
>> + native
>>
>> Index: src/main/java/com/sun/jersey/api/multipart/
>> MultiPartConfigParam.java
>> ===================================================================
>> --- src/main/java/com/sun/jersey/api/multipart/
>> MultiPartConfigParam.java (revision 0)
>> +++ src/main/java/com/sun/jersey/api/multipart/
>> MultiPartConfigParam.java (revision 0)
>> @@ -0,0 +1,53 @@
>> +/*
>> + *
>> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
>> + *
>> + * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
>> + *
>> + * The contents of this file are subject to the terms of either
>> the GNU
>> + * General Public License Version 2 only ("GPL") or the Common
>> Development
>> + * and Distribution License("CDDL") (collectively, the
>> "License"). You
>> + * may not use this file except in compliance with the License.
>> You can obtain
>> + * a copy of the License at https://jersey.dev.java.net/CDDL
>> +GPL.html
>> + * or jersey/legal/LICENSE.txt. See the License for the specific
>> + * language governing permissions and limitations under the License.
>> + *
>> + * When distributing the software, include this License Header
>> Notice in each
>> + * file and include the License file at jersey/legal/LICENSE.txt.
>> + * Sun designates this particular file as subject to the
>> "Classpath" exception
>> + * as provided by Sun in the GPL Version 2 section of the License
>> file that
>> + * accompanied this code. If applicable, add the following below
>> the License
>> + * Header, with the fields enclosed by brackets [] replaced by
>> your own
>> + * identifying information: "Portions Copyrighted [year]
>> + * [name of copyright owner]"
>> + *
>> + * Contributor(s):
>> + *
>> + * If you wish your version of this file to be governed by only
>> the CDDL or
>> + * only the GPL Version 2, indicate your decision by adding
>> "[Contributor]
>> + * elects to include this software in this distribution under the
>> [CDDL or GPL
>> + * Version 2] license." If you don't indicate a single choice of
>> license, a
>> + * recipient has the option to distribute your version of this
>> file under
>> + * either the CDDL, the GPL Version 2 or to extend the choice of
>> license to
>> + * its licensees as provided above. However, if you add GPL
>> Version 2 code
>> + * and therefore, elected the GPL Version 2 license, then the
>> option applies
>> + * only if the new code is made subject to such option by the
>> copyright
>> + * holder.
>> + */
>> +
>> +package com.sun.jersey.api.multipart;
>> +
>> +import java.lang.annotation.Documented;
>> +import java.lang.annotation.ElementType;
>> +import java.lang.annotation.Retention;
>> +import java.lang.annotation.RetentionPolicy;
>> +import java.lang.annotation.Target;
>> +
>> +/**
>> + * <p>Annotation describing an injectable {_at_link
>> MultiPartConfigBean}.</p>
>> + */
>> +
>> @Target
>> (value={ElementType.PARAMETER,ElementType.METHOD,ElementType.FIELD})
>> +_at_Retention(value=RetentionPolicy.RUNTIME)
>> +_at_Documented
>> +public @interface MultiPartConfigParam {
>> +}
>>
>> Property changes on: src/main/java/com/sun/jersey/api/multipart/
>> MultiPartConfigParam.java
>> ___________________________________________________________________
>> Added: svn:keywords
>> + Date Author Id Revision HeadURL
>> Added: svn:eol-style
>> + native
>>
>> Index: pom.xml
>> ===================================================================
>> --- pom.xml (revision 1663)
>> +++ pom.xml (working copy)
>> @@ -67,7 +67,7 @@
>> <groupId>com.sun.jersey</groupId>
>> <artifactId>jersey-core</artifactId>
>> <version>${project.version}</version>
>> - <scope>test</scope>
>> +<!-- <scope>test</scope> -->
>> </dependency>
>> <dependency>
>> <groupId>com.sun.jersey</groupId>
>>
>> ---------------------------------------------------------------------
>> 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
>