配置文件spring-web.xml web.xml均与之前项目相同
直接在浏览器端显示:在浏览器中直接显示图片(谷歌、IE11、Edge浏览器均可用)
主要代码及文件如下:
package cn.tedu.web;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.ServletActionContext;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
@Controller
@Scope("prototype")
public class PhotoAction extends BaseAction{
private InputStream imageStream;
public InputStream getImageStream() {
return imageStream;
}
public void setImageStream(InputStream imageStream) {
this.imageStream = imageStream;
}
//用于获取原文件名称
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public String execute() throws IOException{
//方法一:在内存中画一张图片
//在内存中生成一张图片
BufferedImage img = new BufferedImage(400, 300, BufferedImage.TYPE_3BYTE_BGR);
/*
* 画麻点
* for(int i = 0;i<400*300;i++){
//x、y表示图片的某个位置
int x = (int) (Math.random()*img.getWidth());
int y = (int) (Math.random()*img.getHeight());
int c = (int) (Math.random()*0xffffff);
img.setRGB(x, y, c);//给图片中每个位置画点
}*/
//画图并写字
long c = 0;
for(int x=0;x<400;x++){
for(int y=0;y<300;y++){
img.setRGB(x, y, (int) (c+=100%0xffffff));
}
}
Graphics2D g = img.createGraphics();
g.setColor(Color.PINK);
g.drawString("你好", 40, 80);
//......
//将照片编码为png格式的数组
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(img, "jpg", out);//三个参数 图片 类型 输出流
byte[] png = out.toByteArray();
out.close();
//再将数组包装为InputStream
imageStream = new ByteArrayInputStream(png);
//方法二:windows电脑D盘中有一张图片
//imageStream = new FileInputStream("D://879da7098c51e1f51d731+-d5.jpg");
String name = "879da7098c51e1f51d731 d5你好+-_@!#$%^&()().jpg";
//获取浏览器相关数据
HttpServletRequest re = ServletActionContext.getRequest();
/*
* 对文件名的要求 中文 英文 数字 括号 空格
*/
fileName = transferName(re, name);
return SUCCESS;
}
//获取浏览器信息
public String transferName(HttpServletRequest re, String fileName) throws UnsupportedEncodingException{
//获取浏览器信息--判断浏览器的顺序很重要
String agent = re.getHeader("User-Agent");
System.out.println(agent);
if(agent.contains("Edge")){ //Edge 已测试
System.out.println("Edge");
return URLEncoder.encode(fileName,"UTF-8").replaceAll("\\+","%20");//处理空格转为加号的问题
}else if(agent.contains("Chrome")){ //google 已测试
System.out.println("Chrome");
return new String(fileName.getBytes(), "iso8859-1");
}else if(agent.contains("Firefox")){ //Firefox 待测试
System.out.println("Firefox");
return new String(fileName.getBytes(), "iso8859-1");
}else if(agent.contains("MSIE") || agent.contains("Trident")){ //IE11 已测试
System.out.println("IE");
//在IE8以后,微软使用了Trident来作为IE浏览器的标志,兼容老的版本
return URLEncoder.encode(fileName,"UTF-8").replaceAll("\\+","%20");//处理空格转为加号的问题
}else{
//其余浏览器 可测试并添加
System.out.println("Other");
return URLEncoder.encode(fileName,"UTF-8").replaceAll("\\+","%20");//待测试
}
}
}
既可以在内存中画图,也可以指定某个图片
struts.xml 如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package namespace="/demo" name="demo" extends="struts-default,json-default">
<!-- 直接显示图片 -->
<action name="photo" class="photoAction">
<result name="success" type="stream">
<!-- 发送图片信息 -->
<param name="contentType">image/jpeg</param>
<!-- in为photoAction类中的一个bean属性,其类型必须是InputStream类型 -->
<param name="inputName">imageStream</param>
</result>
</action>
</package>
</struts>
通过该配置可以在浏览器中直接显示图片
URL:http://localhost:8000/struts_day03/demo/photo
在浏览器端弹框显示下载,可自定义文件保存路径:(谷歌、IE11、Edge浏览器均可用)
Action同上,只是配置文件不同
struts.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package namespace="/demo" name="demo" extends="struts-default,json-default">
<!-- 下载图片 默认文件名称 -->
<action name="download" class="photoAction">
<result name="success" type="stream">
<!-- 发送图片信息 -->
<param name="contentType">image/jpeg</param>
<!-- attachment为弹框下载 inline为直接显示或者将 contentDisposition 这个属性去掉,不写以下这行-->
<param name="contentDisposition">attachment;filename="mylove你好.jpg"</param><!-- 此处最好不要使用中文 可能乱码或显示错误 -->
<!-- in为photoAction类中的一个bean属性,其类型必须是InputStream类型 -->
<param name="inputName">imageStream</param>
</result>
</action>
<!-- 下载图片 自定义文件名称 -->
<action name="download1" class="photoAction">
<result name="success" type="stream">
<!-- 发送图片信息 -->
<param name="contentType">image/jpeg</param>
<!-- attachment为弹框下载 inline为直接显示或者将 contentDisposition 这个属性去掉,不写以下这行-->
<param name="contentDisposition">attachment;filename=${fileName}</param>
<!-- in为photoAction类中的一个bean属性,其类型必须是InputStream类型 -->
<param name="inputName">imageStream</param>
</result>
</action>
</package>
</struts>
注意,若在struts.xml文件中指定固定的文件名时候,尽量不要用中文,在不同的浏览器中,中文可能不显示或者乱码,建议如下写法:
<param name="contentDisposition">attachment;filename="mylove.jpg"</param>
若文件名中一定要包含中文或者其他的特殊字符,可以使用第二个下载方法,在控制器action中定义好文件名,并且处理好浏览器的兼容问题和编码方式即可,之前博客已经说明,可参照
若要弹框下载,则必须在result中指定contentDisposition属性