Tomcat 11 Multipart -Upload Senden Sie die Anhänge nichtJava

Java-Forum
Anonymous
 Tomcat 11 Multipart -Upload Senden Sie die Anhänge nicht

Post by Anonymous »

Ich habe einen sehr alten PHP-Code, der einen Post-Multipart/Form-Data an einen Tomcat-Server anfordert, und er gibt einen XML String als Teil und eine Datei als Anhang als zweiter Teil.

Code: Select all

function SendTmsNewsToHost($host, $port, $dest_url, $tnixdata, $attachment) {

global $debug, $TMS_LineId;

$mime_boundary = md5(date('r', time()));
if ($port==0) $port = 8080;
$destination = "http://$host:$port/$dest_url";
$eol = "\r\n";

$tmsnews_xml = '--' . $mime_boundary . $eol;
$tmsnews_xml .= 'Content-Disposition: form-data; name="_tnix"' . $eol . 'Content-Type: text/xml' . $eol . $eol;
$tmsnews_xml .= $tnixdata . $eol;
$msg_length = strlen($tmsnews_xml);

$tmsnews_attachment = "";
$fstr="";

if($attachment!='') {

// MIME attachments type recognization, not necessary for DAM
/*
require('mime_type_lib.php');
$mime_type = get_file_mime_type($attachment);
*/
$base_name=basename($attachment);

$fpr = fopen($attachment, "rb");
$fsize=filesize($attachment);
$fstr = fread($fpr, $fsize);
fclose($fpr);

$tmsnews_attachment = '--' . $mime_boundary . $eol;
$tmsnews_attachment .= 'Content-Disposition: attachment; name="attachment"; filename="' . $base_name . '"' . $eol;
$file_length = strlen($fstr);
$tmsnews_attachment .= 'Content-Length: ' . $file_length . $eol;
$tmsnews_attachment .= 'Content-Transfer-Encoding: binary' . $eol . $eol;

// include attachment length
// (Everything coming after the first empty line (\r\n) -- including your boundary delimiters -- should be counted in the total length )
// but not first: + strlen($eol);
$msg_length += strlen($tmsnews_attachment) + $file_length ;
}

$content = $tmsnews_xml . ($attachment!=''? $tmsnews_attachment . $fstr . $eol: '') .  "--$mime_boundary--". $eol . $eol;
$curl = curl_init($destination);
if (is_resource($curl) === true) {

# TODO content-length check
$realContentSize = strlen($content);
$contentSize = ($msg_length+strlen($eol . "--$mime_boundary--". $eol . $eol));
flog(FINFO, "content logging");
flog(FINFO, "content logging $realContentSize ".$realContentSize);
flog(FINFO, "content logging $contentSize ".$contentSize);
flog(FINFO, "content logging");
flog(FINFO, $content);
# TODO content-length check

curl_setopt($curl, CURLOPT_HTTPHEADER, array(
'Content-Type: multipart/form-data; boundary="' . $mime_boundary . '"',
'Host: ' . "$host:$port",
'Content-length: ' . ($msg_length+strlen($eol . "--$mime_boundary--". $eol . $eol)),
'Connection: Close'
));

curl_setopt($curl, CURLOPT_FAILONERROR, true);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_VERBOSE, true);
curl_setopt($curl, CURLOPT_POST, true);

curl_setopt($curl, CURLOPT_POSTFIELDS, $content);

$response = curl_exec($curl);
curl_close($curl);

return $response;
}
Auf der Java -Seite gibt es ein Servlet , das den gesamten Eingabestream von Hand analysiert und die Informationen aus der Nutzlast extrahiert. />
Multipart -Anforderungen waren im Allgemeinen nicht mehr möglich → gelöst durch Einstellen von erlaubigem MultiPartParsing = "True" < /code> Im Tomcat -Kontext der App; Punkt, ich habe versucht, den vorhandenen Code zu überarbeiten, um die von der Servlet-API angebotenen Funktionen zu verwenden, und habe ihn wie folgt überarbeitet: < /p>

Code: Select all

// Already existing code
public MultipartFormData(final HttpServletRequest request, final long byteLimit) throws IOException {

String contentType = getContentType(request);
if (contentType == null || !contentType.equalsIgnoreCase(CONTENT_TYPE)) {
throw new IllegalArgumentException("invalid content type: " + contentType);
}

if (getBoundary(request) == null) {
throw new IllegalArgumentException("missing boundary");
}

try {
initFromStream(request, byteLimit);
} finally {
close();
}
}

// Already existing code
@Override
public void close() {
Enumeration fields = getFileFormFields();
while (fields.hasMoreElements()) {
String field = fields.nextElement();
String[] localPaths = getLocalPathValues(field);

for (String localPath : localPaths) new File(localPath).delete();
}

fileInfos_.clear();
}

// Already existing code
private String getContentType(final HttpServletRequest request) {
String contentType = request.getContentType();
if (contentType == null) {
return null;
}

int semiColonIndex = contentType.indexOf(';');
if (semiColonIndex == -1) {
return contentType;
}

return contentType.substring(0, semiColonIndex);
}

