欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  web前端

HTTPclient使用MultipartEntity怎么上传文件_html/css_WEB-ITnose

程序员文章站 2022-04-27 15:44:24
...
jsp HTTPclient MultipartEntity multipart/form-data

jsp 页面上传文件代码:




httpclient 不知道怎么写,
网上查了一大堆都是你抄我我抄你的,
网上都是这么写的
jsp 代码是下面这样的
enctype="multipart/form-data">






后天代码都是这样写的

MultipartEntity entity = new MultipartEntity();
entity.addPart("param1", new StringBody("中国", Charset.forName("UTF-8")));
entity.addPart("param2", new StringBody("value2", Charset.forName("UTF-8")));
entity.addPart("param3", new FileBody( new File("C:\\1.txt")));

HttpPost request = new HttpPost(“http://localhost/index.html”);
request.setEntity(entity);

我就不懂了,上面的路径都是文件上传选的,他们写代码都是
entity.addPart("param3", new FileBody( new File("C:\\1.txt")));
文件路径都是写死的,文件上传貌似是没有这个new File()的吧!因为代码在服务器端,怎么可能会这么写呢?
用户上传自己本地的代码是本地的路径,服务器边这边肯定是没这个地址的,

我都不知道上面这些代码他们自己都不去验证就往上写

求高手们帮帮忙,这个问题怎么解决,
服务器端的接口要的就是multipart/form-data这个数据,我该怎么写



回复讨论(解决方案)

你先搞清楚 HTTPclient 是做什么用的
HTTPclient 的作用是在 jsp 中模拟一个浏览器,即 HTTP 协议的客户端(client)
你的后台代码是将你本地服务器上的文件 浏览器那样上传到目标服务器
于是 new File("C:\\1.txt") 的问题就可以解决了吧?C:\\1.txt 是你本地服务器中的文件,当然文件名是你自己定的

至于 multipart/form-data 声明,那是由 HttpPost 的参数 MultipartEntity 自动加上的

我要的就是网页上传到服务器,服务器使用HTTPclient 调用另一个服务接口上传,并不是上传我本地文件

因为这个接口规定了只能传multipart/form-data,浏览器那边会把上传的文件信息通过这边后台获取后再转向接口那边去执行保存,接口那边存放操作各自数据等

我的页面是这样的,这个窗口有上传功能,进行提交,提交到后台,后台再使用httpclient转向另一个接口服务器,需要把这些数据传过去,接口那边要的是multipart/form-data 这个文件流,我现在不知道怎么使用httpclient传过去,因为我以前没用功HTTPclient

上传功能窗口

上传请求到后台的数据


这就是传给后台的数据,现在是想要httpclient获取multipart/form-data,不知道怎么做

Request URL:http://localhost:8080/proxy/api/images/attachments/json/0/67/0/0/-1?Type=Image&CKEditor=textEditor&CKEditorFuncNum=1&langCode=zh-cn
Request Headers CAUTION: Provisional headers are shown.
Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarysw8ttG9a1gakIbQt
Origin:http://localhost:8080
Referer:http://localhost:8080/user/kouht/editonline
User-Agent:Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/34.0.1847.116 Safari/537.36
Query String Parametersview sourceview URL encoded
Type:Image
CKEditor:textEditor
CKEditorFuncNum:1
langCode:zh-cn
Request Payload
------WebKitFormBoundarysw8ttG9a1gakIbQt
Content-Disposition: form-data; name="upload"; filename="menu.png"
Content-Type: image/png


------WebKitFormBoundarysw8ttG9a1gakIbQt--

你浏览器上传文件是上传到你自己的服务器,你接收后在传到其他服务器时,才需要用 HTTPclient
这是接力,不要搞混了!

你浏览器上传文件是上传到你自己的服务器,你接收后在传到其他服务器时,才需要用 HTTPclient
这是接力,不要搞混了!



不能直接传到另一个服务器吗

不能!
因为浏览器上传文件结束时,jsp 才开始工作
而 HTTPclient 只是模拟了浏览器,也是文件方式上传文件
如果你想在 jsp 中一边接收上传文件的数据,一边向上级服务器发送的话
一是要你自己写文件接收程序,二是要用 socket 向上级服务器发送
涉及的知识太多,你一时半会是搞不起来的

不能!
因为浏览器上传文件结束时,jsp 才开始工作
而 HTTPclient 只是模拟了浏览器,也是文件方式上传文件
如果你想在 jsp 中一边接收上传文件的数据,一边向上级服务器发送的话
一是要你自己写文件接收程序,二是要用 socket 向上级服务器发送
涉及的知识太多,你一时半会是搞不起来的



好像是可以的,我看了下他们以前的代码,是可以的,不需要那么麻烦,他们是这么写的

下面这个方法就是我上面说的那个路径 Request URL:http://localhost:8080/proxy/api/images/attachments/json/0/67/0/0/-1?Type=Image&CKEditor=textEditor&CKEditorFuncNum=1&langCode=zh-cn
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String targerUrl =request.getRequestURI();
HttpProxy.request(request, response, targerUrl);// 代理请求
}

