1,背景

博客停了好久,主要是最近工作太忙了,还有就是身体状况没有以前那么好了,乘着国庆长假的空档,写下这篇一直想写的文章。

运营平台是我主要致力的一个项目,这个项目分为四个大部分,个人中心,充值中心,客服中心,家长监护,最近主要忙着个人中心的重写和丰富,关于个人中心,无非就是对平台用户信息的自我管理,以及一些对用户帐号的安全保护措施,下图的菜单非常简要的说明了个人中心的功能。个人觉得最值得关注的就是密保设置和修改头像,因为之前没有处理过类似的问题,本文主要记录对头像的处理过程以及思考,希望给碰到类似问题的苦逼程序员一点借鉴。

个人中心整体功能一览

2,头像处理xmind

叽歪一句,个人碰到问题的时候,首先会分析问题,在分析问题的基础上,得到整体的解决方案,然后一步步分解步骤,去实现,首先奉上我的解决方案,也许不是最优的,但是按照个人的知识和技能水平,绝对是可以实现的。

修改头像mind

3,实现步骤

按照我的mind,首先是上传图片,先上效果图,然后给出实现的代码。首先是整体的结构图,做的比较丑,别喷哥···

修改头像整体效果图

下面按照mind一步步实现,

首先:点击修改头像,弹出一个层,

第一步:弹出上传图片的层,上传图片到服务器

对实现细节不感冒的屌丝可以看看代码(结合哥的mind看可以事半功倍):

分层实现细节

Html结构层这个可以免了,一般都可以弄出来

Js连接层

首先是弹出一个上传图片的层,然后上传图片到服务器端。 $("#editHead").bind("click", function () {

showUploadDiv();

});

function showUploadDiv() {

$("#uploadMsg").empty();

$.fancybox({

type:'inline',

width:400,

href:'#uploadUserHead'

});

}//fancybox弹出层

上传的处理代码

Servlet服务端处理层(commonupload实现)服务器端处理代码

上传的处理代码

$(function () {

$("#uploadFrom").ajaxForm({

beforeSubmit:checkImg,

error:function(data,status){

alert(status+' , '+data);

$("#uploadMsg").html('上传文件超过1M!');

},

success:function (data,status) {

try{

var msg = $.parseJSON(data);

if (msg.code == 200)

{ //如果成功提交

javascript:$.fancybox.close();

$("#uploadUserHead").hide();

var data = msg.object;

$("#editImg").attr("src", data.path).show();

$("#preview1").attr("src", data.path).show();

$(".zoom").show();

$("#width").val(data.width);

$("#height").val(data.height);

$("#oldImgPath").val(data.realPath);

$("#imgFileExt").val(data.fileExt);

var api, jcrop_api, boundx, boundy;

$('#editImg').Jcrop({

onChange:updatePreview,

onSelect:updatePreview,

aspectRatio:1,

bgOpacity:0.5,

bgColor:'white',

addClass:'jcrop-light'

}, function () {

api = this;

api.setSelect([130, 65, 130 + 350, 65 + 285]);

api.setOptions({ bgFade:true });

api.ui.selection.addClass('jcrop-selection');

var bounds = this.getBounds();

boundx = bounds[0];

boundy = bounds[1];

jcrop_api = this;

});

function updatePreview(c) {

if (parseInt(c.w) > 0) {

var rx = 80 / c.w;

var ry = 80 / c.h;

$('#preview1').css({

width:Math.round(rx * boundx) + 'px',

height:Math.round(ry * boundy) + 'px',

marginLeft:'-' + Math.round(rx * c.x) + 'px',

marginTop:'-' + Math.round(ry * c.y) + 'px'

});

}

jQuery('#x').val(c.x);

jQuery('#y').val(c.y);

jQuery('#x2').val(c.x2);

jQuery('#y2').val(c.y2);

jQuery('#w').val(c.w);

jQuery('#h').val(c.h);

}

}

if (msg.code == 204) {

$("#uploadMsg").html(msg.msg);

}

}catch (e){

$("#uploadMsg").html('上传文件超过1M!');

}

}

});

});

//服务器端处理代码

String tempSavePath =  ConfigurationUtils.get("user.resource.dir"); //上传的图片零时保存路径

String tempShowPath =  ConfigurationUtils.get("user.resource.url"); //用户保存的头像路径

if(tempSavePath.equals("/img"))

{

tempSavePath=sc.getRealPath("/")+tempSavePath;

}

Msg msg = new Msg();

