这样的form:<form method='post' enctype='multipart/form-data' action='...'> 在提

  • 主题发起人 主题发起人 Sterntaler
  • 开始时间 开始时间
S

Sterntaler

Unregistered / Unconfirmed
GUEST, unregistred user!
这样的form:<form method='post' enctype='multipart/form-data' action='...'> 在提交后,(100分)<br />提交的后,通过 request.getParamenter() 获取不到form中的各种 input 等参数。
大家是怎么解决这个问题的?我英文水平不行,看不了rfc1867。
 
request.getParamenter() 好像是不会得到form的参数吧。可以得到的参数为
*.jsp?id=1 的参数。具体的查查。
 
因为你的enctype类型的定义的问题呀
你把enctype='multipart/form-data'去掉就可以用request.getParamenter()获取form中的各种 input 等参数
---------------
enctype="multipart/form-data"
这种方式是把from里的内容以流的形式提交 你用 request.getParamenter()是得不到的
 
7syw: 这个知道,但是form中还有 <input type='file' ..,我需要这样。
 
用多个form包含input
 
我用 ServletInputStream 分析了post传来的数据,但是总觉得应该有简单的方法。
 
因为我还没有办法区分普通域内容和文件的内容。
 
-----------------------------7d39c252b01ea Content-Disposition: form-data;
name="id" Fri Nov 07 18:36:30 CST 2003 -----------------------------7d39c252b01ea Content-Disposition: form-data;
name="upfile";
filename="D:/way2.txt" Content-Type: text/plain Are 你好! -----------------------------7d39c252b01ea--
怎么分析这些内容?有方法避免分析就最好。
应该考虑locka 的提议了...用一个form专门来存放一个file?
 
