IBM Mobilefirst Java HTTP Adapter 中的多部分文件上传
Posted
技术标签:
【中文标题】IBM Mobilefirst Java HTTP Adapter 中的多部分文件上传【英文标题】:Multipart file upload in IBM Mobilefirst Java HTTP Adapter 【发布时间】:2020-09-03 03:30:52 【问题描述】:我是 IBM Mobile-first java 适配器的新手,我正在尝试使用 Postman 将图像文件(Multipart 请求)发送到我的 java 适配器(使用 JAX-Rs),并在 Rest API 中接收该图像文件,并且将其发送到第三方服务器。
但是,每当我从 Postman 访问 API 时,我都会收到 415 Unsupported media type 错误,我什至尝试在 MFPJAXRSApplication 类中配置 JAX-rs2.0,但这也不起作用。谁能帮我解决这个问题。
我的主要应用类
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);
我的资源类是当我从代码中删除 FormDataContentDisposition 并只保留 Inputstrem 时,我可以访问 API,但一旦添加 FormDataContentDisposition,它就会以 415 不支持的媒体类型错误开始。
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>
我想知道为什么服务器无法识别 Multipart 请求,我们是否必须配置适配器以接受 multipart 请求,如果是,那么我们如何配置它?任何人都可以通过帮助我来挽救我的生命。
另外,我的应用程序没有 WEB.xml 或任何以 @ApplicationPath 开头的类
【问题讨论】:
在返回此响应之前是否会引发服务器端错误/异常? Mobile-First 是否使用 Jersey 实现来支持其 JAX-RS? 当您省略 FormDataContentDisposition 时,请求正文会显示什么?它只是“文件”部分的内容还是完整的多部分实体?我假设后者。在这种情况下,@FormDataParam
注释将被忽略。当您省略第二个参数时,第一个参数被简单地视为整个身体。除非与 Jersey 一起使用,否则 Jersey 的 Multipart 支持将不起作用。
我已经在适配器应用程序 MFPJAXRSApplication 类中配置了球衣 .. 并且在 mave 文件中导入了球衣依赖,但同样的问题仍然存在
你可以注入HttpServletRequest
。您可以查看one of these options 是否适用于制作多部分端点。
【参考方案1】:
您可以使用 org.apache.commons.fileupload 库。适用于 IBM MobileFirst 适配器的示例代码。 要处理文件,请遵循 apache 文档。
@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)
// ....
从上下文注入请求的地方:
@Context
private HttpServletRequest request;
【讨论】:
以上是关于IBM Mobilefirst Java HTTP Adapter 中的多部分文件上传的主要内容,如果未能解决你的问题,请参考以下文章
Bluemix 的 ibm-mobilefirst-starter 容器 - 添加新的 http 适配器不起作用
IBM MobileFirst:在命令行构建期间使用外部 jar 文件