Can not find a java.io.InputStream with the name [inputStream] in the invocation stack. Check the <

本文介绍了一个基于Struts框架实现文件下载的具体案例,详细解释了如何通过设置正确的文件路径来避免流为空的问题,并提供了完整的代码示例及struts.xml配置。

最近项目需要用到上传下载,以前学jsp的时候直接用的是smartUpload,现在学的框架但是老师只是简单地教了框架的内容

对struts文件上传和下载没有涉及,没办法只能自己自学了!结果出现了上面的问题。

这个问题的根本原因网上都有说出来,但是没有给出的解决方案。原因是要返回的流为空,文件的路径有误导致文件的输入流为空!

所以最好在逻辑处理那块输出的你要下载文件的路径看是不是你要下载的路径!好了废话不多说哈!


package com.iss.action;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import org.apache.struts2.ServletActionContext;
import com.opensymphony.xwork2.ActionSupport;
public class DownLoad extends ActionSupport {


private String fileName;


private String directory;



public void setDirectory(String directory) {
this.directory = directory;
}


public String getFileName() {
return fileName;
}


public void setFileName(String fileName) {
this.fileName = fileName;
}


public InputStream getInputStream() throws FileNotFoundException {


String dir = directory + fileName;

System.out.println(dir);//输出的文件要下载的路径


// return ServletActionContext.getServletContext().getResourceAsStream(
// "/" +dir);//使用相对路径下载文件内容默认是和webRoot同一目录
return new FileInputStream(dir);//使用全局路径下载

}

@Override
public String execute() throws Exception {
System.out.println("fileName:" + fileName);
return SUCCESS;
}
}


struts.xml中的配置

<!--下载action -->
<action name="downloadAction" class="com.iss.action.DownLoad">
<!-- <param name="directory">/images/</param> -->下载路径为相对路径
<param name="directory">E:/wang/head/</param>下载路径为绝对路径
<result type="stream">
<!--指定下载文件内容的类型 -->
<param name="contentType">jpg/gif</param>
<!--inputName默认值inputStream -->
<param name="inputName">inputStream</param>
<!--动态文件获取 -->
<param name="contentDisposition">attachement;fileName="${fileName}"</param>
<!-- 指定下载文件的缓冲大小 -->
<param name="bufferSize">50000000</param>
</result>
<result name="input">error.jsp</result>
</action>

总结:无论使用相对路径还是绝对路径作为下载路径都要把要下载的文件路径写对否则就会出现上面的错误!