Public Sub GetData (MaxSize)
'定义变量
Dim RequestBinDate,sSpace,bCrLf,sInfo,iInfoStart,iInfoEnd,tStream,iStart,oFileInfo
Dim iFileSize,sFilePath,sFileType,sFormValue,sFileName
Dim iFindStart,iFindEnd
Dim iFormStart,iFormEnd,sFormName
'代码开始
If Request.TotalBytes < 1 then
'如果没有数据上传
Err = 1
Exit Sub
End If
If MaxSize > 0 then
'如果限制大小
If Request.TotalBytes > MaxSize then
Err = 2 '如果上传的数据超出限制
Exit Sub
End If
End If
Set Form = Server.CreateObject ("Scripting.Dictionary")
Form.CompareMode = 1
Set File = Server.CreateObject ("Scripting.Dictionary")
File.CompareMode = 1
Set tStream = Server.CreateObject ("ADODB.Stream")
Set oUpFileStream = Server.CreateObject ("ADODB.Stream")
oUpFileStream.Type = 1
oUpFileStream.Mode = 3
oUpFileStream.Open
oUpFileStream.Write Request.BinaryRead (Request.TotalBytes)
oUpFileStream.Position = 0
RequestBinDate = oUpFileStream.Read
iFormEnd = oUpFileStream.Size
bCrLf = ChrB (13) &amp;
ChrB (10)
'取得每个项目之间的分隔符
sSpace = MidB (RequestBinDate,1, InStrB (1,RequestBinDate,bCrLf)-1)
iStart = LenB (sSpace)
iFormStart = iStart+2
'分解项目
do
iInfoEnd = InStrB (iFormStart,RequestBinDate,bCrLf &amp;
bCrLf)+3
tStream.Type = 1
tStream.Mode = 3
tStream.Open
oUpFileStream.Position = iFormStart
oUpFileStream.CopyTo tStream,iInfoEnd-iFormStart
tStream.Position = 0
tStream.Type = 2
tStream.CharSet = "gb2312"
sInfo = tStream.ReadText
'取得表单项目名称
iFormStart = InStrB (iInfoEnd,RequestBinDate,sSpace)-1
iFindStart = InStr (22,sInfo,"name=""",1)+6
iFindEnd = InStr (iFindStart,sInfo,"""",1)
sFormName = Mid (sinfo,iFindStart,iFindEnd-iFindStart)
'如果是文件
If InStr (45,sInfo,"filename=""",1) > 0 then
Set oFileInfo = new FileInfo_Class
'取得文件属性
iFindStart = InStr (iFindEnd,sInfo,"filename=""",1)+10
iFindEnd = InStr (iFindStart,sInfo,"""",1)
sFileName = Mid (sinfo,iFindStart,iFindEnd-iFindStart)
oFileInfo.FileName = Mid (sFileName,InStrRev (sFileName, "/")+1)
oFileInfo.FilePath = Left (sFileName,InStrRev (sFileName, "/"))
oFileInfo.FileExt = Mid (sFileName,InStrRev (sFileName, ".")+1)
iFindStart = InStr (iFindEnd,sInfo,"Content-Type: ",1)+14
iFindEnd = InStr (iFindStart,sInfo,vbCr)
oFileInfo.FileType = Mid (sinfo,iFindStart,iFindEnd-iFindStart)
oFileInfo.FileStart = iInfoEnd
oFileInfo.FileSize = iFormStart -iInfoEnd -2
oFileInfo.FormName = sFormName
file.add sFormName,oFileInfo
else
'如果是表单项目
tStream.Close
tStream.Type = 1
tStream.Mode = 3
tStream.Open
oUpFileStream.Position = iInfoEnd
oUpFileStream.CopyTo tStream,iFormStart-iInfoEnd-2
tStream.Position = 0
tStream.Type = 2
tStream.CharSet = "gb2312"
sFormValue = tStream.ReadText
If Form.Exists (sFormName) then
Form (sFormName) = Form (sFormName) &amp;
", " &amp;
sFormValue
else
form.Add sFormName,sFormValue
End If
End If
tStream.Close
iFormStart = iFormStart+iStart+2
'如果到文件尾了就退出
Loop Until (iFormStart+2) >= iFormEnd
RequestBinDate = ""
Set tStream = Nothing
End Sub
End Class
 
-----------------------------7d39c252b01ea Content-Disposition: form-data;
name="id" Fri Nov 07 18:36:30 CST 2003 -----------------------------7d39c252b01ea Content-Disposition: form-data;
name="upfile";
filename="D:/way2.txt" Content-Type: text/plain Are 你好! -----------------------------7d39c252b01ea--
这里不是已经有了吗???当字符串来处理呀 读到7d39c252b01ea Content-Disposition 然后读 name 在读filename
 
我正在写了个字符串工具,但是还不好用。而且我想这样把所有内容先读到一个StringBuffer占用资源太多。临时文件的话操作困难,java有没有FileMapping?
我目前遇到的问题是,在getParameter方法里面,indexOf() 返回的总是-1,但是我把内容输出到页面之后,再做测试却能正确。大家帮我瞧他一眼吧,非常感激就是了。
package common.tools;
import java.io.RandomAccessFile;
import java.text.MessageFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletInputStream;
public class MultiPartParser{
final static String UPLOAD_PATH = "/jakarta-tomcat-4.1.18/webapps/ROOT/upload_files/";
final static String PART_DELIMITER = "-----------------------------7d39c252b01ea";
final static String FORM_DATA = "Content-Disposition: form-data;";

HttpServletRequest m_Request = null;
StringBuffer m_RequestData = null;
String m_Delimiter = null;
boolean m_OK = false;

public MultiPartParser(HttpServletRequest request){
this.m_Request = request;
m_OK = initParser();
}

boolean initParser(){
ServletInputStream in = null;
try {
in = m_Request.getInputStream();
m_RequestData = new StringBuffer();
byte[] buf = new byte[64 * 1024];
while (in.read(buf) > 0) m_RequestData.append(new String(buf));
buf = null;
in.close();
in = null;

m_Delimiter = m_RequestData.substring(0, PART_DELIMITER.length());
return true;
} catch (Exception e){ m_Request = null;
return false;
}
}

public boolean isInit(){
return m_OK;
}

public String getParamNameFormat(String paramName){
if (!isInit()) return null;

try {
String[] args = {m_Delimiter, FORM_DATA, paramName};
return new MessageFormat("{0} {1} name=/"{2}/"").format(args);
} catch (Exception e){ return null;
}
}


public String getFileNameFormat(String fname){
if (!isInit()) return null;

try {
String[] args = {fname};
return new MessageFormat(";
filename=/"{0}/"").format(args);
} catch (Exception e){ return null;
}
}


public String getFileName(String paramName){
if (!isInit()) return null;
if (!isFileData(paramName)) return null;

String strParamNameFormat = getParamNameFormat(paramName);
int start = m_RequestData.indexOf(strParamNameFormat) + strParamNameFormat.length() + ";filename=/"".length();
int end = m_RequestData.indexOf("/"", start);
return m_RequestData.substring(start, end);
}

public String getParameter(String paramName){
if (!isInit()) return null;

if (isFileData(paramName)) return null;

String strParamNameFormat = getParamNameFormat(paramName);
int start = m_RequestData.indexOf(strParamNameFormat) + strParamNameFormat.length() + 1;
if (start < strParamNameFormat.length() + 1) return null;

int end = m_RequestData.indexOf(m_Delimiter, start) - 1;
if (end < 0) end = m_RequestData.length();
return m_RequestData.substring(start, end);
}

/** 判断是否是文件数据 */
public boolean isFileData(String paramName){
if (!isInit()) return false;

String strParamNameFormat = getParamNameFormat(paramName);
int idx = m_RequestData.indexOf(strParamNameFormat);
return m_RequestData.charAt(idx + strParamNameFormat.length()) == ';';
}

/** 修改文本文件内容 */
public boolean setFileContent(String fname, String content){
if (!isInit()) return false;

RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(fname, "rw");
raf.setLength(0);
raf.writeBytes(content);
raf.close();
raf = null;
return true;
} catch (Exception e){ return false;
}
}
public boolean upLoad(String paramName){
if (!isInit()) return false;

if (!isFileData(paramName)) return false;

String fname = getFileName(paramName);
String strParamNameFormat = getParamNameFormat(paramName);
String strFileNameFormat = getFileNameFormat(fname);
int start = m_RequestData.indexOf(strParamNameFormat) +
strParamNameFormat.length() +
strFileNameFormat.length() + 1;
int end = m_RequestData.indexOf(PART_DELIMITER, start) - 1;
if (end < 0) end = m_RequestData.length();

return setFileContent(UPLOAD_PATH + fname, m_RequestData.substring(start, end));
}

public static void main(String[] args){
}
}
 
谢谢leeeeleeee
 
调试时发现,原来是把回车当成空格了。
把 getParamNameFormat 方法里面的
return new MessageFormat("{0} {1} name=/"{2}/"").format(args);
改为 return new MessageFormat("{0}/n{1} name=/"{2}/"").format(args);
getParameter() 方法就能用了。
 
方法 initParser() 中
初始化缓冲区的地方也不对,应该是
int nRead = 0;
while ((nRead = in.read(buf)) > 0) m_RequestData.append(new String(buf, 0, nRead));
 
对不起,错误太多了,还没有调试完。
 
改了很多,还是重新贴上来吧。现在的问题是,有时能正确获取参数,有时不能(返回null)。但是文件却一直是内容不对,少量文本的时候还差不多,大文件的话,速度很慢别说,而且文件内容缺漏。不知道是不是因为 new String 这样的转换的缘故。哪位大侠再仗义仗义吧。
package common.tools;
import java.io.RandomAccessFile;
import java.text.MessageFormat;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.ServletInputStream;
public class MultiPartParser{
final static String LOG_PATH = "d://";
final static String UPLOAD_PATH = "e://";
final static String PART_DELIMITER = "-----------------------------7d39c252b01ea";
final static String FORM_DATA = "Content-Disposition: form-data;";

HttpServletRequest m_Request = null;
public StringBuffer m_RequestData = null;
String m_Delimiter = null;
boolean m_OK = false;

public MultiPartParser(HttpServletRequest request){
this.m_Request = request;
m_OK = initParser();
}

boolean initParser(){
ServletInputStream in = null;
try {
in = m_Request.getInputStream();
m_RequestData = new StringBuffer();
byte[] buf = new byte[64 * 1024];
int nRead = 0;
while ((nRead = in.read(buf)) > 0) m_RequestData.append(new String(buf, 0, nRead));
buf = null;
in.close();
in = null;

m_Delimiter = m_RequestData.substring(0, PART_DELIMITER.length());
return true;
} catch (Exception e){ m_Request = null;
return false;
}
}

public boolean isInit(){
return m_OK;
}

String getParamNameFormat(String paramName){
if (!isInit()) return null;

try {
String[] args = {m_Delimiter, FORM_DATA, paramName};
return new MessageFormat("{0}/n{1} name=/"{2}/"").format(args);
} catch (Exception e){ return null;
}
}

/** 返回格式化(根据上传的数据格式定的)的文件名 */
String getFileNameFormat(String fname){
if (!isInit()) return null;

try {
String[] args = {fname};
return new MessageFormat(";
filename=/"{0}/"").format(args);
} catch (Exception e){ return null;
}
}

/** 返回file上传的文件名 */
String getFullFileName(String paramName){
if (!isInit()) return null;
if (!isFileData(paramName)) return null;

String strParamNameFormat = getParamNameFormat(paramName);
int start = m_RequestData.indexOf(strParamNameFormat) + strParamNameFormat.length() + ";filename=/"".length() + 1;
int end = m_RequestData.indexOf("/"", start);
return m_RequestData.substring(start, end);
}

/** 返回表单数据 */
public String getParameter(String paramName){
if (!isInit()) return null;

if (isFileData(paramName)) return null;

String strParamNameFormat = getParamNameFormat(paramName);
int start = m_RequestData.indexOf(strParamNameFormat);
if (start == -1) return null;
start += strParamNameFormat.length() + 2;

int end = m_RequestData.indexOf(m_Delimiter, start) - 1;
if (end < 0) end = m_RequestData.length();
return m_RequestData.substring(start, end);
}

/** 判断是否是文件数据 */
public boolean isFileData(String paramName){
if (!isInit()) return false;

String strParamNameFormat = getParamNameFormat(paramName);
int idx = m_RequestData.indexOf(strParamNameFormat);
if (idx == -1) return false;
return m_RequestData.charAt(idx + strParamNameFormat.length()) == ';';
}

/** 修改文本文件内容 */
boolean setFileContent(String fname, String content){
if (!isInit()) return false;

RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(fname, "rw");
raf.setLength(0);
raf.writeBytes(content);
raf.close();
raf = null;
return true;
} catch (Exception e){ return false;
}
}

boolean logMsg(String msg){
return log(LOG_PATH + "log.txt", msg);
}
boolean log(String fname, String msg){
RandomAccessFile raf = null;
try {
raf = new RandomAccessFile(fname, "rw");
raf.seek(raf.length());
raf.writeBytes(msg);
raf.close();
raf = null;
return true;
} catch (Exception e){ return false;
}
}
/** 执行文件上传,保存到UPLOAD_PATH */
public boolean upLoadGB(String paramName){
if (!isInit()) return false;

if (!isFileData(paramName)) return false;

String fname = getFullFileName(paramName);
String strParamNameFormat = getParamNameFormat(paramName);
String strFileNameFormat = getFileNameFormat(fname);
int start = m_RequestData.indexOf(strParamNameFormat);
if (start == -1) return false;

// 分明是两个回车,为何"/n/n"不行,"/uDADA"也不行!
start = m_RequestData.indexOf("Content-Type:", start);
start = m_RequestData.indexOf("/n", start) + "/n/n/n".length();
// ??

int end = m_RequestData.indexOf(PART_DELIMITER, start);
if (end == -1) end = m_RequestData.length() - m_Delimiter.length() - "---/n".length();

return setFileContent(UPLOAD_PATH + getFileName(fname), GBToISO(m_RequestData.substring(start, end)));
}

/** 好像无效果 */
public void close(){
m_RequestData = null;
m_Request = null;
}

String getFileName(String fname){
if (fname == null) return null;

int idx = fname.lastIndexOf("//");
if (idx == -1) idx = fname.lastIndexOf("/");

if (idx == -1) return fname;
else
return fname.substring(idx + 1);
}

String GBToISO(String gb){
try {
return new String(gb.getBytes("GB2312"), "ISO-8859-1");
} catch (Exception e){ return gb;
}
}

public static void main(String[] args){
}
}
 
原来是个回车换行的问题!把 /n 改为 /r/n 就好了。我竟然花了2小时调试才找到原因。但我不明白为何 /u0d0a 也不行。更不明白,以前怎么会有时成功。
 
55,现在还是会有时失败(跟以前的有时成功相比,成功几率大了一点)。为何我写的日志文件中,getParamNameFormat() 返回的有时是 /x0d/x0a(正确),有时是 /x0d/x0a/x0d/x0a(错误),还有时是 /x0d/x0d/x0a(错误)?真的搞不懂。
大家说句话啊。
 
搜到一个SmartUpload,能满足需要了。
还是先把功能实现了,以后有空再来。怎么又结不了帖了。
 
com.jspsmart.upload.SmartUpload 也是一个 parser。
比我的强多了。这个问题算是解决了。谢谢来帮忙的各位。
 
后退
顶部