C#向JAVA发送form-data文件问题处理方案
前言
和上一篇文章一样,.NET 和 JAVA之间的接口请求又遇到了新问题
我们有一个用来接收文件的接口,外部把文件流、文件名、目录,传进来,我们系统把生成的附件ID反回去,接口为POST-form-data格式
我用POSTMAN调用没有问题,就把文档写好发出去了,结果.NET开发的兄弟就又进行不下去了
问题现象
一模一样的参数,POSTMAN里请求正常,C#请求就返回空,翻了一下我们的日志,
NullPointerException
这。。。也不知道是哪抛出来的,本来就是原有的接口,逻辑一大堆,只看日志也看不出个所以然。
而且客户的环境我还没办法远程debug,我本地环境又没办法让对方开发调。
于是乎我和他们远程会议一点点猜他代码的问题,该加的参数都加了,找不出来哪有毛病。
处理过程
最后本着能让他们改,我自己就不动的原则,我开始研究起来了C#,之前基本没怎么接触过,从准备环境开始。。。
详细的环境准备过程请看:
//TODO C#环境准备
因为本来就不怎么会写么,况且POSTMAN能调通,于是准备直接用POSTMAN生成的代码来测,就得到了这个:
var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, "http://localhost:8080/api/doc/upload/uploadFile2Doc");
request.Headers.Add("appid", "CRM");
request.Headers.Add("token", "a3c6e10f-2269-4851-a3e4-3bb7bb1df183");
request.Headers.Add("userid", "EGqrxYColwBVopfkbVn/jUI7n9fPkRvcwnMh5LbNLuCkykywI902H3F98wvwlY8CWeHKXuiwLR8DmsCmupjcD1x79kMsNVkJOiq5N4y4Dj+CaFcelvdL+Nypgho3Sj4dPc/hRkbdXnvf4iAh8LR7v22pQOKuHm8I7ZclLID87JGKlsEs+X64CtJEJtTGh6js4PDBR5zWFB8NwxmcJHq4M26RNWeZVp7Tz93W5qv3WvgROUuuK7cla5gu8GgwqSJAQlti2VuNJpLIgTRNsB7UQeYCrGYNOTAU0JzDhAi+A3t7hA4eoWHb0+na/SLgR6sQrGzLk4KpO6rkU7PVCrHkjg==");
var content = new MultipartFormDataContent();
content.Add(new StreamContent(File.OpenRead("/C:/Users/13064/工作/测试文件/测试表格.xlsx")), "file", "/C:/Users/13064/工作/测试文件/测试表格.xlsx");
content.Add(new StringContent("测试表格.xlsx""), "name");
request.Content = content;
var response = await client.SendAsync(request);
response.EnsureSuccessStatusCode();
Console.WriteLine(await response.Content.ReadAsStringAsync());
不出所料,还是返回了个{}
不过好在是自己的环境,Debug,启动!
一层一层的找,发现这个NullPointerException
是因为拿到的file为null,于是我天真的揣测是不是header没有指定类型的问题
于是天真的加上了
content.Headers.ContentType = new MediaTypeHeaderValue("multipart/form-data")
果不其然,报错变了
Separation boundary was not specified
这是个什么东西,之前没见过,简单搜了一下,表明 multipart/form-data
请求中缺少边界(boundary)信息
然后文档里还写 :MultipartFormDataContent
确保你没有在请求中手动设置 Content-Type
,因为 C# 会自动添加边界
好吧,画蛇添足了属于是
继续从JAVA侧入手吧,看看为什么file为null,继续深入,发现file不是没拿到,而是到file这个参数的时候出问题了,但是异常并没有抛出
直接在里面catch掉之后return了个null
java.lang.RuntimeException: >>>>Xss(NoPass),invalidChar in params:--->referer:null path:/api/doc/upload/uploadFile2Doc param:=?utf-8?B?5rWL6K+V6KGo5qC8Lnhsc3g=?= rule=(the value is too big!(1000000)) paramValue:PK
值超长?其实这会就该想到为什么了,但是没反应过来,新建了个TXT传,心想肯定不会超长了吧,结果倒是没超长,但是file还是没拿到
仔细看了下,发现file参数被当作了个普通param来处理的,怪不得文件大一点就超长了
既然这种请求方式JAVA侧拿不到正确的参数类型,那就换一种,于是就从POSTMAN又得到了这段代码
var options = new RestClientOptions("http://localhost:8080")
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("/api/doc/upload/uploadFile2Doc", Method.Post);
request.AddHeader("appid", "CRM");
request.AddHeader("token", "a3c6e10f-2269-4851-a3e4-3bb7bb1df183");
request.AddHeader("userid", "EGqrxYColwBVopfkbVn/jUI7n9fPkRvcwnMh5LbNLuCkykywI902H3F98wvwlY8CWeHKXuiwLR8DmsCmupjcD1x79kMsNVkJOiq5N4y4Dj+CaFcelvdL+Nypgho3Sj4dPc/hRkbdXnvf4iAh8LR7v22pQOKuHm8I7ZclLID87JGKlsEs+X64CtJEJtTGh6js4PDBR5zWFB8NwxmcJHq4M26RNWeZVp7Tz93W5qv3WvgROUuuK7cla5gu8GgwqSJAQlti2VuNJpLIgTRNsB7UQeYCrGYNOTAU0JzDhAi+A3t7hA4eoWHb0+na/SLgR6sQrGzLk4KpO6rkU7PVCrHkjg==");
request.AddHeader("Cookie", "ecology_JSessionid=aaah7nfm2JXcVfjSBTajz; languageidweaver=7; loginidweaver=1");
request.AlwaysMultipartFormData = true;
request.AddFile("file", "/C:/Users/13064/工作/测试文件/测试表格.xlsx");
request.AddParameter("name", "测试表格.xlsx");
RestResponse response = await client.ExecuteAsync(request);
Console.WriteLine(response.Content);
调用一下,发现这次JAVA这边连debug都没进,而且C#这边也什么都没打出来
简单研究了一下RestResponse
的用法
加上了如下代码
if (response.IsSuccessful)
{
Console.WriteLine("请求成功:");
Console.WriteLine(response.Content);
}
else
{
Console.WriteLine("请求失败:");
Console.WriteLine($"状态码: {response.StatusCode}");
Console.WriteLine($"错误信息: {response.ErrorMessage}");
Console.WriteLine($"响应内容: {response.Content}");
}
状态码: NotAcceptable
继续添加
request.AddHeader("Accept", "*/*");
再看JAVA侧,终于file是个文件了,回看C#也已经正确拿到了返回数据
完整代码
为了方便扔给那边的兄弟做测试,简单优化了下
using RestSharp;
using Newtonsoft.Json.Linq;
string uri = "http://127.0.0.1:8080";
var json = await GetToken();
var jsonObject = JObject.Parse(json);
string token = (string)jsonObject["token"];
var options = new RestClientOptions(uri)
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("/api/doc/upload/uploadFile2Doc", Method.Post);
request.AddHeader("appid", "CRM");
request.AddHeader("token", token);
request.AddHeader("userid", "zOumGpDpL6azXvv/DBS/V3wxmqRxkJg3G1iI20RKtks6PcPTEykqJBAgwze9xT4DSUnaMQdYev3BiAFEX1DpsFoDYKe5LYuXf8h0o/KD86HE4DqzlfrNhwr4bFrbT+YZrONxc+hzx8m1QsqdwZMosrPnSbM0xQEwwMr/TAg3JRQmgDEa+OggqYupEaVfVIJklJEdtX6g2Dfor+WX79aCnKphZxp/N62zi/w6iBusSbwtAADN8Ind61YBZq/+yoi9E/FlkENRTv3tTwNAA59CHYbYZnpvIEW7XddefPTx9JVWtPN40kueNBLTdbsz41HuHOIcMFdaEGTTnA6hYUWllg==");
request.AddHeader("Accept", "*/*");
request.AlwaysMultipartFormData = true;
request.AddFile("file", "./t.txt");
request.AddParameter("name", "t.txt");
RestResponse response = await client.ExecuteAsync(request);
if (response.IsSuccessful)
{
Console.WriteLine("请求成功:");
Console.WriteLine(response.Content);
}
else
{
Console.WriteLine("请求失败:");
Console.WriteLine($"状态码: {response.StatusCode}");
Console.WriteLine($"错误信息: {response.ErrorMessage}");
Console.WriteLine($"响应内容: {response.Content}");
}
async Task<string> GetToken()
{
var options = new RestClientOptions(uri)
{
MaxTimeout = -1,
};
var client = new RestClient(options);
var request = new RestRequest("/api/ec/dev/auth/applytoken", Method.Post);
request.AddHeader("appid", "CRM");
request.AddHeader("secret", "hqHTV4Bf0/AN74M+FXxWs3v2GxxYrQwGoE+ioUOkFttFAFMGAR55JAzDeUkxN5MUwkHy+ovu2Fh2NtEoQh396dIAkdUdHiqzvrxHAIaHPfNrcUtAFVkcqRAKOsVLBVSAR7tMTxw5KkEqYI4mV/pMZeZB5tKK08nUFOi5u06xUwB8AS/jo8CYfuAFJ8xAJWld6bjGnNW6nJXWXam1lbMsD9RUZWJ/RHSzrISDCmNauG+ejpNuB8A4uyAaY7kEIx723ZU2HkczExfQXxwtEjCwS8elj8bQp39j+g8bYlL2O6fP2GDlWhYhzorGgzNc6MYBZFaQ2vDgP3KCP9NX9JlhSQ==");
request.AddHeader("Accept", "*/*");
RestResponse response = await client.ExecuteAsync(request);
return response.Content;
}
PS:C#语法确实比JAVA写起来方便,psvm
都没有就能用,而且比较有意思的是编译之后直接就能生成exe,之前我那JAVA写的东西想给别人直接双击启动 还得自己写bat,或者用exe4j,后面可以好好研究研究。
C#向JAVA发送form-data文件问题处理方案的更多相关文章
- fetch发送Form Data请求并携带cookie
今天我们来说说如何fetch发送Form Data请求并携带cookie,直接进入正题好吧,别问我今天为啥不在开始吹两句了,累到一句牛逼不想吹...... 步骤1: 设置头部,"Conten ...
- VUE axios 发送 Form Data 格式数据请求
axios 默认是 Payload 格式数据请求,但有时候后端接收参数要求必须是 Form Data 格式的,所以我们就得进行转换.Payload 和 Form Data 的主要设置是根据请求头的 C ...
- python 处理form/data文件上传
处理multipart/form-data 的java serverlet请求接口通过python实现 记住不要在头加:"Content-Type":"multipart ...
- springMVC中对HTTP请求form data和request payload两种数据发送块的后台接收方式
最近在做项目中发现,前台提交数据时,如果通过form表单提交和ajax发送json时,springMVC后台接收不能都通过@ModelAttribute方式处理,经过一番查找后,ajax发送json请 ...
- Socket通讯-C#客户端与Java服务端通讯(发送消息和文件)
设计思路 使用websocket通信,客户端采用C#开发界面,服务端使用Java开发,最终实现Java服务端向C#客户端发送消息和文件,C#客户端实现语音广播的功能. Java服务端设计 packag ...
- [整理]Ajax Post请求下的Form Data和Request Payload
Ajax Post请求下的Form Data和Request Payload 通常情况下,我们通过Post提交表单,以键值对的形式存储在请求体中.此时的reqeuest headers会有Conten ...
- html5 file upload and form data by ajax
html5 file upload and form data by ajax 最近接了一个小活,在短时间内实现一个活动报名页面,其中遇到了文件上传. 我预期的效果是一次ajax post请求,然后在 ...
- form data和request payload的区别
HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: <form action="form_action.asp&qu ...
- Web 前沿——HTML5 Form Data 对象的使用
XMLHttpRequest Level 2 添加了一个新的接口——FormData.利用 FormData 对象,我们可以通过 JavaScript 用一些键值对来模拟一系列表单控件,我们还可以使用 ...
- HTTP请求中的form data和request payload的区别
HTML <form> 标签的 enctype 属性 在下面的例子中,表单数据会在未编码的情况下进行发送: <form action="form_action.asp&qu ...
随机推荐
- Fluent Builder 模式
前言 以前最讨厌设计复杂方法调用, 就是那种需要一堆有逻辑规则的 config 作为参数的方法. 这种 config 通常是一个大对象, 有许多 property, property 之间有存在一些逻 ...
- Figma 学习笔记 – Plugin
安装 Figma 安装 plugin 基本上就是点击一下开启而已. 到社区搜索 -> 点击 install Material Icon 下载地址 它的交互不是 drag 出来哦, 而是点击 ic ...
- 2024 年 C# 高效开发:精选实用类库
前言 在平时开发中,好的类库能帮助我们快速实现功能,C#有很多封装好的类库. 本文将介绍一些2024年特别受欢迎的C#类库,并分析各自的优点让我们编程写代码变的更轻松.更快捷. 快来看一看有没有大家常 ...
- 《你必须掌握的Entity Framework 6.x与Core 2.0》代码下载
https://item.jd.com/12376014.html<你必须掌握的Entity Framework 6.x与Core 2.0>代码下载,共享代码: https://git ...
- 一款基于Uniapp开发的开源低代码平台
rtvue-lowcode低代码开发平台 rtvue-lowcode一款基于uniapp框架和uview组件库的低代码开发平台,项目提供可视化拖拽编辑器,采用MIT开源协议,适用于app.小程序等项目 ...
- foobar2000 v2.1.2 汉化版(更新日期: 2024.02.27)
新春佳节,送上一份新年礼物,祝您在新的一年里,万事如意,心想事成,身体健康,事业有成,财源广进,家庭和睦,笑容常开,好运连连. foobar2000 v2.1.2 汉化版 ---------- ...
- go 使用websocket
package chat import ( "encoding/json" "github.com/gorilla/websocket" "githu ...
- js模拟二维数组求和
JavaScri实际上没有二维数组的概念,但是由于js变量是松散的,所以能设置数组元素为数组来模拟二维数组,以此类推,可以模拟多维数组. /* 需求:模拟了3 * 3数组求右上三角元素之和1 + 3 ...
- signalR的身份认证
- Access to XMLHttpRequest at xxxx from origin xxx has been blocked by CORS policy: No 'Access-Control- Allow-Origin' header is present on the requested resource
错误:控制台报错 : network 自动发起了请求: 解决办法: 找到 \node_modules\sockjs-client\dist\sockjs.js 文件 然后 crtl + g 快捷键跳 ...