手机怎么wireshark 抓取手机Form Data?

怎样获取form-data方式POST的数据
转自:http://ju.outofmemory.cn/entry/201812
用x-www-form-urlencoded方式提交表单就可以正常绑定数据,但是用form-data方式提交就绑定不了:
@Controller
@RequestMapping("/tag")
public class TagController {
@Autowired
private NanTianMenFacade nanTianMenFacade;
@RequestMapping(value = "/uploadTags")
@ResponseBody
public TagUploadResult uploadTags(TagParams params) {
String tagIds = params.getTagIds();
String uuid = params.getUuid();
TagUploadResult result = null;
result = nanTianMenFacade.uploadTags(tagIds, uuid);
} catch (Exception e) {
result = new TagUploadResult();
result.setS(0);
return result;
对于我来说,一直都是用x-www-form-urlencoded提交表单数据,除非是要上传文件,才会使用form-data方式。也一直以为Spring对不同的提交方式应该是透明的。不过确实用form-data提交普通表单,确实是拿不到提交的数据。DEBUG发现, request.getParameterMap() 返回的就是空的!
然后发现 org.apache.commons.io.IOUtils.toString(request.getInputStream()); 其实是有返回提交的数据的:
------WebKitFormBoundaryd7FGw9vQyyFIAYd7
Content-Disposition: form-data; name="uuid"
------WebKitFormBoundaryd7FGw9vQyyFIAYd7
Content-Disposition: form-data; name="tagIds"
------WebKitFormBoundaryd7FGw9vQyyFIAYd7
Content-Disposition: form-data; name="aaa"
------WebKitFormBoundaryd7FGw9vQyyFIAYd7--
也就是数据其实是有正常提交到后台的。那么就是这种方式提交的数据,并没有放在pararmeterMap中了。而是要自己去解析这个inputstream的内容,再放回parameterMap中,这样Spring才能够绑定?这个不就是 multipartResolver 做的事情吗?试着配置了一下,发现果然可以了:
id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver"
name="maxUploadSize" value=""
然后深入Spring MVC的代码,其实是做了一个判断,如果是Multipart,那么就会进行解析,然后将解析结果放回parameterMap中:
package org.springframework.web.servlet;
public class DispatcherServlet extends FrameworkServlet {
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
ModelAndView mv = null;
Exception dispatchException = null;
processedRequest = checkMultipart(request);
multipartRequestParsed = processedRequest != request;
// Determine handler for the current request.
mappedHandler = getHandler(processedRequest, false);
if (mappedHandler == null || mappedHandler.getHandler() == null) {
noHandlerFound(processedRequest, response);
// Determine handler adapter for the current request.
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Process last-modified header, if supported by the handler.
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if (isGet || "HEAD".equals(method)) {
long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
if (logger.isDebugEnabled()) {
logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
// Actually invoke the handler.
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
applyDefaultViewName(request, mv);
mappedHandler.applyPostHandle(processedRequest, response, mv);
catch (Exception ex) {
dispatchException = ex;
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
catch (Exception ex) {
triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
catch (Error err) {
triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
if (asyncManager.isConcurrentHandlingStarted()) {
// Instead of postHandle and afterCompletion
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
// Clean up any resources used by a multipart request.
if (multipartRequestParsed) {
cleanupMultipart(processedRequest);
* Convert the request into a multipart request, and make multipart resolver available.
* &p&If no multipart resolver is set, simply use the existing request.
* @param request current HTTP request
* @return the processed request (multipart wrapper if necessary)
* @see MultipartResolver#resolveMultipart
protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
if (request instanceof MultipartHttpServletRequest) {
logger.debug("Request is already a MultipartHttpServletRequest - if not in a forward, " +
"this typically results from an additional MultipartFilter in web.xml");
return this.multipartResolver.resolveMultipart(request);
// If not returned before: return original request.
return request;
package org.springframework.web.multipart.commons;
public class CommonsMultipartResolver extends CommonsFileUploadSupport
implements MultipartResolver, ServletContextAware {
public MultipartHttpServletRequest resolveMultipart(final HttpServletRequest request) throws MultipartException {
Assert.notNull(request, "Request must not be null");
if (this.resolveLazily) {
return new DefaultMultipartHttpServletRequest(request) {
protected void initializeMultipart() {
MultipartParsingResult parsingResult = parseRequest(request);
setMultipartFiles(parsingResult.getMultipartFiles());
setMultipartParameters(parsingResult.getMultipartParameters());
setMultipartParameterContentTypes(parsingResult.getMultipartParameterContentTypes());
MultipartParsingResult parsingResult = parseRequest(request);
return new DefaultMultipartHttpServletRequest(request, parsingResult.getMultipartFiles(),
parsingResult.getMultipartParameters(), parsingResult.getMultipartParameterContentTypes());
* Parse the given servlet request, resolving its multipart elements.
* @param request the request to parse
* @return the parsing result
* @throws MultipartException if multipart resolution failed.
@SuppressWarnings("unchecked")
protected MultipartParsingResult parseRequest(HttpServletRequest request) throws MultipartException {
String encoding = determineEncoding(request);
FileUpload fileUpload = prepareFileUpload(encoding);
List&FileItem& fileItems = ((ServletFileUpload) fileUpload).parseRequest(request);
return parseFileItems(fileItems, encoding);
catch (FileUploadBase.SizeLimitExceededException ex) {
throw new MaxUploadSizeExceededException(fileUpload.getSizeMax(), ex);
catch (FileUploadException ex) {
throw new MultipartException("Could not parse multipart servlet request", ex);
package org.apache.commons.fileupload;
public abstract class FileUploadBase {
* Processes an &a href="http://www.ietf.org/rfc/rfc1867.txt"&RFC 1867&/a&
* compliant &code&multipart/form-data&/code& stream.
* @param request The servlet request to be parsed.
* @return A list of &code&FileItem&/code& instances parsed from the
request, in the order that they were transmitted.
* @throws FileUploadException if there are problems reading/parsing
the request or storing files.
public List&FileItem& parseRequest(HttpServletRequest request)
throws FileUploadException {
return parseRequest(new ServletRequestContext(request));
* Processes an &a href="http://www.ietf.org/rfc/rfc1867.txt"&RFC 1867&/a&
* compliant &code&multipart/form-data&/code& stream.
* @param ctx The context for the request to be parsed.
* @return A list of &code&FileItem&/code& instances parsed from the
request, in the order that they were transmitted.
* @throws FileUploadException if there are problems reading/parsing
the request or storing files.
public List&FileItem& parseRequest(RequestContext ctx)
throws FileUploadException {
List&FileItem& items = new ArrayList&FileItem&();
boolean successful = false;
FileItemIterator iter = getItemIterator(ctx);
FileItemFactory fac = getFileItemFactory();
if (fac == null) {
throw new NullPointerException("No FileItemFactory has been set.");
while (iter.hasNext()) {
final FileItemStream item = iter.next();
// Don't use getName() here to prevent an InvalidFileNameException.
final String fileName = ((FileItemIteratorImpl.FileItemStreamImpl) item).name;
FileItem fileItem = fac.createItem(item.getFieldName(), item.getContentType(),
item.isFormField(), fileName);
items.add(fileItem);
Streams.copy(item.openStream(), fileItem.getOutputStream(), true);
} catch (FileUploadIOException e) {
throw (FileUploadException) e.getCause();
} catch (IOException e) {
throw new IOFileUploadException(format("Processing of %s request failed. %s",
MULTIPART_FORM_DATA, e.getMessage()), e);
final FileItemHeaders fih = item.getHeaders();
fileItem.setHeaders(fih);
successful = true;
return items;
} catch (FileUploadIOException e) {
throw (FileUploadException) e.getCause();
} catch (IOException e) {
throw new FileUploadException(e.getMessage(), e);
} finally {
if (!successful) {
for (FileItem fileItem : items) {
fileItem.delete();
} catch (Throwable e) {
// ignore it
没有更多推荐了,
不良信息举报
举报内容:
怎样获取form-data方式POST的数据
举报原因:
原文地址:
原因补充:
最多只允许输入30个字
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!Python爬虫抓取手机APP的传输数据
转载 & & 作者:j_hao104
大多数APP里面返回的是json格式数据,或者一堆加密过的数据 。这里以超级课程表APP为例,抓取超级课程表里用户发的话题
大多数APP里面返回的是json格式数据,或者一堆加密过的数据 。这里以超级课程表APP为例,抓取超级课程表里用户发的话题。
1、抓取APP数据包
方法详细可以参考这篇博文:
得到超级课程表登录的地址:
表单中包括了用户名和密码,当然都是加密过了的,还有一个设备信息,直接post过去就是。
另外必须加header,一开始我没有加header得到的是登录错误,所以要带上header信息。
登录代码:
import urllib2
from cookielib import CookieJar
loginUrl = 'http://120.55.151.61/V2/StudentSkip/loginCheckV4.action'
headers = {
'Content-Type': 'application/x-www-form- charset=UTF-8',
'User-Agent': 'Dalvik/1.6.0 (L U; Android 4.1.1; M040 Build/JRO03H)',
'Host': '120.55.151.61',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip',
'Content-Length': '207',
loginData = 'phoneBrand=Meizu&platform=1&deviceCode=494&account=FCF030E1F2FBE5BBC422A3D&phoneVersion=16&password=A55B48BB75CA18C5F47D6&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&'
cookieJar = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookieJar))
req = urllib2.Request(loginUrl, loginData, headers)
loginResult = opener.open(req).read()
print loginResult
登录成功 会返回一串账号信息的json数据
和抓包时返回数据一样,证明登录成功
3、抓取数据
用同样方法得到话题的url和post参数
做法就和模拟登录网站一样。详见:
下见最终代码,有主页获取和下拉加载更新。可以无限加载话题内容。
#!/usr/local/bin/python2.7
# -*- coding: utf8 -*-
超级课程表话题抓取
import urllib2
from cookielib import CookieJar
import json
''' 读Json数据 '''
def fetch_data(json_data):
data = json_data['data']
timestampLong = data['timestampLong']
messageBO = data['messageBOs']
topicList = []
for each in messageBO:
topicDict = {}
if each.get('content', False):
topicDict['content'] = each['content']
topicDict['schoolName'] = each['schoolName']
topicDict['messageId'] = each['messageId']
topicDict['gender'] = each['studentBO']['gender']
topicDict['time'] = each['issueTime']
print each['schoolName'],each['content']
topicList.append(topicDict)
return timestampLong, topicList
''' 加载更多 '''
def load(timestamp, headers, url):
headers['Content-Length'] = '159'
loadData = 'timestamp=%s&phoneBrand=Meizu&platform=1&genderType=-1&topicId=19&phoneVersion=16&selectType=3&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&' % timestamp
req = urllib2.Request(url, loadData, headers)
loadResult = opener.open(req).read()
loginStatus = json.loads(loadResult).get('status', False)
if loginStatus == 1:
print 'load successful!'
timestamp, topicList = fetch_data(json.loads(loadResult))
load(timestamp, headers, url)
print 'load fail'
print loadResult
return False
loginUrl = 'http://120.55.151.61/V2/StudentSkip/loginCheckV4.action'
topicUrl = 'http://120.55.151.61/V2/Treehole/Message/getMessageByTopicIdV3.action'
headers = {
'Content-Type': 'application/x-www-form- charset=UTF-8',
'User-Agent': 'Dalvik/1.6.0 (L U; Android 4.1.1; M040 Build/JRO03H)',
'Host': '120.55.151.61',
'Connection': 'Keep-Alive',
'Accept-Encoding': 'gzip',
'Content-Length': '207',
''' ---登录部分--- '''
loginData = 'phoneBrand=Meizu&platform=1&deviceCode=494&account=FCF030E1F2FBE5BBC422A3D&phoneVersion=16&password=A55B48BB75CA18C5F47D6&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&'
cookieJar = CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cookieJar))
req = urllib2.Request(loginUrl, loginData, headers)
loginResult = opener.open(req).read()
loginStatus = json.loads(loginResult).get('data', False)
if loginResult:
print 'login successful!'
print 'login fail'
print loginResult
''' ---获取话题--- '''
topicData = 'timestamp=0&phoneBrand=Meizu&platform=1&genderType=-1&topicId=19&phoneVersion=16&selectType=3&channel=MXMarket&phoneModel=M040&versionNumber=7.2.1&'
headers['Content-Length'] = '147'
topicRequest = urllib2.Request(topicUrl, topicData, headers)
topicHtml = opener.open(topicRequest).read()
topicJson = json.loads(topicHtml)
topicStatus = topicJson.get('status', False)
print topicJson
if topicStatus == 1:
print 'fetch topic success!'
timestamp, topicList = fetch_data(topicJson)
load(timestamp, headers, topicUrl)
您可能感兴趣的文章:
大家感兴趣的内容
12345678910
最近更新的内容
常用在线小工具如何在Controller获取以multipart/form-data方式提交表单的参数值_百度知道
如何在Controller获取以multipart/form-data方式提交表单的参数值
我有更好的答案求助知道网友
form里面的method是不是a.com,如果是的话,那说明是正确的。你可以把method修改为a.com?w=a。这样就达到你的要求了。 以上仅供参考!
@RequestMapping(value = &/login&, method = RequestMethod.&a href=&& target=&_blank& class=&baidu-highlight&&GET&/a&)public ModelAndView myMethod(HttpServletRequest request,
HttpServletResponse response, //@RequestParam(&username&)String username, @RequestParam(&password&)String password
String username,String password,//如果和前台的一样一样简写成这样
ModelMap modelMap) throws Exception {
username = new String(username.&a href=&& target=&_blank& class=&baidu-highlight&&get&/a&Bytes(&iso8859-1&),&UTF-8&);//编码问题 (服务器一帮都是iso的)
System.out.println(username+&:&+password);
modelMap.put(&loginUser&, username);
modelMap.put(&msg&, &I'm in session&);
return new ModelAndView(&/view/hello&, modelMap);
}这里是一个方法,springMVC中参数可以直接现在方法的参数列表中,如果是对象属性的话也可以直接使用对象例如(User user,...)刚才的方法对应的前台:&form action=&login&&username:&input name=&username& /&&br&password:&input name=&password& type=&password& /&&br&&input type=&submit& value=&登入& /&&/form&
本回答被提问者采纳
1条折叠回答
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。FF4中增加了一个很有意思的对象,FormData。通常我们提交(使用submit button)时,会把form中的所有表格元素的name与value组成一个queryString,提交到后台。这用jQuery的方法来说,就是 serialize。但当我们使用Ajax提交时,这过程就要变成人工的了。因此,FormData对象的出现可以减少我们一些工作量。W3c草案提供了三种方案来获取或修改FormData。
1:创建一个空的FormData对象,然后再用append方法逐个添加键值对:
var data = new FormData();
data.append('uploadpic', $('#licensefile')[0].files[0]);//可以是文件
data.append('type',"license");
2:取得form元素对象,将它作为参数传入FormData对象中:
var form = document.getElementById("form");
var data= new FormData(form);
3 : 利用form元素对象的getFormData方法生成它:
var form =
document.getElementById("form");
var data= form.getFormData()
formdata是一个不透明的对象,现在暂时只有一个append可以操作,不能通过序列化手段得到其里面的内容。
最终可以将 data = new FormData()获取到的数据丢到ajax的data里面,作为数据传给后台;以下是我用FormData对象上传图片的例子:
html& file域:
&input type="file" id="licensefile" multiple="multiple"&
jquery ajax结合FormData异步上传图片:
$("#licensefile").change(function(){
popLayer.loading();
var data = new FormData();
data.append('uploadpic', $('#licensefile')[0].files[0]);
data.append('type',"license");
type: "post",
url: "fileupload/uploadify!userUploadPhoto.action",
processData: false,
contentType: false,
data: data,
success: function(data){
var _data = data
if (data.errorCode=="000000") {
vm.licenseUrl = data.halfImgU
storage.set("licenseUrl",data.halfImgUrl);
popLayer.destroy();
关于FormData更多的属性和查阅:
参考其他人经验以及部分个人总结,如有侵权,请及时联系本人,QQ:,谢谢
阅读(...) 评论()如何在Controller获取以multipart/form-data方式提交表单的参数值_百度知道
如何在Controller获取以multipart/form-data方式提交表单的参数值
我有更好的答案
form里面的method是不是a.com,如果是的话,那说明是正确的。你可以把method修改为a.com?w=a。这样就达到你的要求了。以上仅供参考!
为您推荐:
其他类似问题
换一换
回答问题,赢新手礼包
个人、企业类
违法有害信息,请在下方选择后提交
色情、暴力
我们会通过消息、邮箱等方式尽快将举报结果通知您。

我要回帖

更多关于 怎么抓取手机封包 的文章

 

随机推荐