我正在尝试修复此代码,使用 Struts 2 上传图像文件。 当我调试时,我在我的动作类中验证,我的变量
descriptor
,descriptorContentType
和descriptorFileName
都是null
。
我尝试寻找问题所在,但没有任何结果。这是我的代码,有人知道这段代码有什么问题吗?
ver.jsp
:
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib prefix="s" uri="/struts-tags" %>
<%@taglib prefix="sj" uri="/struts-jquery-tags"%>
<html>
<head>
<title></title>
<meta name="decorator" content="ajax"/>
</head>
<body>
<s:form action="guardar" id="formularioImagen" enctype="multipart/form-data" method="post">
<s:token name="imagenFichaEmpresaForm"/>
<s:hidden name="codigoFichaEmpresa"/>
<div class="mensajeInfo mensajeRelativo">
<s:text name="fichaEmpresa.texto.imagenInformacion"/>
</div>
<table>
<s:file name="descriptor"/>
</table>
<div style="text-align: center">
<sj:submit name="btnGuardar"
targets="imagenFichaEmpresa"
title="%{getText('comun.textos.guardar')}"
value="%{getText('comun.textos.guardar')}"
formIds="formularioImagen"
/>
<sj:submit name="btnCerrar"
onClickTopics="cerrarUrlImagenes"
title="%{getText('comun.texto.cerrar')}"
value="%{getText('comun.texto.cerrar')}"
/>
</div>
</s:form>
</body>
</html>
struts.xml
:
<package name="clienteFichaEmpresaImagen" namespace="/validador/privado/cliente/fichaEmpresa/imagen" extends="struts-validador">
<action name="listado"
class="com.construdata21.construdata.validador.vista.actions.cliente.FichaEmpresaImagenAction"
method="listado">
<result>/validador/cliente/fichaEmpresa/imagen/listar.jsp</result>
</action>
<action name="eliminarImagen"
class="com.construdata21.construdata.validador.vista.actions.cliente.FichaEmpresaImagenAction"
method="eliminar">
<result type="redirectAction">
<param name="actionName">listado</param>
<param name="codigoFichaEmpresa">${codigoFichaEmpresa}</param>
</result>
</action>
<action name="ver"
class="com.construdata21.construdata.validador.vista.actions.cliente.FichaEmpresaImagenAction"
method="ver">
<result>/validador/cliente/fichaEmpresa/imagen/ver.jsp</result>
</action>
<action name="guardar"
class="com.construdata21.construdata.validador.vista.actions.cliente.FichaEmpresaImagenAction"
method="guardar">
<interceptor-ref name="defaultStack">
<param name="fileUpload.maximumSize">10485760</param> <!-- Max file size: 10MB -->
<param name="fileUpload.allowedTypes">image/jpeg,image/png,image/gif</param> <!-- Allowed types -->
</interceptor-ref>
<result>/validador/cliente/fichaEmpresa/imagen/imagenCorrecta.jsp</result>
<result name="input">/validador/cliente/fichaEmpresa/imagen/ver.jsp</result>
</action>
<action name="moverImagen"
class="com.construdata21.construdata.validador.vista.actions.cliente.FichaEmpresaImagenAction"
method="moverImagen">
<result>/validador/cliente/fichaEmpresa/imagen/listar.jsp</result>
</action>
<action name="validarImagen"
class="com.construdata21.construdata.validador.vista.actions.cliente.FichaEmpresaImagenAction"
method="validarImagen">
<result type="redirectAction">
<param name="actionName">listado</param>
<param name="codigoFichaEmpresa">${codigoFichaEmpresa}</param>
</result>
</action>
</package>
FichaEmpresaImagenAction.java
:
package com.construdata21.construdata.validador.vista.actions.cliente;
import com.construdata21.construdata.cliente.negocio.fachadas.FachadaCliente;
import com.construdata21.construdata.negocio.modelo.Archivo;
import com.construdata21.construdata.negocio.modelo.ArchivoImagen;
import com.construdata21.construdata.negocio.modelo.FichaEmpresa;
import com.construdata21.construdata.negocio.modelo.UsuarioConstrudata;
import com.construdata21.construdata.validador.negocio.fachadas.FachadaValidador;
import com.construdata21.construdata.validador.vista.actions2.ValidadorAction;
import com.construdata21.construdata.vista.comun.FachadaSesion;
import static com.opensymphony.xwork2.Action.SUCCESS;
import com.opensymphony.xwork2.ModelDriven;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Date;
import javax.imageio.ImageIO;
import org.apache.struts2.interceptor.validation.SkipValidation;
public class FichaEmpresaImagenAction
extends ValidadorAction
implements ModelDriven<Archivo> {
public static final int MAX_ANCHO_IMAGEN = 1024;
public static final int MAX_ALTO_IMAGEN = 800;
/**
* Atributo que conten a imaxe
*/
private final ArchivoImagen imagen = new ArchivoImagen();
/**
*
* @return imagen Archivo coa imaxe
*/
@Override
public Archivo getModel() {
return imagen;
}
/**
* Atributo que contén as imaxes da ficha empresa
*/
private Archivo[] imagenes;
/**
* Metodo que retorna o atributo imagenes
*
* @return imagenes Archivo[] coas imaxes
*/
public Archivo[] getImagenes() {
return imagenes;
}
/**
* Atributo co descriptor do arquivo
*/
private File descriptor;
/**
* Método que nos devolve o descriptor do arquivo
*
* @return File co descriptor
*/
public File getDescriptor() {
return descriptor;
}
/**
* Método que establece o descriptor do arquivo
*
* @param descriptor File
*/
public void setDescriptor(File descriptor) {
this.descriptor = descriptor;
}
private String descriptorContentType;
/**
* Content type do arquivo
*
* @return String descriptorContentType
*/
public String getDescriptorContentType() {
return descriptorContentType;
}
/**
* Método que establece o content type
*
* @param descriptorContentType
*/
public void setDescriptorContentType(String descriptorContentType) {
this.descriptorContentType = descriptorContentType;
}
/**
* Atributo co nome do descriptor
*/
private String descriptorFileName;
/**
* Método que nos devolve o nome do arquivo
*
* @return String
*/
public String getDescriptorFileName() {
return descriptorFileName;
}
/**
* Método que nos establece o nome do arquivo
*
* @param descriptorFileName
*/
public void setDescriptorFileName(String descriptorFileName) {
this.descriptorFileName = descriptorFileName;
}
/**
* Atributo que representa o codigo da ficha empresa
*/
private int codigoFichaEmpresa;
/**
* Metodo que retorna o codigo da ficha empresa
*
* @return codigoFichaEmpresa int co codigo
*/
public int getCodigoFichaEmpresa() {
return codigoFichaEmpresa;
}
/**
* Metodo que establece o codigo da ficha empresa
*
* @param codigoFichaEmpresa int co codigo
*/
public void setCodigoFichaEmpresa(int codigoFichaEmpresa) {
this.codigoFichaEmpresa = codigoFichaEmpresa;
}
/**
* Método encargado de visualizar unha imaxe da ficha empresa
*
* @return String co resultado da execución do action
* @throws Exception
*/
@SkipValidation
public String ver() throws Exception {
return SUCCESS;
}
/**
* Método encargado de gardar unha imaxe da ficha empresa
*
* @return String co resultado da execución do action
* @throws Exception
*/
public String guardar() throws Exception {
UsuarioConstrudata usuario = (UsuarioConstrudata) this.getSession().get(FachadaSesion.USUARIO_SESION_VALIDADOR);
if (codigoFichaEmpresa > 0) {
imagen.setArchivo(Files.readAllBytes(descriptor.toPath()));
imagen.setLongitud(descriptor.getTotalSpace());
imagen.setNombre(descriptorFileName);
imagen.setFechaValidacion(new Date());
imagen.setCodigo(FachadaValidador.guardarImagenFichaEmpresa(codigoFichaEmpresa, imagen, usuario));
FachadaValidador.validarArchivoImagen(
imagen.getCodigo(),
usuario.getCodigo());
}
return SUCCESS;
}
/**
* Metodo que executa a accion de eliminar as imaxes
*
* @return String co resultado
* @throws java.lang.Exception
*/
@SkipValidation
public String eliminar() throws Exception {
UsuarioConstrudata usuario = (UsuarioConstrudata) this.getSession().get(FachadaSesion.USUARIO_SESION_VALIDADOR);
if (codigoFichaEmpresa > 0 && imagen.getCodigo() > 0) {
FachadaValidador.fichaEmpresaImagenEliminar(codigoFichaEmpresa,
imagen.getCodigo(),
usuario);
}
return SUCCESS;
}
/**
* Metodo que executa a accion de listar
*
* @return String co resultado
* @throws java.lang.Exception
*/
@SkipValidation
public String listado() throws Exception {
UsuarioConstrudata usuarioSesion = (UsuarioConstrudata) getSession().get(FachadaSesion.USUARIO_SESION_VALIDADOR);
FichaEmpresa fichaEmpresa = FachadaCliente.getFichaEmpresaCompleta(codigoFichaEmpresa, usuarioSesion);
imagenes = fichaEmpresa.getImagenes();
return SUCCESS;
}
/**
* Metodo que executa a accion de listar
*
* @return String co resultado
* @throws java.lang.Exception
*/
@SkipValidation
public String moverImagen() throws Exception {
if (imagen.getCodigo() > 0 && codigoFichaEmpresa > 0) {
FachadaCliente.modificarOrdenImagenFichaEmpresa(
codigoFichaEmpresa,
imagen.getCodigo(),
imagen.getOrden()
);
}
UsuarioConstrudata usuarioSesion = (UsuarioConstrudata) getSession().get(FachadaSesion.USUARIO_SESION_VALIDADOR);
FichaEmpresa fichaEmpresa = FachadaCliente.getFichaEmpresaCompleta(codigoFichaEmpresa, usuarioSesion);
imagenes = fichaEmpresa.getImagenes();
return SUCCESS;
}
/**
* Metodo que valida unha imaxe
*
* @return resultado String co resultado
* @throws Exception
*/
@SkipValidation
public String validarImagen() throws Exception {
if (imagen.getCodigo() > 0) {
UsuarioConstrudata usuario = (UsuarioConstrudata) this.getSession().get(FachadaSesion.USUARIO_SESION_VALIDADOR);
FachadaValidador.validarArchivoImagen(imagen.getCodigo(), usuario.getCodigo());
}
return SUCCESS;
}
/**
* Metodo que valida o formulario (Imaxe)
*/
@Override
public void validate() {
super.validate();
BufferedImage img = null;
if (descriptor != null) {
try {
img = ImageIO.read(descriptor);
} catch (IOException ex) {
}
if (img != null) {
if (img.getWidth() > MAX_ANCHO_IMAGEN) {
this.addFieldError("descriptor", "Ha superado el ancho permitido: " + MAX_ANCHO_IMAGEN);
} else if (img.getHeight() > MAX_ALTO_IMAGEN) {
this.addFieldError("descriptor", "Ha superado el alto permitido: " + MAX_ALTO_IMAGEN);
}
} else {
this.addFieldError("descriptor", "El archivo no es una imagen");
}
} else {
this.addFieldError("descriptor", "Selecciona un archivo");
}
}
}
首先,您应该检查您的操作配置。该包包含文件上传操作配置 inerits
struts-validator
。无论这个包的定义是什么都是未知的(没有可用的源代码)。但它应该延伸struts-default
。这是默认配置,其中定义了拦截器的defaultStack
。请参阅文档。
既然你在你的动作配置中使用它,你应该知道
fileUpload
拦截器正在到达,在它被拦截器堆栈链接到defaultStack
之后。这个堆栈很大,用于获取 Struts 操作的通用功能,直到它被操作配置覆盖。您这样做是为了更改 fileUpload
拦截器的某些属性,但没有更改 defaultStack
以及拦截器在堆栈中的顺序。特别是,您需要它来创建自定义堆栈,因为您的操作类实现了 ModelDriven
。
我不建议您使用
ModelDriven
,因为您可能在正确实施它时遇到问题。例如,getModel()
返回了错误的类型。 modelDriven
拦截器将模型对象压入值栈,这是fileUpload
拦截器期望找到setter来存储上传文件的属性,例如descriptor
、descriptorContentType
和descriptorFileName
。但就你而言,你在操作类中定义了它们。
您还使用
descriptor
表单编码与文件 multipart/form-data
一起提交其他文本字段值。因此,您应该为存储文件属性的对象提供适当的设置器。
fileUpload
拦截器在当前版本的Struts中已被废弃,并替换为actionFileUpload
。如果您阅读this答案,您可以找到更多信息。