HTTP状态 500 - 内部服务器错误 类型 异常报告 消息 设置字段值失败 描述 服务器遇到一个意外的情况,阻止它完成请求。 例外情况 java.lang.RuntimeException: 设置字段值失败 com.yyq.util.DBUtil.setEntityField(DBUtil.java:120) com.yyq.util.DBUtil.executeQuery(DBUtil.java:78) com.yyq.dao.AdminDao.login(AdminDao.java:56) com.yyq.servlet.AdminServlet.doPost(AdminServlet.java:46) jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) 根本原因。 java.lang.NoSuchFieldException: java.lang.integer java.base/java.lang.Class.getDeclaredField(Class.java:2610) com.yyq.util.DBUtil.setEntityField(DBUtil.java:112) com.yyq.util.DBUtil.executeQuery(DBUtil.java:78) com.yyq.dao.AdminDao.login(AdminDao.java:56) com.yyq.servlet.AdminServlet.doPost(AdminServlet.java:46) jakarta.servlet.http.HttpServlet.service(HttpServlet.java:590) jakarta.servlet.http.HttpServlet.service(HttpServlet.java:658) org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51) ):注意 主要问题的全部 stack 信息可以在 server logs 里查看 Apache Tomcat/10.1.42package com.yyq.util; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; import java.sql.*; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Properties; /** * @Author 写你的名字 * @Date 2025/9/23 下午7:07 (可以根据需要修改) * @Version 1.0 (版本号) */ public class DBUtil { private static String url ; private static String userName; private static String password; public DBUtil() { } static{ Properties properties = new Properties(); InputStream is = DBUtil.class.getClassLoader().getResourceAsStream("db.properties"); if(is==null){ throw new RuntimeException("未找到jdbc配置文件"); } try { properties.load(is); } catch (IOException e) { throw new RuntimeException(e); } url = properties.getProperty("jdbcUrl"); userName = properties.getProperty("userName"); password = properties.getProperty("password"); } public static Connection getConnection() throws SQLException, ClassNotFoundException { Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver"); System.out.println("mysql驱动加载成功"); return DriverManager.getConnection(url,userName,password); } public static void closeAll(Connection connection, PreparedStatement ps, ResultSet rs) throws SQLException { if(rs!=null){ rs.close(); } if(ps!=null){ ps.close(); } if(connection!=null){ connection.close(); } } public <T> List<T> executeQuery(String sql,Object[] params,Class<T> clazz) throws SQLException { Connection connection = null; PreparedStatement ps = null; ResultSet rs= null; List<T> list = new ArrayList<>(); try { connection = DBUtil.getConnection(); ps = connection.prepareStatement(sql); setParam(ps,params); rs = ps.executeQuery(); while(rs.next()){ T t = clazz.getDeclaredConstructor().newInstance(); ResultSetMetaData metaData = rs.getMetaData(); int columnCount = metaData.getColumnCount(); for (int i = 1; i <= columnCount; i++) { String columnName = metaData.getColumnClassName(i); Object value = rs.getObject(i); setEntityField(t,columnName,value); } list.add(t); } } catch (SQLException e) { throw new RuntimeException(e); } catch (ClassNotFoundException | NoSuchMethodException | InstantiationException | IllegalAccessException | InvocationTargetException e) { throw new RuntimeException("执行查询失败",e); }finally { closeAll(connection,ps,rs); } return list; } public int executeUpdate(String sql,Object[] params) throws SQLException, ClassNotFoundException { int row = 0; Connection connection = null; PreparedStatement ps = null; ResultSet rs = null; connection = DBUtil.getConnection(); ps = connection.prepareStatement(sql); setParam(ps,params); row = ps.executeUpdate(); closeAll(connection,ps,null); return row; } private <T> void setEntityField(T t, String columnClassName, Object value) { try { String fieldName = formatColumnName(columnClassName); //获取实体类的字段 Field field = t.getClass().getDeclaredField(fieldName); //处理字段访问权限 field.setAccessible(true); //处理类型转换 Object setValue = convertValue(value,field.getType()); field.set(t,setValue); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException("设置字段值失败" , e); } } private Object convertValue(Object value, Class<?> type) { if(value==null){ return null; } //处理日期类型转换成字符串 if(value instanceof java.util.Date && type==String.class){ java.util.Date value1 = (Date) value; return value1.toString(); } if(value instanceof Timestamp && type == String.class){ LocalDateTime localDateTime = ((Timestamp) (value)).toLocalDateTime(); String format = localDateTime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")); return format; } if(value instanceof Number){ if(type == Integer.class || type == int.class ){ return ((Number)value).intValue();//将number类型转换成int类型 } if(type==long.class || type == Long.class){ return ((Number)value).longValue(); } if(type==double.class || type == Double.class){ return ((Number)value).doubleValue(); } } if(type.isInstance(value)){ return value; } return value; } private void setParam(PreparedStatement ps ,Object[] param) throws SQLException { if(param!=null&&param.length>0){ for (int i = 0; i < param.length; i++) { ps.setObject(i+1,param[i]); } } } public String formatColumnName(String columnName) { if (columnName == null) { return null; } // 修复:不管是否包含下划线,都先转小写(避免数据库列名大写导致不匹配) columnName = columnName.toLowerCase(); if (!columnName.contains("_")) { return columnName; // 无下划线直接返回(如account→account) } StringBuilder sb = new StringBuilder(); String[] splitName = columnName.split("_"); sb.append(splitName[0]); // 第一部分直接加(如admin) for (int i = 1; i < splitName.length; i++) { if (splitName[i].isEmpty()) { continue; // 避免空字符串导致异常 } char c = splitName[i].charAt(0); char upperCase = Character.toUpperCase(c); // 首字母大写(如id→Id) sb.append(upperCase); sb.append(splitName[i].substring(1)); // 拼接后续字符(如d→d) } return sb.toString(); // 最终:admin_id→adminId } }
最新发布
09-26
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值