// Already existing code
private byte[] getBoundary(final HttpServletRequest request) {
String contentType = request.getContentType();
if (contentType == null) {
return null;
}

int boundaryIndex = contentType.toLowerCase().indexOf("boundary");
if (boundaryIndex == -1) {
return null;
}

int startIndex = boundaryIndex + 9;

// fix : gequotete boundaries auch akzeptieren
char delimiter = ';';
if ((contentType.length() > startIndex)
&& (contentType.charAt(startIndex) == '"')) {
startIndex++;
delimiter = '"';
}
int endIndex = startIndex;
for (int i = startIndex; i < contentType.length()
&& contentType.charAt(i) != delimiter; ++i) {
++endIndex;
}

return contentType.substring(startIndex, endIndex).getBytes();
}

// Refactored code
private void initFromStream(final HttpServletRequest input, final long byteLimit) throws IOException {
long requestSize = input.getContentLengthLong();
if (requestSize == -1) {
try {
requestSize = input.getParts().stream().mapToLong(Part::getSize).sum();
} catch (ServletException e) {
throw new IOException(e);
}
}
if (requestSize > byteLimit) throw new ByteLimitExceededException("byte limit exceeded: " + byteLimit);

readParts(input);
}

// Already existing code
private void addParameter(final String name, final String value) {
List  values = parameters_.get(name);
if (values == null) {
values = new LinkedList();
}

values.add(value);

parameters_.put(name, values);
}

// Refactored code
private void readParts(final HttpServletRequest input) throws IOException {
try {
for (Part part : input.getParts()) {
if (part.getSubmittedFileName() == null) {
addParameter(part.getName(), readValue(part));
} else {
addFileInfo(part.getName(), new FileInfo(readData(part), part.getSubmittedFileName(), part.getContentType()));
}
}
} catch (ServletException ex) {
throw new IOException(ex);
}
}

// Refactored code
private String readValue(Part part) throws IOException {
StringBuilder builder = new StringBuilder();
try (BufferedReader reader = new BufferedReader(new InputStreamReader(part.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) builder.append(line).append(lineSeparator());
}

return builder.toString().strip();
}

// Refactored code
private String readData(Part part) throws IOException {
File file = File.createTempFile("multipartdatabean", null);
file.deleteOnExit();

try (BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(file));
BufferedInputStream in = new BufferedInputStream(part.getInputStream())) {
byte[] buffer = new byte[8192];
int bytesRead;
while ((bytesRead = in.read(buffer)) != -1) {
out.write(buffer, 0, bytesRead);
}
}
return file.getPath();
}

// Already existing code
private void addFileInfo(final String name, final FileInfo info) {
List infos = fileInfos_.get(name);
if (infos == null) {
infos = new LinkedList();
}

infos.add(info);

fileInfos_.put(name, infos);
}
< /code>
Ergebnis: Keine Fehler mehr, aber nur der XML wird tatsächlich verarbeitet. Der Anhang ist einfach verloren.
NewsQueryService
foo.NSPortal

log4j-init-file
WEB-INF/etc/log4j.properties


log4j-read-intervall
10000

1

/home/nsc/tmp
104857600
418018841
10485760


Aber ich habe das gleiche Ergebnis erhalten. />

Code: Select all

multipart
org.springframework.web.multipart.support.MultipartFilter


multipart
NewsQueryService

< /code>
und überarbeitete die obige Implementierung wie folgt: < /p>
public MultipartFormData(final HttpServletRequest request, final long byteLimit) throws IOException {
if(!(request instanceof MultipartHttpServletRequest multipartRequest)) throw new IllegalArgumentException("Not a multipart request");

long totalFileSizeBytes = 0;
for(Entry file : multipartRequest.getFileMap().entrySet()) {
MultipartFile multipartFile = file.getValue();
totalFileSizeBytes += multipartFile.getSize();
if (totalFileSizeBytes > byteLimit) throw new ByteLimitExceededException("byte limits exceeded");

File osFile = multipartFile.getResource().getFile();
addFileInfo(file.getKey(), new FileInfo(osFile.getPath(), osFile.getName(), multipartFile.getContentType()));
}
Enumeration parameterNames = multipartRequest.getParameterNames();
while (parameterNames.hasMoreElements()) {
String parameterName = parameterNames.nextElement();
String[] parameterValues = multipartRequest.getParameterValues(parameterName);
for (String value : parameterValues) {
addParameter(parameterName, value);
}
}
}
< /code>
Aber ich habe noch einmal das gleiche Ergebnis erhalten.public MultipartFormData(final HttpServletRequest request, final long byteLimit) throws IOException {
try {
long totalFileSizeBytes = 0;
for(Part part : request.getParts()) {
totalFileSizeBytes += part.getSize();
if (totalFileSizeBytes > byteLimit) throw new ByteLimitExceededException("byte limits exceeded");

String headerValue = part.getHeader(CONTENT_DISPOSITION);
ContentDisposition disposition = parse(headerValue);
String filename = disposition.getFilename();
if (filename == null) {
addParameter(part.getName(), readValue(part));
} else {
addFileInfo(part.getName(), new FileInfo(readData(part), filename, part.getContentType()));
}
part.delete();
}
} catch (ServletException ex) {
throw new IOException(ex);
}
}
Aber auch dies hat am Ende das gleiche Ergebnis erbracht.
Hat jemand eine Idee?

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post