cropper头像上传

来源:互联网 发布:淘宝企业店如何避税 编辑:程序博客网 时间:2024/06/05 14:49

花了几天时间学习了下javaWeb中cropper头像上传功能,下面仅在此记录一下.

看到有篇博客是在前台用canvas的toDataURL处理,但貌似无法处理gif图像(如有大侠知道如何处理,还望告知),故放弃这一做法而选择在后端处理,

前台提交scaleX,scaleY,rotate,x,y,width,height及原始图片,后台缩放、旋转、裁剪.


一、下面先提供一个处理类:

import java.awt.Color;import java.awt.Dimension;import java.awt.Graphics2D;import java.awt.geom.AffineTransform;import java.awt.image.BufferedImage;import java.io.ByteArrayOutputStream;import java.io.IOException;import java.io.InputStream;import javax.imageio.ImageIO;import org.apache.commons.lang3.StringUtils;import com.lzw.gif.AnimatedGifEncoder;import com.lzw.gif.GifDecoder;/** * @author nc-wl001 配合cropper头像上传插件使用的bean、(注意cropper插件缩放后图片大小是不变的及图片中心是不变的) */public class Cropper {//水平方向缩放比例private double scaleX;//垂直方向缩放比例private double scaleY;// 旋转角度15、45等private int rotate;// 注意以下数据均是相对于旋转后的图片// 裁剪框左上角xprivate int x;// 裁剪框左上角yprivate int y;// 裁剪框宽度private int width;// 裁剪框高度private int height;// 为防止目标图片过大而添加的一个缩放比例参数protected double scale = 1.0;public Cropper(double scaleX,double scaleY,int rotate, int x, int y, int width, int height) {super();this.scaleX=scaleX;this.scaleY=scaleY;this.rotate = rotate;this.x = x;this.y = y;this.width = width;this.height = height;}public int getRotate() {return rotate;}public void setRotate(int rotate) {this.rotate = rotate;}public int getX() {return x;}public void setX(int x) {this.x = x;}public int getY() {return y;}public void setY(int y) {this.y = y;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;}public double getScaleX() {return scaleX;}public void setScaleX(double scaleX) {this.scaleX = scaleX;}public double getScaleY() {return scaleY;}public void setScaleY(double scaleY) {this.scaleY = scaleY;}/** * 设置缩放比例 *  * @param scale */protected void setScale(double scale) {this.x = (int) Math.ceil(this.x * scale / this.scale);this.y = (int) Math.ceil(this.y * scale / this.scale);this.width = (int) Math.ceil(this.width * scale / this.scale);this.height = (int) Math.ceil(this.height * scale / this.scale);this.scale = scale;}/** * 设置目标图片宽度 *  * @param width */public void setFactWidth(int width) {double scale = width * this.scale / this.width;this.setScale(scale);}/** * 设置目标图片高度 *  * @param height */public void setFactHeight(int height) {double scale = height * this.scale / this.height;this.setScale(scale);}/** * 获取源图片旋转后的目标容器大小 *  * @param source *            源图片大小 * @return */protected final Dimension getTargetDimension(Dimension source) {source.setSize(source.getWidth() * this.scale, source.getHeight()* this.scale);// 获取旋转后图片大小double theta = Math.toRadians(this.rotate);double target_width, target_height;if ((int) Math.floor(this.rotate / 90.0) % 2 == 0) {// 也即Math.sin(2*theta)>0(Math.sin(2*theta)=0时两个分支结果一样)target_width = Math.abs(source.width * Math.cos(theta)+ source.height * Math.sin(theta));target_height = Math.abs(source.height * Math.cos(theta)+ source.width * Math.sin(theta));} else {target_width = Math.abs(source.width * Math.cos(theta)- source.height * Math.sin(theta));target_height = Math.abs(source.height * Math.cos(theta)- source.width * Math.sin(theta));}Dimension target = new Dimension();target.setSize(target_width, target_height);return target;}/** * 获取旋转并裁剪后的图片 *  * @param src *            源图片 * @return 旋转并裁剪后的图片 */protected final BufferedImage rotate_CropImage(BufferedImage src) {// 原图大小Dimension source = new Dimension(src.getWidth(), src.getHeight());// 旋转后大小Dimension target = this.getTargetDimension(source);// 旋转并裁剪后的目标图片BufferedImage rotate_crop_Image = new BufferedImage(this.width,this.height, BufferedImage.TYPE_INT_RGB);Graphics2D rotate_crop_g2d = rotate_crop_Image.createGraphics();// 设置填充色为白色rotate_crop_g2d.setColor(Color.WHITE);rotate_crop_g2d.fillRect(0, 0, this.width, this.height);// transform;translate(x,y)是将坐标系往右平移x,往下平移y,(x,y的正负对应正反方向)rotate_crop_g2d.translate((target.width - source.width) / 2 - this.x,(target.height - source.height) / 2 - this.y);// 平移坐标系(以便后面将原图画上去)// rotate 旋转坐标系rotate_crop_g2d.rotate(Math.toRadians(this.rotate), source.width / 2,source.height / 2);// 旋转坐标系、注意旋转中心rotate_crop_g2d.translate((1-this.scaleX)*source.width/2, (1-this.scaleY)*source.height/2);// 将图画上去rotate_crop_g2d.drawImage(src,AffineTransform.getScaleInstance(this.scale*this.scaleX, this.scale*this.scaleY), null);// 画图rotate_crop_g2d.dispose();return rotate_crop_Image;}/** * 获取旋转并裁剪后的图片二进制流 *  * @param inputStream *            图片文件输入流 * @param imageType *            图片文件类型(jpeg,png,jpg,gif等) * @return 旋转并裁剪后的图片二进制流 */public byte[] rotate_CropImage(InputStream inputStream, String imageType) {byte[] result = new byte[] {};ByteArrayOutputStream outputStream = new ByteArrayOutputStream();try {if (StringUtils.equalsIgnoreCase(imageType, "gif")) {/*----------------AnimatedGifEncoder.java处理----------------------*/GifDecoder decoder = new GifDecoder();decoder.read(inputStream);AnimatedGifEncoder encoder = new AnimatedGifEncoder();encoder.start(outputStream);// 若要生成gif图片则使用encoder.start("xxx.gif");encoder.setRepeat(decoder.getLoopCount());for (int i = 0, n = decoder.getFrameCount(); i < n; i++) {encoder.setDelay(decoder.getDelay(i));encoder.addFrame(this.rotate_CropImage(decoder.getFrame(i)));}encoder.finish();} else {// 其他格式图片文件处理ImageIO.write(this.rotate_CropImage(ImageIO.read(inputStream)),imageType, outputStream);}result = outputStream.toByteArray();} catch (IOException e) {e.printStackTrace();} finally {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}return result;}}


说明:此类是基于Cropper插件的几个裁剪数据而建的,可处理动态图,动态图处理部分是在网上找的几个处理gif的类.

这里打成了jar包方便使用:http://download.csdn.net/download/xinshijimanon/9796051;

此类的重点是后三个方法,由于本人表达能力先天欠缺难过,就不详细熬叙此方法了(主要是获取旋转后的图片大小,以及在scaleX,scaleY不为1时如何将坐标系平移、旋转到正确位置)。

二、前台部分代码:

我这里是以弹窗的形式弹出修改头像框的,用的是layer插件,请酌情替换.

1、html/jsp

<!-- 修改头像2 --><div id="editPhotoDialog" class="dialog"><label class="btn btn-primary btn-upload" for="inputImage" style="margin: 15px;"><input type="file" class="sr-only" id="inputImage" accept=".jpg,.jpeg,.png,.gif,.bmp"><span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="上传图片文件(.jpg、.jpeg、.png、.gif、.bmp)"><span class="icon icon-upload"> 选择图片</span></span></label><div><div class="col-md-8">        <!-- <h3>Demo:</h3> -->        <div class="img-container" style="width:390px;height:390px;">        <img id="image" src="">        </div>    </div>    <div class="col-md-3">        <!-- <h3>Preview:</h3> -->        <div class="docs-preview clearfix">          <div class="img-preview preview-lg"></div>          <div class="img-preview preview-md"></div>          <div class="img-preview preview-sm"></div>          <div class="img-preview preview-xs"></div>        </div>    </div>    </div>            <div>    <div class="col-md-9 docs-buttons">    <div class="btn-group">          <button class="btn btn-primary" data-method="zoom" data-option="0.1" type="button" title="Zoom In">           <span class="docs-tooltip" data-toggle="tooltip" title="放大">              <span class="icon icon-zoom-in"></span>            </span>          </button>          <button class="btn btn-primary" data-method="zoom" data-option="-0.1" type="button" title="Zoom Out">            <span class="docs-tooltip" data-toggle="tooltip" title="缩小">              <span class="icon icon-zoom-out"></span>            </span>          </button>          <button class="btn btn-primary" data-method="rotate" data-option="-45" type="button" title="Rotate Left">            <span class="docs-tooltip" data-toggle="tooltip" title="左旋转45度">              <span class="icon icon-rotate-left"></span>            </span>          </button>          <button class="btn btn-primary" data-method="rotate" data-option="45" type="button" title="Rotate Right">            <span class="docs-tooltip" data-toggle="tooltip" title="右旋转45度">              <span class="icon icon-rotate-right"></span>            </span>          </button>        </div>                <div class="btn-group">          <button type="button" class="btn btn-primary" data-method="move" data-option="-2" data-second-option="0" title="Move Left">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="左移">              <span class="icon icon-arrow-left"></span>            </span>          </button>          <button type="button" class="btn btn-primary" data-method="move" data-option="2" data-second-option="0" title="Move Right">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="右移">              <span class="icon icon-arrow-right"></span>            </span>          </button>          <button type="button" class="btn btn-primary" data-method="move" data-option="0" data-second-option="-2" title="Move Up">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="上移">              <span class="icon icon-arrow-up"></span>            </span>          </button>          <button type="button" class="btn btn-primary" data-method="move" data-option="0" data-second-option="2" title="Move Down">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="下移">              <span class="icon icon-arrow-down"></span>            </span>          </button>       </div>              <div class="btn-group">          <button type="button" class="btn btn-primary" data-method="addScaleX" data-option="0.08" data-second-option="2" data-three-option="3" title="Flip Horizontal">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="水平放大">              <span class="icon  icon-chevron-left"></span>            </span>          </button>          <button type="button" class="btn btn-primary" data-method="addScaleX" data-option="-0.08" data-second-option="2" data-three-option="3" title="Flip Horizontal">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="水平缩小">              <span class="icon icon-chevron-right"></span>            </span>          </button>          <button type="button" class="btn btn-primary" data-method="addScaleY" data-option="0.08" data-second-option="2" data-three-option="3" title="Flip Vertical">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="竖直放大">              <span class="icon  icon-chevron-up"></span>            </span>          </button>          <button type="button" class="btn btn-primary" data-method="addScaleY" data-option="-0.08" data-second-option="2" data-three-option="3" title="Flip Vertical">            <span class="docs-tooltip" data-toggle="tooltip" data-animation="false" title="竖直缩小">              <span class="icon icon-chevron-down"></span>            </span>          </button>       </div>    </div>    </div>    </div>

说明:可以看到最后一组按钮中有data-Method="addScaleX"或data-Method="addScaleY",这需要修改cropper.js的源码,添加addScaleX,addScaleY方法.

在cropper.js中找到scaleX,scaleY方法,在其后面分别添加这两个方法(分别用于在水平、垂直方向拉伸原图):

 /**   * add scaleX of the image   *   * @param {Number} addNumber   *    * @param {Number} decimalCount   *    * @param {Number} maxABS   *    */  addScaleX:function addScaleX(addNumber,decimalCount,maxABS){  var self = this;  var scaleX = self.image.scaleX;  scaleX+=addNumber;  if(decimalCount&&!isNaN(decimalCount)){  scaleX=scaleX.toFixed(parseInt(decimalCount));  }  if(scaleX>Math.abs(maxABS)||scaleX<-Math.abs(maxABS)){  return;  }  this.scaleX(scaleX);  },  /**   * add scaleY of the image   *   * @param {Number} addNumber   *    * @param {Number} decimalCount   *    * @param {Number} maxABS   *    */  addScaleY:function addScaleY(addNumber,decimalCount,maxABS){  var self = this;  var scaleY = self.image.scaleY;  scaleY+=addNumber;  if(decimalCount&&!isNaN(decimalCount)){  scaleY=scaleY.toFixed(parseInt(decimalCount));  }  if(scaleY>Math.abs(maxABS)||scaleY<-Math.abs(maxABS)){  return;  }  this.scaleY(scaleY);  },

2、js

$("a.editPhoto").on("click",function(){layer.closeAll();layer.open({type : 1,title : false,closeBtn : 1,shift : 2,shade : 0.01,shadeClose : false,area : ['600px','600px'],content : $("#editPhotoDialog"),btn : [ '确认', '取消' ],yes : function(index) { // 确认按钮if($("#image").attr("src")==""){layer.msg("未选择图片文件", {time : 1000});return;}var cropperData=$("#image").cropper("getData");var fd=new FormData();fd.append("file",$("#image").data("file"));fd.append("scaleX",cropperData.scaleX);fd.append("scaleY",cropperData.scaleY);fd.append("rotate",parseInt(cropperData.rotate));fd.append("x",parseInt(cropperData.x));fd.append("y",parseInt(cropperData.y));fd.append("width",parseInt(cropperData.width));fd.append("height",parseInt(cropperData.height));var loadIndex=0;$.ajax({url : "../../user/webSetPersonalPhoto",//设置个人头像接口type: 'post',data: fd,dataType: 'json',cache: false,processData: false,contentType: false,beforeSend: function(){layer.close(index);loadIndex = layer.load(1);},success:function(data, status, xhr, $form) {layer.msg(data.msg, {time : 1000});$("#header .userinfo div").css({//刷新个人头像"background-image" : "url(../../user/getPersonalPhoto?_="+ new Date().getTime()+ ")"});},complete : function(xhr, status, $form) {layer.close(loadIndex);if (status == "parsererror") {location.reload(true);// 刷新浏览器,类似于按F5}}});},end : function(index) {$("#image").cropper("destroy").attr("src","").data("file",null);}});});$(".btn-group").on('click', '[data-method]', function () {var $this = $(this);    var data = $this.data();    var $target;    var result;     if ($this.prop('disabled') || $this.hasClass('disabled')) {      return;    }    if ($("#image").data('cropper') && data.method) {      data = $.extend({}, data); // Clone a new one      if (typeof data.target !== 'undefined') {        $target = $(data.target);        if (typeof data.option === 'undefined') {          try {            data.option = JSON.parse($target.val());          } catch (e) {            console.log(e.message);          }        }      }      if (data.method === 'rotate') {      $("#image").cropper('clear');      }      if(data.method === 'addScaleX'||data.method === 'addScaleY'){      result = $("#image").cropper(data.method, data.option, data.secondOption,data.threeOption);      }else{      result = $("#image").cropper(data.method, data.option, data.secondOption);      }            if (data.method === 'rotate') {      $("#image").cropper('crop');      }      if ($.isPlainObject(result) && $target) {        try {          $target.val(JSON.stringify(result));        } catch (e) {          console.log(e.message);        }      }    }});var URL = window.URL || window.webkitURL;var uploadedImageURL;if (URL) {$('#inputImage').change(function (e) {var files = this.files;    var file;    if (files && files.length) {    file = files[0];    var errorMsg="";    if (!/^image\/\w+$/.test(file.type)) {    errorMsg="请选择图片文件";        }else if(file.size==0){        errorMsg="图片为空,请重新选择";    }else if(file.size>2048000){    errorMsg="图片大小超过最大限制(2MB)";    }    if(errorMsg!=""){    $("#inputImage").val("");    layer.msg(errorMsg,{time:1000});    return;    }    if (uploadedImageURL) {    URL.revokeObjectURL(uploadedImageURL);    }    uploadedImageURL = URL.createObjectURL(file);    $("#image").cropper("destroy").attr('src', uploadedImageURL).data('file',file).cropper({aspectRatio: 1 / 1,dragMode:"move",toggleDragModeOnDblclick:false,strict:true,minCanvasWidth: 50,//画布minCanvasHeight: 0,minCropBoxWidth: 50,//裁剪框minCropBoxHeight: 0,minContainerWidth: 50,//容器minContainerHeight: 50,/*viewMode:2,*/    preview: '.img-preview',    crop: function (e) {        }});    $("#inputImage").val("");    }});} else {$('#inputImage').prop('disabled', true).parent().addClass('disabled');}

说明:以上代码中使用的cropper版本是Cropper v3.0.0-beta,下载地址:https://github.com/fengyuanchen/cropper;

js部分使用的是FormData提交文件即裁剪旋转数据(因input file选择文件时再单击'取消'(而不是'打开')后file就没有了,造成不好的体验).

3、css

/* Basic *//* Main * ========================================================================== *//* Icons * -------------------------------------------------------------------------- */.icon {  display: inline-block;  width: 20px;  height: 20px;  background-image: url("../assets/img/icons.png");  vertical-align: middle;}.icon-move {  background-position: 0 0;}.icon-crop {  background-position: -30px 0;}.icon-zoom-in {  background-position: -60px 0;}.icon-zoom-out {  background-position: -90px 0;}.icon-rotate-left {  background-position: -120px 0;}.icon-rotate-right {  background-position: -150px 0;}.icon-lock {  background-position: -180px 0;}.icon-unlock {  background-position: -210px 0;}.icon-remove {  background-position: -240px 0;}.icon-refresh {  background-position: -270px 0;}.icon-upload {  background-position: -300px 0;}.icon-off {  background-position: -330px 0;}.icon-info {  background-position: -360px 0;}/* Alerts * -------------------------------------------------------------------------- */.docs-alert {  display: none;  position: fixed;  top: 20px;  left: 0;  right: 0;  height: 0;  text-align: center;  opacity: 0.9;}.docs-alert .message {  display: inline-block;  padding: 5px 10px;  border-radius: 2px;  background-color: #aaa;  color: #fff;}.docs-alert .primary {  background-color: #0074d9;}.docs-alert .success {  background-color: #2ecc40;}.docs-alert .info {  background-color: #39cccc;}.docs-alert .warning {  background-color: #ff851b;}.docs-alert .danger {  background-color: #ff4136;}/* Button * -------------------------------------------------------------------------- */.btn-primary {  border-color: #003973; /* hsb(210, 100%, 45%) */  background-color: #00468c; /* hsb(210, 100%, 55%) */}.btn-primary:hover,.btn-primary:focus,.btn-primary:active,.btn-primary.active,.btn-primary.active:focus,.btn-primary.active:hover {  border-color: #00264d; /* hsb(208, 100%, 10%) */  background-color: #003366; /* hsb(208, 100%, 40%) */}/* Basic style * -------------------------------------------------------------------------- */body {  overflow-x: hidden;}/* Header */.docs-header {  border-color: #003973;  background-color: #00468c;  color: #fff;}.docs-header .navbar-brand {  color: #eee;}.docs-header .navbar-toggle {  border-color: #003973;  background-color: #00468c;}.docs-header .navbar-toggle:hover,.docs-header .navbar-toggle:focus {  border-color: #003366;  background-color: #003973;}.docs-header .navbar-collapse {  border-color: #003973;}.docs-header .navbar-text {  color: #ddd;}.docs-header .navbar-nav > li > a {  color: #eee;}/* Content */.img-container,.img-preview {  background-color: #f7f7f7;  overflow: hidden;  width: 100%;  text-align: center;}.img-container {  min-height: 200px;  max-height: 390px;  margin-bottom: 20px;}@media (min-width: 768px) {  .img-container {    min-height: 390px;  }}.img-container > img {  max-width: 100%;}.docs-preview {  margin-left: 15px;  margin-bottom: 10px;}.img-preview {  float: left;  margin-right: 10px;  margin-bottom: 10px;  border: 1px solid grey;}.img-preview > img {  max-width: 100%;}.preview-lg {  width: 148px !important;  height: 148px !important;}.preview-md {  width: 78px !important;  height: 78px !important;}.preview-sm {  width: 39px !important;  height: 39px !important;}.preview-xs {  width: 25px !important;  height: 25px !important;  margin-right: 0;}.docs-data > .input-group {  margin-bottom: 10px;}.docs-data > .input-group > label {  min-width: 80px;}.docs-data > .input-group > span {  min-width: 50px;}.docs-buttons > .btn,.docs-buttons > .btn-group,.docs-buttons > .form-control {  margin-right: 5px;  margin-bottom: 10px;}.docs-toggles > .btn,.docs-toggles > .btn-group,.docs-toggles > .dropdown {  margin-bottom: 10px;}.docs-tooltip {  display: block;  margin: -6px -12px;  padding: 6px 12px;}.docs-tooltip > .icon {  margin: 0 -3px;  vertical-align: middle;}.tooltip-inner {  white-space: normal;}.btn-upload .tooltip-inner {  white-space: nowrap;}@media (max-width: 400px) {  .btn-group-crop {    margin-right: -15px!important;  }  .btn-group-crop > .btn {    padding-left: 5px;    padding-right: 5px;  }  .btn-group-crop .docs-tooltip {    margin-left: -5px;    margin-right: -5px;    padding-left: 5px;    padding-right: 5px;  }}.docs-options .dropdown-menu {  width: 100%;}.docs-options .dropdown-menu > li {  padding: 3px 20px;}.docs-options .dropdown-menu > li:hover {  background-color: #f7f7f7;}.docs-options .dropdown-menu > li > label {  display: block;}.docs-cropped .modal-body {  text-align: center;}.docs-cropped .modal-body > img,.docs-cropped .modal-body > canvas {  max-width: 100%;}


三、后台部分代码:

1、后台用的是spring的MultipartFile、Spring这部分的配置大致如下:

<!-- file uploader support --><bean id="multipartResolver"class="org.springframework.web.multipart.commons.CommonsMultipartResolver"><property name="defaultEncoding" value="UTF-8" /><property name="maxUploadSize" value="255541538" /></bean>
2、后台接口:(这里图片是以二进制流的形式存在数据库中的、请酌情修改)

/** 设置个人头像 * @param scaleX 裁剪参数scaleX * @param scaleY 裁剪参数scaleY * @param rotate 裁剪参数rotate * @param x 裁剪参数x * @param y 裁剪参数y * @param width 裁剪参数width * @param height 裁剪参数height * @param file 图片文件 * @return */@RequestMapping(value = "/webSetPersonalPhoto", method = RequestMethod.POST)@ResponseBodypublic Tidings<User> webSetPersonalPhoto(@RequestParam("scaleX") Double scaleX,@RequestParam("scaleY") Double scaleY,@RequestParam("rotate") Integer rotate,@RequestParam("x") Integer x,@RequestParam("y") Integer y,@RequestParam("width") Integer width,@RequestParam("height") Integer height,@RequestParam("file") MultipartFile file) {String fileName=file.getOriginalFilename().toLowerCase();String imageType=fileName.substring(fileName.lastIndexOf(".")+1);if (!fileName.matches(".*\\.(jpg|jpeg|png|gif|bmp)")) {return new Tidings<User>("failure", "请选择图片文件");}//初始化裁剪信息Cropper cropper=new Cropper(scaleX,scaleY,rotate, x, y, width, height);//设置目标图片宽度cropper.setFactWidth(512);Subject subject = SecurityUtils.getSubject();String username = (String) subject.getPrincipal();InputStream input;byte[] photo = null;try {input = file.getInputStream();photo=cropper.rotate_CropImage(input, imageType);input.close();} catch (IOException e) {e.printStackTrace();}User user=userServiceImpl.findByUsername(username);if (photo != null && this.userServiceImpl.updatePropByUsername(username, "personalPhoto", photo)) {return new Tidings<User>("success", "设置个人头像成功",user);} else {return new Tidings<User>("failure", "设置个人头像失败",user);}}


上面的SecurityUtils、Subject是Shiro权限框架中的东西,Tidings是封装返回结果的类.请酌情修改部分代码.

附:

1、Tiddings.java:

public class Tidings<T> {private String status;private String msg;private T t;public Tidings(){super();}public Tidings(String status,String msg){super();this.status=status;this.msg=msg;}public Tidings(String status,String msg,T t){super();this.status=status;this.msg=msg;this.t=t;}public String getStatus() {return status;}public void setStatus(String status) {this.status = status;}public String getMsg() {return msg;}public void setMsg(String msg) {this.msg = msg;}public T getT() {return t;}public void setT(T t) {this.t = t;}}
2、获取个人头像:

/** * 获取个人头像 *  * @param request * @param response */@RequestMapping(value = "/getPersonalPhoto", method = RequestMethod.GET)public void getPersonalPhoto(HttpServletRequest request, HttpServletResponse response) {Subject subject = SecurityUtils.getSubject();String username = (String) subject.getPrincipal();User user = this.userServiceImpl.findByUsername(username);byte[] b = user.getPersonalPhoto();if (b == null) {//未设置图片则用一张默认图片FileInputStream fis = null;try {fis = new FileInputStream(request.getSession().getServletContext().getRealPath("/") + "img/default_personalPhoto.png");b = new byte[fis.available()];fis.read(b);} catch (FileNotFoundException e) {e.printStackTrace();} catch (IOException e) {e.printStackTrace();} finally {if (fis != null) {try {fis.close();} catch (IOException e) {e.printStackTrace();}}}}response.setContentType("image/png");OutputStream out = null;try {out = response.getOutputStream();out.write(b);out.flush();} catch (Exception e) {e.printStackTrace();} finally {if (out != null) {try {out.close();} catch (IOException e) {e.printStackTrace();}}}}


0 0