msg.setCode(204);

msg.setMsg("上传头像失败!");

String type = request.getParameter("type");

if (!Strings.isNullOrEmpty(type) && type.equals("first")) {

request.setCharacterEncoding("utf-8");

DiskFileItemFactory factory = new DiskFileItemFactory();

ServletFileUpload servletFileUpload = new ServletFileUpload(factory);

try {

List items = servletFileUpload.parseRequest(request);

Iterator iterator = items.iterator();

while (iterator.hasNext()) {

FileItem item = (FileItem) iterator.next();

if (!item.isFormField()) {

{

File tempFile = new File(item.getName());

File saveTemp = new File(tempSavePath+"/tempImg/");

String getItemName=tempFile.getName();

String fileName = UUID.randomUUID()+"." +getItemName.substring(getItemName.lastIndexOf(".") + 1, getItemName.length());

File saveDir = new File(tempSavePath+"/tempImg/", fileName);

//如果目录不存在,创建。

if (saveTemp.exists() == false) {

if (!saveTemp.mkdir()) { // 创建失败

saveTemp.getParentFile().mkdir();

saveTemp.mkdir();

} else {

}

}

if (saveDir.exists()) {

log.info("存在同名文件···");

saveDir.delete();

}

item.write(saveDir);

log.info("上传头像成功!"+saveDir.getName());

msg.setCode(200);

msg.setMsg("上传头像成功!");

Image image = new Image();

BufferedImage bufferedImage = null;

try {

bufferedImage = ImageIO.read(saveDir);

} catch (IOException e) {

e.printStackTrace();

}

image.setHeight(bufferedImage.getHeight());

image.setWidth(bufferedImage.getWidth());

image.setPath(tempShowPath+ "/tempImg/" + fileName);

log.info(image.getPath());

image.setRealPath(tempSavePath+"/tempImg/"+ fileName);

image.setFileExt(fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()));

msg.setObject(image);

}

} else {

log.info("" + item.getFieldName());

}

}

} catch (Exception ex) {

log.error("上传用户头像图片异常!");

ex.printStackTrace();

}

finally {

AppHelper.returnJsonAjaxForm(response, msg);

}

}

上传成功后,可以看到照片和照片的预览效果。看图:

上传头像之后的效果

Friday, October 05, 2012

第二步:编辑和保存头像

选中图中的区域,保存头像,就完成头像的修改。

修改之后的效果入下:

修改之后的头像(因为传了一张动态图片,得到的跟上图有些不同)

实现细节:

首先用了一个js控件:Jcrop,有兴趣的屌丝可以去搜一下,然后,利用上传之后的图片和之前的选定区域,完成了一个截图,保存为用户的头像。

连接层的js:

$("#saveHead").bind("click", function () {

var width = $("#width").val();

var height = $("#height").val();

var oldImgPath = $("#oldImgPath").val();

var imgFileExt = $("#imgFileExt").val();

var x = $('#x').val();

var y = $('#y').val();

var w = $('#w').val();

var h = $('#h').val();

$.ajax({

url:'/imgCrop',

type:'post',

data:{x:x, y:y, w:w, h:h, width:width, height:height, oldImgPath:oldImgPath, fileExt:imgFileExt},

datatype:'json',

success:function (msg) {

if (msg.code == 200) {

$("#avatar").attr("src", msg.object);

forword('/nav', 'index');

}

else {

alert(msg.msg);

}

}

});

});

function checkImg() {

//限制上传文件的大小和后缀名

var filePath = $("input[name='uploadImg']").val();

if (!filePath) {

$("#uploadMsg").html("请选择上传文件!").show();

return false;

}

else {

var extStart = filePath.lastIndexOf(".");

var ext = filePath.substring(extStart, filePath.length).toUpperCase();

if (ext != ".PNG" && ext != ".GIF" && ext != ".JPG") {

$("#uploadMsg").html("图片限于png,gif,jpg格式!").show();

return false;

}

}

return true;

}

服务器端处理代码:

String savePath =  ConfigurationUtils.get("user.resource.dir"); //上传的图片保存路径

String showPath =  ConfigurationUtils.get("user.resource.url"); //显示图片的路径

if(savePath.equals("/img"))

{

savePath=sc.getRealPath("/")+savePath;

}

int userId = AppHelper.getUserId(request);

String userName=AppHelper.getUserName(request);

Msg msg = new Msg();

msg.setCode(204);

msg.setMsg("剪切图片失败!");

