0

I am a newbie to IBM Mobile-first java adapter, I am trying to send an image file( Multipart request) to my java adapter (uses JAX-Rs) using Postman, and receive that image file in Rest API, and send it to third party server.

But whenever I hit the API from the Postman I get 415 Unsupported media type error, I even tried configuring JAX-rs2.0 in MFPJAXRSApplication class, but that also doesn't work. Could anyone please help me with this.

My main application class

package com.sample.adapter;

import java.util.logging.Logger;
import com.ibm.mfp.adapter.api.MFPJAXRSApplication;

public class JavaAdapterApplication extends MFPJAXRSApplication{

    static Logger logger = Logger.getLogger(JavaAdapterApplication.class.getName());

    @Override
    protected void init() throws Exception {
        logger.info("Adapter initialized!");
    }

    @Override
    protected String getPackageToScan() {
        //The package of this class will be scanned (recursively) to find JAX-RS 2.0 resources.
        return getClass().getPackage().getName();
    }

    @Override
    public Set<Class<?>> getClasses() {
        
        
        log.info("********* added this part by following few suggestin of stack overflow ************");
        Set<Class<?>> resources = new java.util.HashSet<Class<?>>();
        resources.add(MultiPartFeature.class);
        addRestResourceClasses(resources);
        return resources;
    }

    /**
     * Do not modify addRestResourceClasses() method. It is automatically populated
     * with all resources defined in the project. If required, comment out calling
     * this method in getClasses().
     */
    private void addRestResourceClasses(Set<Class<?>> resources) {
        log.info("********* added this part by following few suggestin of stack overflow ************");
        resources.add(com.adapter.application.services.TestService.class);
    }
}

My resource class is When I remove FormDataContentDisposition from the code and keep only Inputstrem I can reach the API but as soon as I add FormDataContentDisposition it starts with 415 unsupported media type error.

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;

import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

import org.apache.http.client.methods.HttpRequestBase;

import com.adapter.util.CRGEHttpRequestGenerator;
import com.adapter.util.CRGELogUtils;
import com.adapter.util.CRGERequestHandler;
import com.adapter.util.CRGEResponseHandler;
import com.ibm.mfp.adapter.api.ConfigurationAPI;
import com.ibm.mfp.adapter.api.OAuthSecurity;
import com.ibm.mfp.server.security.external.resource.AdapterSecurityContext;

import org.glassfish.jersey.media.multipart.FormDataContentDisposition;
import org.glassfish.jersey.media.multipart.FormDataMultiPart;
import org.glassfish.jersey.media.multipart.FormDataParam;

@Path("/hi")   
public class TestService extends RequestHandler  {
    @Context
    AdapterSecurityContext securityContext;
    
    @Context
    static ConfigurationAPI configurationAPI;

    static org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(TestService.class.getName());
 

   @POST
@Path("/uploadFeedback")
@Consumes(MediaType.MULTIPART_FORM_DATA)
@Produces("*/*")
@OAuthSecurity(enabled=false)
public Response  attachupload( @FormDataParam("file") InputStream uploadedInputStream,
        @FormDataParam("file") FormDataContentDisposition fileDetail){
    log.info("fileName"+fileDetail);
    return Response.ok().build();
}

Pom.xml

    <properties>
        <!-- Use UTF-8 as the encoding of the adapter -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

        
    </properties>

     <dependencies>
        <!-- https://mvnrepository.com/artifact/com.ibm.mfp/adapter-maven-api -->
        <dependency>
            <groupId>com.ibm.mfp</groupId>
            <artifactId>adapter-maven-api</artifactId>
            <version>8.0.2018071507</version>
            <scope>provided</scope>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>3.0.4.RELEASE</version>
            <type>jar</type>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/log4j/log4j -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-io -->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-io</artifactId>
            <version>1.3.2</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/com.fasterxml.jackson.core/jackson-annotations -->
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.9.7</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/com.ibm.mfp/mfp-java-token-validator -->
        <dependency>
            <groupId>com.ibm.mfp</groupId>
            <artifactId>mfp-java-token-validator</artifactId>
            <version>8.0.2017020112</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/com.ibm.mfp/mfp-security-checks-base -->
        <dependency>
            <groupId>com.ibm.mfp</groupId>
            <artifactId>mfp-security-checks-base</artifactId>
            <version>8.0.2018030404</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson -->
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.5</version>
        </dependency>

    
    <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents/httpmime -->
<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpmime</artifactId>
    <version>4.3.1</version>
</dependency>
    
   
   
     <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>2.7</version>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-multipart</artifactId>
            <version>2.7</version>
        </dependency>     

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>com.ibm.mfp</groupId>
                <artifactId>adapter-maven-plugin</artifactId>
                <extensions>true</extensions>
            </plugin>
        </plugins>
    </build>
</project>

I want to know why the server is not recognizing Multipart request, do we have to configure the adapter to accept the multipart request, if yes then how do we configure it? Could anyone please save my life by helping me with this.

Also my application does not have WEB.xml or any class that begins with @ApplicationPath

Swathi
  • 156
  • 1
  • 2
  • 11
  • Does it throw a server side error/exception, before this response is returned? – Vivin K Sep 03 '20 at 04:32
  • Does Mobile-First use Jersey implementation for its JAX-RS support? – Paul Samsotha Sep 03 '20 at 07:49
  • What shows as the request body when you leave out the FormDataContentDisposition? Is it just the contents of the "file" part or is it the complete multipart entity? I'm assuming the latter. In which case, the `@FormDataParam` annotations are simply ignored. When you leave off the second parameter, the first parameter is simply treated as the entire body. Jersey's Multipart support will not work unless it's with Jersey. – Paul Samsotha Sep 03 '20 at 07:54
  • I have configured jersey in adapter Application MFPJAXRSApplication class .. And imported jersey dependecy in mave file but the same issue continues – Swathi Sep 03 '20 at 10:06
  • @PaulSamsotha is there any way we can configure the application to consider the jersey configuration? – Swathi Sep 03 '20 at 10:17
  • I don't know anything about the Mobile-First platform. So I'm not sure. I would imagine that you can't just _choose_ to use Jersey. It's just whatever implementation they are using under the hood. – Paul Samsotha Sep 03 '20 at 10:26
  • 1
    You can inject `HttpServletRequest`. You can see if [one of these options](https://stackoverflow.com/a/2424824/2587435) works for making a multipart endpoint. – Paul Samsotha Sep 03 '20 at 15:06
  • Thank you for the suggestions but we decided to send imsge as base 64 encoded string in json key... This has been a dead end for weeks now – Swathi Sep 05 '20 at 07:36

1 Answers1

1

You can use org.apache.commons.fileupload library. Sample code that works for me for IBM MobileFirst adapter. To proces file follow apache documentation.

@POST
@Path("attachment")
@Consumes(MediaType.MULTIPART_FORM_DATA)
public Response uploadAttachment() {
    try {
        FileUploadUtil fileUploadUtil = new FileUploadUtil();
        List<FileItem> items = new ServletFileUpload(fileUploadUtil.createDiskFileItemFactory())
                .parseRequest(request);
        Optional<FileItem> file = fileUploadUtil.findFileItem(items, "file");
        //Your custom logic ....
    } catch (FileUploadException | IOException | MobileException e) {
        // ....
    }
}

where request is injected from context:

@Context
private HttpServletRequest request;
3squad
  • 355
  • 3
  • 14