Thanks for your reply.
I have looked the links below and I tried what it says:
The form:
<form id="myform" action="nodecorate/myaction.action"
enctype="multipart/form-data" method="post">
<s:file name="myfile"></s:file>
<input type="button" onclick="sendIt(); return false;">
</form>
The javascript:
function sendIt(){
var bindArgs = {
transport: "IframeTransport",
formNode: document.getElementById("myform"),
mimetype: "text/html",
load: function(type, data, evt){
document.getElementById("mydiv").innerHTML =
data.firstChild.innerHTML;
}
};
var request = dojo.io.bind(bindArgs);
}
The div with id 'mydiv' will then get updated with the response from the
action.
Well, my form looks like this:
<s:form id="addPluginForm" name="addPluginForm" theme="simple"
action="AddPlugin" enctype="multipart/form-data" method="post">
<div class="field">
<span class="label">
<fmt:message key="PluginsTable.File"/>*:
</span>
<span class="entry">
<s:file name="upload" size="40"
accept="application/java-archive"/>
<span id="errorId" class="errorMessage">
<s:property value="fieldErrors['upload'][0]" />
</span>
<span id="errorId" class="errorMessage">
<s:property value="fieldErrors['uploadContentType'][0]" />
</span>
</span>
</div>
<!-- BOTONES -->
<div class="button">
<span class="buttonLeft">
<s:submit type="button"
onclick="sendMultiPartForm('addPluginForm', 'configAjaxContent'); return false;"
cssClass="submit">
<s:param name="value">
<fmt:message key="Buttons.accept"/>
</s:param>
</s:submit>
</span>
<span class="buttonRight">
<!-- cancelar -->
<s:url id="CancelUrl" action="CancelConfiguration"/>
<s:submit type="button" theme="ajax" targets="configAjaxContent"
showLoadingText="false" cssClass="reset" href="${CancelUrl}">
<s:param name="value">
<fmt:message key="Buttons.cancel"/>
</s:param>
</s:submit>
</span>
</div>
</s:form>
and my Javascript:
function sendMultiPartForm(formId, targetId) {
dojo.require("dojo.io.IframeIO");
var bindArgs = {
transport: "IframeTransport",
formNode: document.getElementById(formId),
mimetype: "text/html",
load: function(type, data, evt) {
document.getElementById(targetId).innerHTML =
data.firstChild.innerHTML;
}
};
var request = dojo.io.bind(bindArgs);
}
Unfortunately, it is happening the same than before: the file is uploaded but my target div is not being updated with the action's response content.
And, as before, if I want to upload another file, I must go first to another action and then, return to this one; if not, it doesn't work...
Am I missing sth? Doing sth wrong?
Jeromy Evans escribió:
hmm...that's interesting.
My approach would be to create a new blank struts application that
just contains a file upload action. Get it to work without ajax as
there still seems to be a configuration problem.
Then, when you're satisfied the configuration is correct...
unfortunately you can't use s:form theme=ajax to perform a multi-part
upload in Struts2.0. To perform an asynchronous upload, you'll have
to use Dojo's IFrameIO feature directly. I haven't used it myself,
but it's described in the following two posts:
http://www.mail-archive.com/user@struts.apache.org/msg60245.html
http://www.nabble.com/Image-Upload-and-Dojo-td14350527.html
I hope that helps!
Pablo Vázquez Blázquez wrote:
Error de lectura XML: contenido incorrecto tras un elemento XML del
documento
Ubicación: http://localhost:8080/scheduler-admintool-1.0/AddPlugin.do
Número de línea 8, columna 1:<form id="addPluginForm"
name="addPluginForm" onsubmit="return true;"
action="/scheduler-admintool-1.0/AddPlugin.do" method="post"
enctype="multipart/form-data">
^
That´s the result if I try without the ajax theme on the form.
Yes, I would like to use the ajax theme.
Thanks.
Jeromy Evans escribió:
Are you deliberately trying to do an XHR file upload? Have you tried
it without the ajax theme on the form?
Pablo Vázquez Blázquez wrote:
Yes yes, that debugging statement is executed. That´s why I know my
plugin is created.
"Anadido plugin " + uploadFileName means "Added plugin " +
uploadFileName.
And then, it goes to ShowPlugins and the debugging statement
log.debug("Obtenidos plugins"); (Getted all plugins) is also executed.
Cheng Wei Lee escribió:
Was this debugging statement executed?
log.debug("Anadido plugin " + uploadFileName);
On Jan 18, 2008 12:13 AM, Pablo Vázquez Blázquez
<[EMAIL PROTECTED]>
wrote:
Here I send you my JSP and Action code.
Yes, when I submit, the new plugin is added (I know it because of my
logs), but I don´t know why I don´t get the result page.
Thank you.
PD: I have now tried without struts.multipart.parser, but it
doesn´t work.
****** JSP ******
<jsp:root xmlns="http://www.w3.org/1999/xhtml"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:fmt="http://java.sun.com/jsp/jstl/fmt"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:s="/struts-tags"
version="2.0">
<!-- Tabla con los plugins. Si no hay ninguno, se muestra un
mensaje
-->
<table class="pluginsTable" cellspacing="0px" cellpadding="3px"
border="1px">
<tbody>
<tr>
<td class="tableTitle" colspan="5">
<fmt:message key="PluginsTable.Title"/>
</td>
</tr>
<tr>
<td class="tableHeader">
<fmt:message key="PluginsTable.Name"/>
</td>
<td class="tableHeader">
<fmt:message key="PluginsTable.JarFile"/>
</td>
<td class="tableHeader">
<fmt:message key="PluginsTable.PluginClass"/>
</td>
<td class="tableHeader">
<fmt:message key="PluginsTable.Type"/>
</td>
<td class="tableHeader">
<fmt:message key="PluginsTable.Actions"/>
</td>
</tr>
<c:if test="${empty plugins}">
<tr>
<td class="tableMessage" colspan="5">
<fmt:message key="PluginsTable.NoPlugins"/>
</td>
</tr>
</c:if>
<c:forEach items="${plugins}" var="plugin"
varStatus="status">
<!-- stuff -->
</c:forEach>
</tbody>
</table>
<!-- Form to add plugin -->
<s:form id="addPluginForm" name="addPluginForm" theme="ajax"
action="AddPlugin" enctype="multipart/form-data"
method="post">
<div class="field">
<span class="label">
<fmt:message key="PluginsTable.File"/>*:
</span>
<span class="entry">
<s:file name="upload" size="40"
accept="application/java-archive"/>
<span id="errorId" class="errorMessage">
<s:property value="fieldErrors['upload'][0]" />
</span>
<span id="errorId" class="errorMessage">
<s:property
value="fieldErrors['uploadContentType'][0]"
/>
</span>
</span>
</div>
<!-- BOTONES -->
<jsp:directive.include file="FormButtons.jspf"/>
</s:form>
</jsp:root>
****** FORMBUTTONS.JSPF****
<!-- BUTTONS-->
<div class="button">
<span class="buttonLeft">
<s:submit type="button"
targets="configAjaxContent" executeScripts="true"
showLoadingText="false" indicator="indicator"
cssClass="submit">
<s:param name="value">
<fmt:message key="Buttons.accept"/>
</s:param>
</s:submit>
</span>
<span class="buttonRight">
<!-- cancelar -->
<s:url id="CancelUrl" action="CancelConfiguration"/>
<s:submit type="button" targets="configAjaxContent"
showLoadingText="false" cssClass="reset"
href="${CancelUrl}">
<s:param name="value">
<fmt:message key="Buttons.cancel"/>
</s:param>
</s:submit>
</span>
</div>
*****ACTION *****
public class AddPluginAction extends DefaultRequestResponseAction {
private static final long serialVersionUID =
1516786859681901796L;
/**
* Logger for this class
*/
private static final Log log =
LogFactory.getLog(AddPluginAction.class
);
private File upload;
private String uploadContentType;
private String uploadFileName;
@Override
protected String doExecute() throws Exception {
clearErrorsAndMessages();
Context context =
SessionManager.getRemoteServerContext(getRequest());
SchedulerManager facade =
SessionManager.getUserFacadeDelegate(getRequest(),
context);
try {
byte[] filedata = readInputStream(new
FileInputStream(upload));
facade.addPlugin(uploadFileName, filedata);
log.debug("Anadido plugin " + uploadFileName);
} catch (ConnectException e) {
log.error(e);
throw new InternalErrorException(e);
} catch (DuplicateInstanceException e) {
log.error(e);
addFieldError("upload",
getText("PluginsTable.File.Duplicate"));
} catch (FileNotFoundException e) {
log.error(e);
addFieldError("upload",
getText("PluginsTable.File.NotFound"));
} catch (Exception e) {
log.error(e);
addFieldError("uploadContentType",
getText("ErrorMessages.file.incorrectExtension"));
}
if (hasErrors()) {
return Action.INPUT;
}
return Action.SUCCESS;
}
/*
* Read an input stream in its entirety into a byte array
*/
private static byte[] readInputStream(InputStream inputStream)
throws IOException {
....
return content;
}
/**
* Getters/Setters
* @return
*/
public File getUpload() {
return upload;
}
public void setUpload(File upload) {
this.upload = upload;
}
public String getUploadContentType() {
return uploadContentType;
}
public void setUploadContentType(String uploadContentType) {
this.uploadContentType = uploadContentType;
}
public String getUploadFileName() {
return uploadFileName;
}
public void setUploadFileName(String uploadFileName) {
this.uploadFileName = uploadFileName;
}
}
Dave Newton escribió:
--- Pablo Vázquez Blázquez <[EMAIL PROTECTED]> wrote:
I send you my struts-config.xml file, but it works ok. If I
delete my
"s:file" from my form, everything works fine.
The error happens after you submit, correct?
I guess I'd want to see the JSP and the action code, then; the
configuration
seems okay.
Have you tried it without setting the "struts.multipart.parser"
constant? The
default value of that is "jakarta", not a classname; it's worth
a shot,
anyway.
d.
To see the action involved search: <!-- HERE IS THE PROBLEM -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration
2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<constant name="struts.enable.DynamicMethodInvocation"
value="false" />
<constant name="struts.devMode" value="true" /> <!-- TODO:
cambiar
a
false en produccion -->
<constant name="struts.action.extension" value="do"/>
<constant name="struts.ui.theme" value="simple"/>
<constant name="struts.multipart.parser"
value="org.apache.struts2.dispatcher.multipart.JakartaMultiPartRequest
"/>
<!-- Internacionalizacion para los tags de struts 2 -->
<constant name="struts.custom.i18n.resources"
value="admintool.http.view.messages.Messages"/>
<include file="struts-default.xml"/>
<!-- ===== Paquetes ===== -->
<package name="scheduler" extends="struts-default">
<!-- ===== Resultados globales ===== -->
<result-types>
<result-type name="tiles"
class="org.apache.struts2.views.tiles.TilesResult"/>
</result-types>
<!-- ===== Interceptors ===== -->
<interceptors>
<interceptor name="session"
class="admintool.http.controller.interceptors.SessionInterceptor"
/>
<interceptor name="login"
class="admintool.http.controller.interceptors.AuthenticationInterceptor"
/>
<interceptor-stack name="defaultLoginStack">
<interceptor-ref name="exception" />
<interceptor-ref name="alias" />
<interceptor-ref name="servlet-config" />
<interceptor-ref name="session" />
<interceptor-ref name="login" />
<interceptor-ref name="prepare" />
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain" />
<interceptor-ref name="model-driven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="static-params" />
<interceptor-ref name="params" />
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" />
<interceptor-ref name="workflow" />
</interceptor-stack>
<interceptor-stack name="defaultInsecureStack">
<interceptor-ref name="exception" />
<interceptor-ref name="alias" />
<interceptor-ref name="servlet-config" />
<interceptor-ref name="session" />
<interceptor-ref name="prepare" />
<interceptor-ref name="i18n"/>
<interceptor-ref name="chain" />
<interceptor-ref name="model-driven" />
<interceptor-ref name="fileUpload" />
<interceptor-ref name="static-params" />
<interceptor-ref name="params" />
<interceptor-ref name="conversionError" />
<interceptor-ref name="validation" />
<interceptor-ref name="workflow" />
</interceptor-stack>
<!-- Sample file upload stack -->
<interceptor-stack name="fileUploadStack">
<interceptor-ref name="fileUpload"/>
<interceptor-ref name="basicStack"/>
</interceptor-stack>
</interceptors>
<!--
Make the defaultLoginStack the default one used
for all actions unless otherwise configured.
-->
<default-interceptor-ref name="defaultLoginStack" />
<!-- ===== Resultados globales ===== -->
<!-- se corresponden con los valores por defecto
devueltos por
Action (ej: error, login) -->
<global-results>
<result name="login"
type="redirect-action">ShowAuthentication</result>
<result name="MainPage"
type="redirect-action">Workspace</result>
<result
name="error">/HTML/tiles/base/InternalError.jspx</result>
<result
name="exito">/HTML/tiles/base/SuccessPage.jspx</result>
</global-results>
<!-- ===== Secciones principales ===== -->
<action name="Workspace">
<result type="tiles">.Workspace</result>
</action>
<action name="Scheduler">
<result type="tiles">.Scheduler</result>
</action>
<action name="Configuration">
<result type="tiles">.Configuration</result>
</action>
<!-- ===== Autenticacion ===== -->
<!-- Accion que muestra el formulario de autenticacion -->
<action name="ShowAuthentication"
class="admintool.http.controller.actions.users.ShowAuthenticationAction
">
<interceptor-ref name="defaultInsecureStack"/>
<result type="tiles">.Login</result>
</action>
<!-- Ejecuta la accion de login. Si hay fallos, vuelve
a la
misma pagina -->
<action name="Login"
class="admintool.http.controller.actions.users.LoginAction">
<interceptor-ref name="defaultInsecureStack"/>
<result name="input" type="tiles">.Login</result>
</action>
<!-- Cierra la sesion y vuelve a la pagina de login -->
<action name="Logout"
class="admintool.http.controller.actions.users.LogoutAction">
<interceptor-ref name="defaultInsecureStack"/>
</action>
<!-- ===== Configuration ===== -->
<action name="CancelConfiguration">
<result>/HTML/tiles/configuration/ConnectionInfo.jspx</result>
</action>
<action name="ShowChangePassword">
<result>/HTML/tiles/configuration/ChangePassword.jspx</result>
</action>
<action name="ChangePassword"
class="
admintool.http.controller.actions.configuration.ChangePasswordAction">
<result
name="input">/HTML/tiles/configuration/ChangePassword.jspx</result>
</action>
<action name="ShowChangeServer">
<result>/HTML/tiles/configuration/ChangeServer.jspx</result>
</action>
<action name="ChangeServer"
class="
admintool.http.controller.actions.configuration.ChangeServerAction">
<result
name="input">/HTML/tiles/configuration/ChangeServer.jspx</result>
</action>
<action name="ShowChangeRemotePort">
<result>/HTML/tiles/configuration/ChangeRemotePort.jspx</result>
</action>
<action name="ChangeRemotePort"
class="
admintool.http.controller.actions.configuration.ChangeRemotePortAction">
<result
name="input">/HTML/tiles/configuration/ChangeRemotePort.jspx</result>
</action>
<action name="ShowChangeMail">
<result>/HTML/tiles/configuration/ChangeMail.jspx</result>
</action>
<action name="ChangeMail"
class="admintool.http.controller.actions.configuration.ChangeMailAction
">
<result
name="input">/HTML/tiles/configuration/ChangeMail.jspx</result>
</action>
<action name="ShowChangeThreads">
=== message truncated ===
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]