if (userId <= 0) {

msg.setMsg("请先登录");

return;

}

// 用户经过剪辑后的图片的大小

Integer x = (int)Float.parseFloat(request.getParameter("x"));

Integer y = (int)Float.parseFloat(request.getParameter("y"));

Integer w = (int)Float.parseFloat(request.getParameter("w"));

Integer h = (int)Float.parseFloat(request.getParameter("h"));

//获取原显示图片路径 和大小

String oldImgPath = request.getParameter("oldImgPath");

Integer width = (int)Float.parseFloat(request.getParameter("width"));

Integer height = (int)Float.parseFloat(request.getParameter("height"));

//图片后缀

String imgFileExt = request.getParameter("fileExt");

String foldName="/"+ DateUtils.nowDatetoStrToMonth()+"/";

String imgName = foldName + UUID.randomUUID()+userName + "." + imgFileExt;

//组装图片真实名称

String createImgPath = savePath + imgName;

//进行剪切图片操作

ImageCut.abscut(oldImgPath,createImgPath, x*width/300, y*height/300, w*width/300, h*height/300);

File f = new File(createImgPath);

if (f.exists()) {

msg.setObject(imgName);

//把显示路径保存到用户信息下面。

UserService userService = userServiceProvider.get();

int rel = userService.updateUserAvatar(userId, showPath+imgName);

if (rel >= 1) {

msg.setCode(200);

msg.setMsg("剪切图片成功!");

log.info("剪切图片成功!");

//记录日志,更新session

log(showPath+imgName,userName);

UserObject userObject= userService.getUserObject(userName);

request.getSession().setAttribute("userObject", userObject);

if (userObject != null && Strings.isNullOrEmpty(userObject.getHeadDir()))

userObject.setHeadDir("/images/geren_right_01.jpg");

} else {

msg.setCode(204);

msg.setMsg("剪切图片失败!");

log.info("剪切图片失败!");

}

}

AppHelper.returnJson(response, msg);

File file=new File(oldImgPath);

boolean deleteFile= file.delete();

if(deleteFile==true)

{

log.info("删除原来图片成功");

}

/**

* 图像切割(改)     *

*

* @param srcImageFile 源图像地址

* @param dirImageFile 新图像地址

* @param x            目标切片起点x坐标

* @param y            目标切片起点y坐标

* @param destWidth    目标切片宽度

* @param destHeight   目标切片高度

*/

public static void abscut(String srcImageFile, String dirImageFile, int x, int y, int destWidth, int destHeight) {

try {

Image img;

ImageFilter cropFilter;

// 读取源图像

BufferedImage bi = ImageIO.read(new File(srcImageFile));

int srcWidth = bi.getWidth(); // 源图宽度

int srcHeight = bi.getHeight(); // 源图高度

if (srcWidth >= destWidth && srcHeight >= destHeight) {

Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);

// 改进的想法:是否可用多线程加快切割速度

// 四个参数分别为图像起点坐标和宽高

// 即: CropImageFilter(int x,int y,int width,int height)

cropFilter = new CropImageFilter(x, y, destWidth, destHeight);

img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));

BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);

Graphics g = tag.getGraphics();

g.drawImage(img, 0, 0, null); // 绘制缩小后的图

g.dispose();

// 输出为文件

ImageIO.write(tag, "JPEG", new File(dirImageFile));

}

} catch (Exception e) {

e.printStackTrace();

}

}

最后一个处理的比较好的地方就是图片的存储路径问题:

我在服务器端的nginx中做了一个图片的地址映射,把图片放到了跟程序不同的路径中,每次存储图片都是存到图片路径中,客户端拿到图片的地址确实经过nginx映射过的地址。

还有就是关于限制上传图片的大小的问题:

我在服务器端显示了资源的最大大小为1M,当上传的资源超过1M,服务器自动报错413,通过异常处理,可以在客户端得到正确的提示信息。

4,总结优点和不足。

关于修改头像,这么做下来确实达到了目的,用户可以从容的修改头像,性能也还可以。但是,上传图片的大小判断是依靠服务器端来判断的,等待的时间比较久,改进的方向是使用flash控件来限制,使用flash来上传,也不会出现弹出层,这样比较大众化,更容易为用户接受一点。我会不断改进。

