通过对象FC接入点访问GetObject API时,将触发您所绑定的函数计算服务中的函数,并在函数中配合WriteGetObjectResponse接口实现自定义返回数据和响应标头。
前提条件
-
已创建对象FC接入点。具体操作,请参见创建对象FC接入点。
-
OSS Java SDK为3.17.2及以上版本。
-
OSS Python SDK为2.18.3及以上版本。
操作步骤
-
编写处理GetObject请求的函数示例。
示例一:通过转换后的图片进行响应
Java
import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.VoidResult; import com.aliyun.oss.model.WriteGetObjectResponseRequest; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.*; import java.util.Scanner; public class Example1 implements StreamRequestHandler { // Endpoint以华北1(青岛)为例。 String endpoint = "https://oss-cn-qingdao.aliyuncs.com"; private static int status = 200; public static String convertToString(InputStream inputStream) { Scanner scanner = new Scanner(inputStream).useDelimiter("\A"); return scanner.hasNext() ? scanner.next() : ""; } @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { Credentials creds = context.getExecutionCredentials(); // 从上下文中获取访问密钥。 OSS ossClient = new OSSClientBuilder().build(endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); try { String result = convertToString(inputStream); JSONObject jsonObject = new JSONObject(result); String route = jsonObject.getJSONObject("getObjectContext").getString("outputRoute"); String token = jsonObject.getJSONObject("getObjectContext").getString("outputToken"); // 通过调用BufferedImage创建200*200像素的对象,并为该对象绘制红色的矩形框。 // 完成以上调整后,将内容写入WriteGetObjectResponse请求的主体中。 BufferedImage image = new BufferedImage(200, 200, BufferedImage.TYPE_INT_RGB); Graphics2D graphics = image.createGraphics(); graphics.setColor(Color.RED); graphics.fillRect(0, 0, 200, 200); graphics.dispose(); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ImageIO.write(image, "png", baos); WriteGetObjectResponseRequest writeGetObjectResponseRequest = new WriteGetObjectResponseRequest(route, token, status,new ByteArrayInputStream(baos.toByteArray())); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(baos.size()); writeGetObjectResponseRequest.setMetadata(metadata); VoidResult voidResult = ossClient.writeGetObjectResponse(writeGetObjectResponseRequest); System.out.println("getRequestId:"+voidResult.getRequestId()); System.out.println("status:"+voidResult.getResponse().getStatusCode()); System.out.println("Headers:"+voidResult.getResponse().getHeaders().toString()); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.getMessage()); System.out.println("Error Code: " + oe.getErrorCode()); System.out.println("Request ID: " + oe.getRequestId()); System.out.println("Host ID: " + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getMessage()); } catch (JSONException e) { e.printStackTrace(); } finally { ossClient.shutdown(); } } }
Python
# -*- coding: utf-8 -*- import io from PIL import Image import oss2 import json # Endpoint以华北1(青岛)为例。 endpoint = 'http://oss-cn-qingdao.aliyuncs.com' fwd_status = '200' # Fc function entry def handler(event, context): evt = json.loads(event) creds = context.credentials # do not forget security_token auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token) headers = dict() event_ctx = evt["getObjectContext"] route = event_ctx["outputRoute"] token = event_ctx["outputToken"] print(evt) endpoint = route service = oss2.Service(auth, endpoint) # 通过调用Image方法创建200*200像素的对象,并为该对象绘制红色的矩形框。 # 完成以上调整后,将内容写入write_get_object_response请求的主体中。 image = Image.new('RGB', (200, 200), color=(255, 0, 0)) transformed = io.BytesIO() image.save(transformed, "png") resp = service.write_get_object_response(route, token, fwd_status, transformed.getvalue(), headers) print('status: {0}'.format(resp.status)) print(resp.headers) return 'success'
示例二:通过压缩内容进行响应
Java
import com.aliyun.fc.runtime.Context; import com.aliyun.fc.runtime.Credentials; import com.aliyun.fc.runtime.StreamRequestHandler; import com.aliyun.oss.ClientException; import com.aliyun.oss.OSS; import com.aliyun.oss.OSSClientBuilder; import com.aliyun.oss.OSSException; import com.aliyun.oss.model.OSSObject; import com.aliyun.oss.model.ObjectMetadata; import com.aliyun.oss.model.VoidResult; import com.aliyun.oss.model.WriteGetObjectResponseRequest; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import java.io.*; import java.net.URL; import java.util.HashMap; import java.util.Map; import java.util.Scanner; import java.util.zip.ZipEntry; import java.util.zip.ZipOutputStream; public class Example2 implements StreamRequestHandler { // Endpoint以华北1(青岛)为例。 String endpoint = "https://oss-cn-qingdao.aliyuncs.com"; // 填写object名称。 String fileName = "examplefile.txt"; // 本地临时生成的压缩包路径。 String path = "test.zip"; private static int status = 200; public static String convertToString(InputStream inputStream) { Scanner scanner = new Scanner(inputStream).useDelimiter("\A"); return scanner.hasNext() ? scanner.next() : ""; } public static void convertToZip(InputStream inputStream, String fileName, String path) throws IOException { FileOutputStream fos = new FileOutputStream(path); ZipOutputStream zipOut = new ZipOutputStream(fos); ZipEntry zipEntry = new ZipEntry(fileName); zipOut.putNextEntry(zipEntry); byte[] bytes = new byte[1024]; int length; while((length = inputStream.read(bytes)) >= 0) { zipOut.write(bytes, 0, length); } zipOut.close(); inputStream.close(); fos.close(); } @Override public void handleRequest(InputStream inputStream, OutputStream outputStream, Context context) throws IOException { Credentials creds = context.getExecutionCredentials(); // 从上下文中获取访问密钥。 System.out.println("getAccessKeyId: "+creds.getAccessKeyId()); System.out.println("getAccessKeySecret: "+creds.getAccessKeySecret()); OSS ossClient = new OSSClientBuilder().build(endpoint, creds.getAccessKeyId(), creds.getAccessKeySecret(), creds.getSecurityToken()); try { String result = convertToString(inputStream); JSONObject jsonObject = new JSONObject(result); String route = jsonObject.getJSONObject("getObjectContext").getString("outputRoute"); String token = jsonObject.getJSONObject("getObjectContext").getString("outputToken"); String inputOssUrl = jsonObject.getJSONObject("getObjectContext").getString("inputOssUrl"); System.out.println("jsonObject:"+jsonObject); System.out.println("inputOssUrl: "+inputOssUrl); Map customHeaders = new HashMap(); URL signedUrl = new URL(inputOssUrl); OSSObject ossObject = ossClient.getObject(signedUrl, customHeaders); System.out.println("getObject StatusCode: "+ossObject.getResponse().getStatusCode()); // 把通过签名url获取到的文件进行压缩后上传。 convertToZip(ossObject.getObjectContent(), fileName, path); File file = new File(path); FileInputStream fis = new FileInputStream(file); WriteGetObjectResponseRequest writeGetObjectResponseRequest = new WriteGetObjectResponseRequest(route, token, status, fis); ObjectMetadata metadata = new ObjectMetadata(); metadata.setContentLength(file.length()); writeGetObjectResponseRequest.setMetadata(metadata); VoidResult voidResult = ossClient.writeGetObjectResponse(writeGetObjectResponseRequest); System.out.println("getRequestId:"+voidResult.getRequestId()); System.out.println("status:"+voidResult.getResponse().getStatusCode()); System.out.println("Headers:"+voidResult.getResponse().getHeaders().toString()); // 删除临时生成的压缩包。 file.delete(); } catch (OSSException oe) { System.out.println("Caught an OSSException, which means your request made it to OSS, " + "but was rejected with an error response for some reason."); System.out.println("Error Message: " + oe.getMessage()); System.out.println("Error Code: " + oe.getErrorCode()); System.out.println("Request ID: " + oe.getRequestId()); System.out.println("Host ID: " + oe.getHostId()); } catch (ClientException ce) { System.out.println("Caught an ClientException, which means the client encountered " + "a serious internal problem while trying to communicate with OSS, " + "such as not being able to access the network."); System.out.println("Error Message: " + ce.getMessage()); } catch (JSONException e) { e.printStackTrace(); } finally { ossClient.shutdown(); } } }
Python
# -*- coding: utf-8 -*- import os import oss2 import json import gzip import requests # Endpoint以华北1(青岛)为例。 endpoint = 'http://oss-cn-qingdao.aliyuncs.com' fwd_status = '200' # 填写object名称。 fileName = "examplefile.txt" # 本地临时生成的压缩包路径。 path = 'test.zip' def handler(event, context): evt = json.loads(event) creds = context.credentials # 从上下文中获取访问密钥。 auth = oss2.StsAuth(creds.access_key_id, creds.access_key_secret, creds.security_token) headers = dict() event_ctx = evt["getObjectContext"] route = event_ctx["outputRoute"] token = event_ctx["outputToken"] inputOssUrl = event_ctx["inputOssUrl"] print(evt) endpoint = route resp = requests.get(inputOssUrl) # 把通过签名URL获取到的文件进行压缩后上传。 g = gzip.GzipFile(filename=fileName, mode="wb", compresslevel=9, fileobj=open(path, 'wb')) g.write(resp.content) g.close() service = oss2.Service(auth, endpoint) with open(path, 'rb') as fileobj: resp = service.write_get_object_response(route, token, fwd_status, fileobj, headers) print('status: {0}'.format(resp.status)) print(resp.headers) # 删除临时生成的压缩包。 os.remove(path) return 'success'
-
部署函数。
Java
-
自行打包.jar文件。
-
将.jar文件上传至函数计算控制台。
- 登录函数计算控制台,在左侧导航栏,单击服务及函数。
-
在顶部导航栏,选择华北1(青岛)地域。
-
在服务列表页面,单击已创建的服务,然后单击已创建的运行环境为Java 11的函数。
-
在函数详情页面,选择上传代码 > 上传JAR包。
-
在弹出的对话框,选择已打包的.jar文件,勾选我想在选中文件后直接部署函数,然后单击保存并部署。
-
根据函数示例对应修改请求处理程序(函数入口)。
-
在函数详情页面,单击函数配置页签。
-
在环境信息区域,单击编辑。
-
修改请求处理程序(函数入口)。
当运行环境为Java时,当前值的格式为
[package].[class]::[method]
。如果当前值为example.HelloFC::handleRequest
,则在函数被触发时,将执行example包中HelloFC类下的handleRequest函数。您需要根据处理GetObject请求的函数示例的实际情况修改当前值,例如com.aliyun.sts.sample.Example1::handleRequest
。
-
Python
-
在服务列表页面,单击已创建的服务,然后单击已创建的运行环境为Python 3.10的函数。
-
在函数详情页面,单击函数代码页签,然后选择Terminal > New Terminal 。
-
在TERMINAL面板,输入以下命令更新OSS Python SDK版本。
pip install oss2 -t .
-
将index.py中的代码示例替换为Python处理GetObject请求的函数示例,然后单击部署函数。
-
后续步骤
使用对象FC接入点
内容没看懂? 不太想学习?想快速解决? 有偿解决: 联系专家
阿里云企业补贴进行中: 马上申请
腾讯云限时活动1折起,即将结束: 马上收藏
同尘科技为腾讯云授权服务中心。
购买腾讯云产品享受折上折,更有现金返利:同意关联,立享优惠
转转请注明出处:https://www.yunxiaoer.com/159075.html