关于内网服务的图片上传代码,开发细节及一些要注意的地方。
一:tomcat服务器
1.1】
修改tomcat下的web.xml
1.2】
创建upload目录用来存放图片
1.3】
tomcat放在192.168.1.108:8585,
启动tomcat,验证容器正常可用
二:java代码
2.1】
pom.xml添加依赖
<dependency> <groupId>commons-fileupload</groupId> <artifactId>commons-fileupload</artifactId> <version>1.3.1</version> </dependency> <!-- commons-io --> <dependency> <groupId>commons-io</groupId> <artifactId>commons-io</artifactId> <version>2.4</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.18.1</version> </dependency> <dependency> <groupId>org.glassfish.jersey.core</groupId> <artifactId>jersey-common</artifactId> <version>2.0-m03</version> </dependency> <dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-core</artifactId> <version>1.18.1</version>
</dependency>
2.2】
springmvc.xml配置文件中添加
<!-- SpringMVC上传文件时,需要配置MultipartResolver处理器 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!-- 指定所上传文件的总大小不能超过10M。注意maxUploadSize属性的限制不是针对单个文件,而是所有文件的容量之和 --> <property name="defaultEncoding" value="utf-8"/> <property name="maxUploadSize" value="1048576"/>
</bean>
2.3】
sysconfig.properties属性文件添加
#文件服务器地址 uploadHost=http://192.168.1.108:8585/ #上传的文件保存的目录 imgPath = upload/2.4】
Controller层代码,消息实体自己封装
import java.util.Map; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.springframework.beans.factory.annotation.Value; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartHttpServletRequest; import com.sun.jersey.api.client.Client; import cn.com.onethird.common.dto.WebMessage; import cn.com.onethird.protection.common.constant.ReturnCode; import cn.com.onethird.util.ImageUtils; /** * 上传接口 * * @author * @UploadController * @date */ @RestController public class UploadController { @Value(value="${imgPath}") //图片保存地址 private String imgPath; @Value(value="${uploadHost}") private String uploadHost; //项目host /** * 上传头像 * @param request * @param response */ @RequestMapping(value="/upload/uploadHeadImg", method=RequestMethod.POST) public @ResponseBody WebMessage<String> uploadSysHeadImg(HttpServletRequest request, HttpServletResponse response){ WebMessage<String> message = new WebMessage<String>(); message.setReturnCode(ReturnCode.ok.toString()); String realPath = ""; try { MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)(request); // MultipartResolver resolver = new CommonsMultipartResolver(request.getSession().getServletContext()); // MultipartHttpServletRequest Murequest = resolver.resolveMultipart(request); Map<String, MultipartFile> files = multiRequest.getFileMap(); Client client = new Client(); for(MultipartFile pic: files.values()){ String uploadInfo = ImageUtils.upload(client, pic, request, response, uploadHost, imgPath, 200, 200); if(!"".equals(uploadInfo)){ realPath = uploadInfo;//完整路径 } } }catch (Exception e) { e.printStackTrace(); message.setReturnCode(ReturnCode.fail.toString()); } message.setMesssageBody(realPath); return message; }
}
2.5】
upload工具类方法
/** * 上传文件--支持跨域 * * @param request * @param response * @param serverPath * 服务器地址:(http://192.168.1.121:8585/) * @param path * 文件路径(upload/) * @return */ public static String upload(Client client, MultipartFile file, HttpServletRequest request, HttpServletResponse response, String serverPath, String path) { // 新文件名 String fileName = generateFileName(file.getOriginalFilename()); // 获取文件的扩展名 String extension = FilenameUtils.getExtension(file.getOriginalFilename()); // 相对路径 String relaPath = path + fileName; //跨域 另一台tomcat的URL(真实路径) String realPath = serverPath + relaPath; // 按比例压缩图片 BufferedImage srcBufferImage = ImageIO.read(file.getInputStream()); ScaleImage scaleImage = ScaleImage.getInstance(); ByteArrayOutputStream out = new ByteArrayOutputStream(); // 如果上传图片 宽高 比 压缩的要小 则不压缩 if (w < srcBufferImage.getWidth() && h < srcBufferImage.getHeight()) { BufferedImage scaledImage = scaleImage.imageZoomOut(srcBufferImage, w, h); try { //填充out ImageIO.write(scaledImage, extension, out); } catch (IOException e) { e.printStackTrace(); } } // 设置请求路径 WebResource resource = client.resource(realPath); resource.put(String.class, out.toByteArray()); return realPath;
}
/** * 获得一个时间格式的新名称 * * @param fileName * 原图名称 * @return */ private static String generateFileName(String fileName) { DateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); String formatDate = format.format(new Date()); int random = new Random().nextInt(10000); int position = fileName.lastIndexOf("."); String extension = fileName.substring(position); return formatDate + random + extension;
}
2.6】
ScaleImage 类
-
-
-
import java.awt.image.BufferedImage;
-
-
public class ScaleImage {
-
private int width;
-
-
private int height;
-
-
private int scaleWidth;
-
-
private double support = (double) 3.0;
-
-
private double PI = (double) 3.14159265358978;
-
-
private double[] contrib;
-
-
private double[] normContrib;
-
-
private double[] tmpContrib;
-
-
private int nDots;
-
-
private int nHalfDots;
-
-
/**
-
* Start: Use Lanczos filter to replace the original algorithm for image
-
* scaling. Lanczos improves quality of the scaled image modify by :blade
-
*/
-
private static ScaleImage instance = new ScaleImage();
-
private ScaleImage(){};
-
public static ScaleImage getInstance(){
-
return instance;
-
}
-
public BufferedImage imageZoomOut(BufferedImage srcBufferImage, int w, int h) {
-
width = srcBufferImage.getWidth();
-
height = srcBufferImage.getHeight();
-
scaleWidth = w;
-
-
if (DetermineResultSize(w, h) == 1) {
-
return srcBufferImage;
-
}
-
CalContrib();
-
BufferedImage pbOut = HorizontalFiltering(srcBufferImage, w);
-
BufferedImage pbFinalOut = VerticalFiltering(pbOut, h);
-
return pbFinalOut;
-
}
-
-
/**
-
* 决定图像尺寸
-
*/
-
private int DetermineResultSize(int w, int h) {
-
double scaleH, scaleV;
-
scaleH = (double) w / (double) width;
-
scaleV = (double) h / (double) height;
-
-
if (scaleH >= 1.0 && scaleV >= 1.0) {
-
return 1;
-
}
-
return 0;
-
-
} // end of DetermineResultSize()
-
-
private double Lanczos(int i, int inWidth, int outWidth, double Support) {
-
double x;
-
-
x = (double) i * (double) outWidth / (double) inWidth;
-
-
return Math.sin(x * PI) / (x * PI) * Math.sin(x * PI / Support)
-
/ (x * PI / Support);
-
-
} // end of Lanczos()
-
-
//
-
// Assumption: same horizontal and vertical scaling factor
-
//
-
private void CalContrib() {
-
nHalfDots = (int) ((double) width * support / (double) scaleWidth);
-
nDots = nHalfDots * 2 + 1;
-
try {
-
contrib = new double[nDots];
-
normContrib = new double[nDots];
-
tmpContrib = new double[nDots];
-
} catch (Exception e) {
-
System.out.println("init contrib,normContrib,tmpContrib" + e);
-
}
-
-
int center = nHalfDots;
-
contrib[center] = 1.0;
-
-
double weight = 0.0;
-
int i = 0;
-
for (i = 1; i <= center; i++) {
-
contrib[center + i] = Lanczos(i, width, scaleWidth, support);
-
weight += contrib[center + i];
-
}
-
-
for (i = center - 1; i >= 0; i--) {
-
contrib[i] = contrib[center * 2 - i];
-
}
-
-
weight = weight * 2 + 1.0;
-
-
for (i = 0; i <= center; i++) {
-
normContrib[i] = contrib[i] / weight;
-
}
-
-
for (i = center + 1; i < nDots; i++) {
-
normContrib[i] = normContrib[center * 2 - i];
-
}
-
} // end of CalContrib()
-
-
// 处理边缘
-
private void CalTempContrib(int start, int stop) {
-
double weight = 0;
-
-
int i = 0;
-
for (i = start; i <= stop; i++) {
-
weight += contrib[i];
-
}
-
-
for (i = start; i <= stop; i++) {
-
tmpContrib[i] = contrib[i] / weight;
-
}
-
-
} // end of CalTempContrib()
-
-
private int GetRedValue(int rgbValue) {
-
int temp = rgbValue & 0x00ff0000;
-
return temp >> 16;
-
}
-
-
private int GetGreenValue(int rgbValue) {
-
int temp = rgbValue & 0x0000ff00;
-
return temp >> 8;
-
}
-
-
private int GetBlueValue(int rgbValue) {
-
return rgbValue & 0x000000ff;
-
}
-
-
private int ComRGB(int redValue, int greenValue, int blueValue) {
-
-
return (redValue << 16) + (greenValue << 8) + blueValue;
-
}
-
-
-
private int HorizontalFilter(BufferedImage bufImg, int startX, int stopX,
-
int start, int stop, int y, double[] pContrib) {
-
double valueRed = 0.0;
-
double valueGreen = 0.0;
-
double valueBlue = 0.0;
-
int valueRGB = 0;
-
int i, j;
-
-
for (i = startX, j = start; i <= stopX; i++, j++) {
-
valueRGB = bufImg.getRGB(i, y);
-
-
valueRed += GetRedValue(valueRGB) * pContrib[j];
-
valueGreen += GetGreenValue(valueRGB) * pContrib[j];
-
valueBlue += GetBlueValue(valueRGB) * pContrib[j];
-
}
-
-
valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen),
-
Clip((int) valueBlue));
-
return valueRGB;
-
-
} // end of HorizontalFilter()
-
-
// 图片水平滤波
-
private BufferedImage HorizontalFiltering(BufferedImage bufImage, int iOutW) {
-
int dwInW = bufImage.getWidth();
-
int dwInH = bufImage.getHeight();
-
int value = 0;
-
BufferedImage pbOut = new BufferedImage(iOutW, dwInH,
-
BufferedImage.TYPE_INT_RGB);
-
-
for (int x = 0; x < iOutW; x++) {
-
-
int startX;
-
int start;
-
int X = (int) (((double) x) * ((double) dwInW) / ((double) iOutW) + 0.5);
-
int y = 0;
-
-
startX = X - nHalfDots;
-
if (startX < 0) {
-
startX = 0;
-
start = nHalfDots - X;
-
} else {
-
start = 0;
-
}
-
-
int stop;
-
int stopX = X + nHalfDots;
-
if (stopX > (dwInW - 1)) {
-
stopX = dwInW - 1;
-
stop = nHalfDots + (dwInW - 1 - X);
-
} else {
-
stop = nHalfDots * 2;
-
}
-
-
if (start > 0 || stop < nDots - 1) {
-
CalTempContrib(start, stop);
-
for (y = 0; y < dwInH; y++) {
-
value = HorizontalFilter(bufImage, startX, stopX, start,
-
stop, y, tmpContrib);
-
pbOut.setRGB(x, y, value);
-
}
-
} else {
-
for (y = 0; y < dwInH; y++) {
-
value = HorizontalFilter(bufImage, startX, stopX, start,
-
stop, y, normContrib);
-
pbOut.setRGB(x, y, value);
-
}
-
}
-
}
-
-
return pbOut;
-
-
} // end of HorizontalFiltering()
-
-
private int VerticalFilter(BufferedImage pbInImage, int startY, int stopY,
-
int start, int stop, int x, double[] pContrib) {
-
double valueRed = 0.0;
-
double valueGreen = 0.0;
-
double valueBlue = 0.0;
-
int valueRGB = 0;
-
int i, j;
-
-
for (i = startY, j = start; i <= stopY; i++, j++) {
-
valueRGB = pbInImage.getRGB(x, i);
-
-
valueRed += GetRedValue(valueRGB) * pContrib[j];
-
valueGreen += GetGreenValue(valueRGB) * pContrib[j];
-
valueBlue += GetBlueValue(valueRGB) * pContrib[j];
-
// System.out.println(valueRed+"->"+Clip((int)valueRed)+"<-");
-
//
-
// System.out.println(valueGreen+"->"+Clip((int)valueGreen)+"<-");
-
// System.out.println(valueBlue+"->"+Clip((int)valueBlue)+"<-"+"-->");
-
}
-
-
valueRGB = ComRGB(Clip((int) valueRed), Clip((int) valueGreen),
-
Clip((int) valueBlue));
-
// System.out.println(valueRGB);
-
return valueRGB;
-
-
} // end of VerticalFilter()
-
-
private BufferedImage VerticalFiltering(BufferedImage pbImage, int iOutH) {
-
int iW = pbImage.getWidth();
-
int iH = pbImage.getHeight();
-
int value = 0;
-
BufferedImage pbOut = new BufferedImage(iW, iOutH,
-
BufferedImage.TYPE_INT_RGB);
-
-
for (int y = 0; y < iOutH; y++) {
-
-
int startY;
-
int start;
-
int Y = (int) (((double) y) * ((double) iH) / ((double) iOutH) + 0.5);
-
-
startY = Y - nHalfDots;
-
if (startY < 0) {
-
startY = 0;
-
start = nHalfDots - Y;
-
} else {
-
start = 0;
-
}
-
-
int stop;
-
int stopY = Y + nHalfDots;
-
if (stopY > (int) (iH - 1)) {
-
stopY = iH - 1;
-
stop = nHalfDots + (iH - 1 - Y);
-
} else {
-
stop = nHalfDots * 2;
-
}
-
-
if (start > 0 || stop < nDots - 1) {
-
CalTempContrib(start, stop);
-
for (int x = 0; x < iW; x++) {
-
value = VerticalFilter(pbImage, startY, stopY, start, stop,
-
x, tmpContrib);
-
pbOut.setRGB(x, y, value);
-
}
-
} else {
-
for (int x = 0; x < iW; x++) {
-
value = VerticalFilter(pbImage, startY, stopY, start, stop,
-
x, normContrib);
-
pbOut.setRGB(x, y, value);
-
}
-
}
-
-
}
-
-
return pbOut;
-
-
} // end of VerticalFiltering()
-
-
private int Clip(int x) {
-
if (x < 0)
-
return 0;
-
if (x > 255)
-
return 255;
-
return x;
-
}
-
-
/**
-
* End: Use Lanczos filter to replace the original algorithm for image
-
* scaling. Lanczos improves quality of the scaled image modify by :blade
-
*/
-
-
}
2.7】
前端代码省略
常规提供一个type="file"的提交模块,后台会自动处理请求中的图片
====================================================
三:遇到的问题:
returned a response status of 403 Forbidden
需要在这个存储图片的项目所在的tomcat中配置可写操作,具体的是在Tomcat目录下的conf文件夹下的web.xml中加入
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
returned a response status of 409 Conflict
确保服务器webapps中image-web项目中存在upload路径
====================================================
由于是测试用例,主机是直接关闭了防火墙,如果需要开启防火墙还需要配置相应的出入规则
参考--
如何在局域网访问Tomcat项目
图片压缩的ScaleImage类借用http://blog.youkuaiyun.com/mmm333zzz/article/details/8569637