servlet修改用户头像_修改头像总结相关推荐

  1. mysql之库操作_创建用户_修改用户权限_修改用户密码

    用户操作: 1.create user 'Faye'@'127.0.0.1'IDENTIFIED BY '123'  #添加一个用户名字为Faye的用户,127.0.0.1为本机的ip,123为密码 ...

  2. ubuntu创建普通用户,删除用户,修改用户密码,修改用户名

    创建用户名为 user 的用户 1.进入root权限账号 su 2.添加普通用户名 useradd user 3.设置普通用户密码 passwd user 4.修改用户登入后所使用的shell use ...

  3. Web项目实战 | 购物系统v2.0 | 开发记录(五)使用base64编码实现头像修改 | 用户个人信息修改 | JQuery动态提示

    文章目录 以往记录 一.运行环境 二.实现头像修改 三.用户个人信息修改 四.Bug & DeBug 以往记录 Web项目实战 | 购物系统v2.0 | 开发记录(一)需求分析 | 技术选型 ...

  4. ubuntu修改登陆用户名称_修改ubuntu的用户名(注意用户名和主机名的区别)

    1.用户名是user,一个主机可以有多个主机; 主机名是 hostname,要修改,就去 /etc/hostname目录修改. 2.修改用户名: 比如我想把 用户名"sanshanxiash ...

  5. mysql5.7.26修改账号密码_修改mysql5.7的用户密码

    MySQL5.7版本加入了密码安全策略机制,修改用户的密码必须符合安全策略的规则,否则无法修改.这对于本地开发来说,有点不方便,密码太长容易忘记,我本地的MySQL密码一般都是123456,这样就不会 ...

  6. mysql 如何修改用户密码_如何更改MySQL用户密码

    在本教程中,我们将向您展示如何更改MySQL用户密码.这些说明应适用于任何现代Linux发行版,例如Ubuntu 18.04和CentOS7. 先决条件 根据系统上运行的MySQL或MariaDB服务 ...

  7. 修改密码问题_修改密码

    修改密码问题 As I'm writing this, most of us are stuck around the house due to Covid-19. If you're quarant ...

  8. ubuntu 添加、删除用户,修改用户名称,修改主机名

    添加用户 ubuntu添加用户操作如下: sudo adduser test 会自动同名组,创建/home/test/,从etc/skel/复制文件,并设定密码和相关初始身份信息 删除用户 ubunt ...

  9. 修改mysql编_修改mysql编码

    SHOW VARIABLES LIKE 'character%'; SET character_set_server = utf8; SET character_set_results = utf8; ...

最新文章

  1. 让 VAGRANT 启动并运行起来
  2. Fragment注入漏洞(CVE-2013-6271)检测
  3. python与excel的差别-python对Excel按条件进行内容补充(推荐)
  4. django.core.exceptions.ImproperlyConfigured: SQLite 3.8.3 or later is required (found 3.7.17).
  5. nginx的函数调用
  6. 使用Chrome开发者工具调试Android端内网页(微信,QQ,UC,App内嵌页等)
  7. javafx应用启动自动执行函数_JavaFx:Application start方法中的异常
  8. autocad完全应用指南_如何提高CAD画图的速度?有哪些途径和技法?【AutoCAD教程】...
  9. 使用Python迭代字符串中的每个字符
  10. 源代码分析工具推荐Understand
  11. C++ 中typedef用法
  12. 【unity地编】unity制作场景的流程和要点简要
  13. Office365强制Microsoft Authenticator验证登录如何关闭
  14. cadence如何导入gds_如何将Cadence的原理图和PCB转成PADS
  15. Java第一周学习总结
  16. 深度学习高手该怎样炼成?这位拿下阿里天池大赛冠军的中科院博士为你规划了一份专业成长路径
  17. “艺工交叉”--达芬奇的人生密码
  18. 【R文档】1 isolation.forest/孤立森林算法
  19. f2fs mkfs 格式化过程系列 0
  20. 驰骋股市!手把手教你如何用Python和数据科学赚钱?

热门文章

  1. 【Java学习之代码学习】 Prog25_求闰年个数的问题
  2. php读取excel文件的数据,如何使用php获取excel文件数据
  3. 游戏反外挂技术首次公开
  4. 人工智能常用评估指标
  5. 星淘惠:做跨境电商为什么要选择亚马逊?
  6. (十五)路过师大 - 4
  7. 【跟学C++】C++类与对象—构造函数—析构函数(Study10)
  8. 大数据Hadoop之——Zookeeper鉴权认证(Kerberos认证+账号密码认证)
  9. ubuntu下普通用户没有sudo权限的解决办法
  10. mes系统故障_MES系统解决了什么问题?