/**
* 代理请求
*
* @param request
* - 请求
* @param response
* - 响应
* @param targetUrl
* - 目标服务器地址
* @param encoding
* - 目标服务器的编码格式
* @return
* @throws IOException
*/
public static void request(HttpServletRequest request, HttpServletResponse response, String targetUrl) throws IOException {

// System.out.println("进入Http代理");

// 目标url
if (null == targetUrl) {
throw new IOException("缺少目标服务器地址");
}

// 目标服务器地址
String url = null;

// 获取目标服务器地址,并对目标服务器中的中文进行重新编码
try {
url = ProxyUtils.rebuildURL2(targetUrl, "utf-8");
} catch (Exception e) {
e.printStackTrace();
}

// 请求参数
Map params = new HashMap();

// 请求头部信息
Map headers = new HashMap();

// 客户端请求方式
String method = request.getMethod();

logger.info("[代理请求] method: " + method + ": " + url);

// 获取请求头部信息的枚举
Enumeration headersEnu = request.getHeaderNames();
while (headersEnu.hasMoreElements()) {
// 取得请求头部名称
String headerName = (String) headersEnu.nextElement();
String headerValue = request.getHeader(headerName);
headers.put(headerName.toLowerCase(), headerValue);
logger.info("\t[header] " + headerName + "=" + headerValue);
}

// 如果有指定请求头部,就覆盖原来请求头部
if (null != headerMap && headerMap.size() > 0) {
for (String key : headerMap.keySet()) {
headers.put(key.toLowerCase(), headerMap.get(key));
}
}
// 获取参数键值名称
Enumeration enu = request.getParameterNames();
while (enu.hasMoreElements()) {
// 取得参数名称列表
String paramName = (String) enu.nextElement();
// 处理本请求参数以及发送给第三方服务器的参数
String paramValue = request.getParameter(paramName);
params.put(paramName, paramValue);
logger.info("\t[参数] " + paramName + "=" + paramValue);
}

// 取得ajax代理
AjaxProxy proxy = ProxyFactory.getProxyInstance(method, url, params, headers);

// // 请求body
// String requestBody = readFileByLines(request.getInputStream());
//
// System.out.println("\n[requestBody]" + requestBody);

// 获取ajax代理响应
AjaxResponse resp = null;

// 若是post请求,且属于表单上传时(multipart/form-data),传递input流
String contentType = headers.get("content-type");
boolean isUpload = null != contentType && contentType.toLowerCase().indexOf("multipart/form-data") >= 0;

// 1,当请求的资源是图片时,直接使用流作为response返回结果
String accept = headers.get("accept");
boolean useStream4response = null != accept ? (accept.indexOf("image/") >= 0) : true;

// 始终使用流作为返回值
useStream4response = true;

if ("post".equalsIgnoreCase(method) && isUpload) {
useStream4response = false;
// 期望上传图片后返回xml格式数据
headers.put("accept", "application/json");
resp = proxy.getAjaxResponse(request.getInputStream());
// } else if ( "put".equalsIgnoreCase(method) && params.size() > 0 )
// {
// // put请求, 且具有参数, 传递input流
// resp = proxy.getAjaxResponse(request.getInputStream());
} else if (useStream4response) {
OutputStream out = response.getOutputStream();
resp = proxy.getAjaxResponse(out);
out.flush();
} else {
resp = proxy.getAjaxResponse();
}

// 取得方法
HttpMessage httpMethod = resp.getMethod();

// 无响应时httpMethod为null
if (null == httpMethod) {
logger.info("[代理请求失败] http code: " + resp.getStatusCode() + ": " + url);
return;
}

// 取得响应头部
Header[] respHheaders = httpMethod.getAllHeaders();
for (int i = 0, len = respHheaders.length; i Header header = respHheaders[i];
if (!isOverrideCookie && "Set-Cookie".equalsIgnoreCase(header.getName())) {
continue;
}
if ("content-type".equalsIgnoreCase(header.getName())) {
if ("post".equalsIgnoreCase(method) && isUpload) {
// 若是上传,则不覆盖contentType
response.setCharacterEncoding("utf-8");
continue;
}
}
response.setHeader(header.getName(), header.getValue());
logger.info("\t[response header] " + header.getName() + "=" + header.getValue());
}

// 输出
if (useStream4response) {
logger.info("请求地址: " + url + "\n-----返回结果: [Stream]");
} else {
PrintWriter out = response.getWriter();
String result = resp.getContent();
out.print(result);
}
return;
}

用这个红色的代码给上传上去了

你按他写的成功了吗?

他的思路是完全不同的,他是写了一个代理服务器
用你的服务器中站客户端请求

需要注意的是,写代理服务器时,不要窥视用户数据。这是有违职业道德的

对,这个就成功了,没有窥视,他这就是相当于把浏览器请求的信息全部拿到再去用代理请求一次,把数据原封不动的再去请求