用户模块开发
Const:
package com.mmall.common; import com.google.common.collect.Sets; import java.util.Set; /** * Created by geely */ public class Const { public static final String CURRENT_USER = "currentUser"; public static final String EMAIL = "email"; public static final String USERNAME = "username"; public interface ProductListOrderBy{ Set<String> PRICE_ASC_DESC = Sets.newHashSet("price_desc","price_asc"); } public interface Cart{ int CHECKED = 1;//即购物车选中状态 int UN_CHECKED = 0;//购物车中未选中状态 String LIMIT_NUM_FAIL = "LIMIT_NUM_FAIL"; String LIMIT_NUM_SUCCESS = "LIMIT_NUM_SUCCESS"; } public interface Role{ int ROLE_CUSTOMER = 0; //普通用户 int ROLE_ADMIN = 1;//管理员 } public enum ProductStatusEnum{ ON_SALE(1,"在线"); private String value; private int code; ProductStatusEnum(int code,String value){ this.code = code; this.value = value; } public String getValue() { return value; } public int getCode() { return code; } } public enum OrderStatusEnum{ CANCELED(0,"已取消"), NO_PAY(10,"未支付"), PAID(20,"已付款"), SHIPPED(40,"已发货"), ORDER_SUCCESS(50,"订单完成"), ORDER_CLOSE(60,"订单关闭"); OrderStatusEnum(int code,String value){ this.code = code; this.value = value; } private String value; private int code; public String getValue() { return value; } public int getCode() { return code; } public static OrderStatusEnum codeOf(int code){ for(OrderStatusEnum orderStatusEnum : values()){ if(orderStatusEnum.getCode() == code){ return orderStatusEnum; } } throw new RuntimeException("么有找到对应的枚举"); } } public interface AlipayCallback{ String TRADE_STATUS_WAIT_BUYER_PAY = "WAIT_BUYER_PAY"; String TRADE_STATUS_TRADE_SUCCESS = "TRADE_SUCCESS"; String RESPONSE_SUCCESS = "success"; String RESPONSE_FAILED = "failed"; } public enum PayPlatformEnum{ ALIPAY(1,"支付宝"); PayPlatformEnum(int code,String value){ this.code = code; this.value = value; } private String value; private int code; public String getValue() { return value; } public int getCode() { return code; } } public enum PaymentTypeEnum{ ONLINE_PAY(1,"在线支付"); PaymentTypeEnum(int code,String value){ this.code = code; this.value = value; } private String value; private int code; public String getValue() { return value; } public int getCode() { return code; } public static PaymentTypeEnum codeOf(int code){ for(PaymentTypeEnum paymentTypeEnum : values()){ if(paymentTypeEnum.getCode() == code){ return paymentTypeEnum; } } throw new RuntimeException("么有找到对应的枚举"); } } }
ResponseCode:
package com.mmall.common; /** * Created by geely */ public enum ResponseCode { SUCCESS(0,"SUCCESS"), ERROR(1,"ERROR"), NEED_LOGIN(10,"NEED_LOGIN"), ILLEGAL_ARGUMENT(2,"ILLEGAL_ARGUMENT"); private final int code; private final String desc; ResponseCode(int code,String desc){ this.code = code; this.desc = desc; } public int getCode(){ return code; } public String getDesc(){ return desc; } }
ServerResponse:
package com.mmall.common; import org.codehaus.jackson.annotate.JsonIgnore; import org.codehaus.jackson.map.annotate.JsonSerialize; import java.io.Serializable; /** * Created by geely */ @JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) //保证序列化json的时候,如果是null的对象,key也会消失 public class ServerResponse<T> implements Serializable { private int status; private String msg; private T data; private ServerResponse(int status) { this.status = status; } private ServerResponse(int status, T data) { this.status = status; this.data = data; } private ServerResponse(int status, String msg, T data) { this.status = status; this.msg = msg; this.data = data; } private ServerResponse(int status, String msg) { this.status = status; this.msg = msg; } @JsonIgnore //使之不在json序列化结果当中 public boolean isSuccess() { return this.status == ResponseCode.SUCCESS.getCode(); } public int getStatus() { return status; } public T getData() { return data; } public String getMsg() { return msg; } public static <T> ServerResponse<T> createBySuccess() { return new ServerResponse<T>(ResponseCode.SUCCESS.getCode()); } public static <T> ServerResponse<T> createBySuccessMessage(String msg) { return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(), msg); } public static <T> ServerResponse<T> createBySuccess(T data) { return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(), data); } public static <T> ServerResponse<T> createBySuccess(String msg, T data) { return new ServerResponse<T>(ResponseCode.SUCCESS.getCode(), msg, data); } public static <T> ServerResponse<T> createByError() { return new ServerResponse<T>(ResponseCode.ERROR.getCode(), ResponseCode.ERROR.getDesc()); } public static <T> ServerResponse<T> createByErrorMessage(String errorMessage) { return new ServerResponse<T>(ResponseCode.ERROR.getCode(), errorMessage); } public static <T> ServerResponse<T> createByErrorCodeMessage(int errorCode, String errorMessage) { return new ServerResponse<T>(errorCode, errorMessage); } }
TokenCache:
package com.mmall.common; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; import com.google.common.cache.LoadingCache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.util.concurrent.TimeUnit; /** * Created by geely */ public class TokenCache { private static Logger logger = LoggerFactory.getLogger(TokenCache.class); public static final String TOKEN_PREFIX = "token_"; //LRU算法 private static LoadingCache<String,String> localCache = CacheBuilder.newBuilder().initialCapacity(1000).maximumSize(10000).expireAfterAccess(12, TimeUnit.HOURS) .build(new CacheLoader<String, String>() { //默认的数据加载实现,当调用get取值的时候,如果key没有对应的值,就调用这个方法进行加载. @Override public String load(String s) throws Exception { return "null"; } }); public static void setKey(String key,String value){ localCache.put(key,value); } public static String getKey(String key){ String value = null; try { value = localCache.get(key); if("null".equals(value)){ return null; } return value; }catch (Exception e){ logger.error("localCache get error",e); } return null; } }
UserController:
package com.mmall.controller.portal; import com.mmall.common.Const; import com.mmall.common.ResponseCode; import com.mmall.common.ServerResponse; import com.mmall.pojo.User; import com.mmall.service.IUserService; import com.sun.corba.se.spi.activation.Server; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpSession; /** * Created by geely */ @Controller @RequestMapping("/user/") public class UserController { @Autowired private IUserService iUserService; /** * 用户登录 * * @param username * @param password * @param session * @return */ @RequestMapping(value = "login.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<User> login(String username, String password, HttpSession session) { ServerResponse<User> response = iUserService.login(username, password); if (response.isSuccess()) { session.setAttribute(Const.CURRENT_USER, response.getData()); } return response; } @RequestMapping(value = "logout.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> logout(HttpSession session) { session.removeAttribute(Const.CURRENT_USER); return ServerResponse.createBySuccess(); } @RequestMapping(value = "register.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> register(User user) { return iUserService.register(user); } @RequestMapping(value = "check_valid.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> checkValid(String str, String type) { return iUserService.checkValid(str, type); } @RequestMapping(value = "get_user_info.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<User> getUserInfo(HttpSession session) { User user = (User) session.getAttribute(Const.CURRENT_USER); if (user != null) { return ServerResponse.createBySuccess(user); } return ServerResponse.createByErrorMessage("用户未登录,无法获取当前用户的信息"); } @RequestMapping(value = "forget_get_question.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> forgetGetQuestion(String username) { return iUserService.selectQuestion(username); } @RequestMapping(value = "forget_check_answer.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> forgetCheckAnswer(String username, String question, String answer) { return iUserService.checkAnswer(username, question, answer); } @RequestMapping(value = "forget_reset_password.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> forgetRestPassword(String username, String passwordNew, String forgetToken) { return iUserService.forgetResetPassword(username, passwordNew, forgetToken); } @RequestMapping(value = "reset_password.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<String> resetPassword(HttpSession session, String passwordOld, String passwordNew) { User user = (User) session.getAttribute(Const.CURRENT_USER); if (user == null) { return ServerResponse.createByErrorMessage("用户未登录"); } return iUserService.resetPassword(passwordOld, passwordNew, user); } @RequestMapping(value = "update_information.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<User> update_information(HttpSession session, User user) { User currentUser = (User) session.getAttribute(Const.CURRENT_USER); if (currentUser == null) { return ServerResponse.createByErrorMessage("用户未登录"); } user.setId(currentUser.getId()); user.setUsername(currentUser.getUsername()); ServerResponse<User> response = iUserService.updateInformation(user); if (response.isSuccess()) { response.getData().setUsername(currentUser.getUsername()); session.setAttribute(Const.CURRENT_USER, response.getData()); } return response; } @RequestMapping(value = "get_information.do", method = RequestMethod.POST) @ResponseBody public ServerResponse<User> get_information(HttpSession session) { User currentUser = (User) session.getAttribute(Const.CURRENT_USER); if (currentUser == null) { return ServerResponse.createByErrorCodeMessage(ResponseCode.NEED_LOGIN.getCode(), "未登录,需要强制登录status=10"); } return iUserService.getInformation(currentUser.getId()); } }
UserMapper:
package com.mmall.dao; import com.mmall.pojo.User; import org.apache.ibatis.annotations.Param; public interface UserMapper { int deleteByPrimaryKey(Integer id); int insert(User record); int insertSelective(User record); User selectByPrimaryKey(Integer id); int updateByPrimaryKeySelective(User record); int updateByPrimaryKey(User record); int checkUsername(String username); int checkEmail(String email); User selectLogin(@Param("username") String username, @Param("password") String password); String selectQuestionByUsername(String username); int checkAnswer(@Param("username") String username, @Param("question") String question, @Param("answer") String answer); int updatePasswordByUsername(@Param("username") String username, @Param("passwordNew") String passwordNew); int checkPassword(@Param(value = "password") String password, @Param("userId") Integer userId); int checkEmailByUserId(@Param(value = "email") String email, @Param(value = "userId") Integer userId); }
UserServiceImpl:
package com.mmall.service.impl; import com.mmall.common.Const; import com.mmall.common.ServerResponse; import com.mmall.common.TokenCache; import com.mmall.dao.UserMapper; import com.mmall.pojo.User; import com.mmall.service.IUserService; import com.mmall.util.MD5Util; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import java.util.UUID; /** * Created by geely */ @Service("iUserService") public class UserServiceImpl implements IUserService { @Autowired private UserMapper userMapper; @Override public ServerResponse<User> login(String username, String password) { int resultCount = userMapper.checkUsername(username); if (resultCount == 0) { return ServerResponse.createByErrorMessage("用户名不存在"); } String md5Password = MD5Util.MD5EncodeUtf8(password); User user = userMapper.selectLogin(username, md5Password); if (user == null) { return ServerResponse.createByErrorMessage("密码错误"); } user.setPassword(org.apache.commons.lang3.StringUtils.EMPTY); return ServerResponse.createBySuccess("登录成功", user); } public ServerResponse<String> register(User user) { ServerResponse validResponse = this.checkValid(user.getUsername(), Const.USERNAME); if (!validResponse.isSuccess()) { return validResponse; } validResponse = this.checkValid(user.getEmail(), Const.EMAIL); if (!validResponse.isSuccess()) { return validResponse; } user.setRole(Const.Role.ROLE_CUSTOMER); //MD5加密 user.setPassword(MD5Util.MD5EncodeUtf8(user.getPassword())); int resultCount = userMapper.insert(user); if (resultCount == 0) { return ServerResponse.createByErrorMessage("注册失败"); } return ServerResponse.createBySuccessMessage("注册成功"); } public ServerResponse<String> checkValid(String str, String type) { if (org.apache.commons.lang3.StringUtils.isNotBlank(type)) { //开始校验 if (Const.USERNAME.equals(type)) { int resultCount = userMapper.checkUsername(str); if (resultCount > 0) { return ServerResponse.createByErrorMessage("用户名已存在"); } } if (Const.EMAIL.equals(type)) { int resultCount = userMapper.checkEmail(str); if (resultCount > 0) { return ServerResponse.createByErrorMessage("email已存在"); } } } else { return ServerResponse.createByErrorMessage("参数错误"); } return ServerResponse.createBySuccessMessage("校验成功"); } public ServerResponse selectQuestion(String username) { ServerResponse validResponse = this.checkValid(username, Const.USERNAME); if (validResponse.isSuccess()) { //用户不存在 return ServerResponse.createByErrorMessage("用户不存在"); } String question = userMapper.selectQuestionByUsername(username); if (org.apache.commons.lang3.StringUtils.isNotBlank(question)) { return ServerResponse.createBySuccess(question); } return ServerResponse.createByErrorMessage("找回密码的问题是空的"); } public ServerResponse<String> checkAnswer(String username, String question, String answer) { int resultCount = userMapper.checkAnswer(username, question, answer); if (resultCount > 0) { //说明问题及问题答案是这个用户的,并且是正确的 String forgetToken = UUID.randomUUID().toString(); TokenCache.setKey(TokenCache.TOKEN_PREFIX + username, forgetToken); return ServerResponse.createBySuccess(forgetToken); } return ServerResponse.createByErrorMessage("问题的答案错误"); } public ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken) { if (org.apache.commons.lang3.StringUtils.isBlank(forgetToken)) { return ServerResponse.createByErrorMessage("参数错误,token需要传递"); } ServerResponse validResponse = this.checkValid(username, Const.USERNAME); if (validResponse.isSuccess()) { //用户不存在 return ServerResponse.createByErrorMessage("用户不存在"); } String token = TokenCache.getKey(TokenCache.TOKEN_PREFIX + username); if (org.apache.commons.lang3.StringUtils.isBlank(token)) { return ServerResponse.createByErrorMessage("token无效或者过期"); } if (org.apache.commons.lang3.StringUtils.equals(forgetToken, token)) { String md5Password = MD5Util.MD5EncodeUtf8(passwordNew); int rowCount = userMapper.updatePasswordByUsername(username, md5Password); if (rowCount > 0) { return ServerResponse.createBySuccessMessage("修改密码成功"); } } else { return ServerResponse.createByErrorMessage("token错误,请重新获取重置密码的token"); } return ServerResponse.createByErrorMessage("修改密码失败"); } public ServerResponse<String> resetPassword(String passwordOld, String passwordNew, User user) { //防止横向越权,要校验一下这个用户的旧密码,一定要指定是这个用户.因为我们会查询一个count(1),如果不指定id,那么结果就是true啦count>0; int resultCount = userMapper.checkPassword(MD5Util.MD5EncodeUtf8(passwordOld), user.getId()); if (resultCount == 0) { return ServerResponse.createByErrorMessage("旧密码错误"); } user.setPassword(MD5Util.MD5EncodeUtf8(passwordNew)); int updateCount = userMapper.updateByPrimaryKeySelective(user); if (updateCount > 0) { return ServerResponse.createBySuccessMessage("密码更新成功"); } return ServerResponse.createByErrorMessage("密码更新失败"); } public ServerResponse<User> updateInformation(User user) { //username是不能被更新的 //email也要进行一个校验,校验新的email是不是已经存在,并且存在的email如果相同的话,不能是我们当前的这个用户的. int resultCount = userMapper.checkEmailByUserId(user.getEmail(), user.getId()); if (resultCount > 0) { return ServerResponse.createByErrorMessage("email已存在,请更换email再尝试更新"); } User updateUser = new User(); updateUser.setId(user.getId()); updateUser.setEmail(user.getEmail()); updateUser.setPhone(user.getPhone()); updateUser.setQuestion(user.getQuestion()); updateUser.setAnswer(user.getAnswer()); int updateCount = userMapper.updateByPrimaryKeySelective(updateUser); if (updateCount > 0) { return ServerResponse.createBySuccess("更新个人信息成功", updateUser); } return ServerResponse.createByErrorMessage("更新个人信息失败"); } public ServerResponse<User> getInformation(Integer userId) { User user = userMapper.selectByPrimaryKey(userId); if (user == null) { return ServerResponse.createByErrorMessage("找不到当前用户"); } user.setPassword(org.apache.commons.lang3.StringUtils.EMPTY); return ServerResponse.createBySuccess(user); } //backend /** * 校验是否是管理员 * * @param user * @return */ public ServerResponse checkAdminRole(User user) { if (user != null && user.getRole().intValue() == Const.Role.ROLE_ADMIN) { return ServerResponse.createBySuccess(); } return ServerResponse.createByError(); } }
IUserService:
package com.mmall.service; import com.mmall.common.ServerResponse; import com.mmall.pojo.User; /** * Created by geely */ public interface IUserService { ServerResponse<User> login(String username, String password); ServerResponse<String> register(User user); ServerResponse<String> checkValid(String str, String type); ServerResponse selectQuestion(String username); ServerResponse<String> checkAnswer(String username, String question, String answer); ServerResponse<String> forgetResetPassword(String username, String passwordNew, String forgetToken); ServerResponse<String> resetPassword(String passwordOld, String passwordNew, User user); ServerResponse<User> updateInformation(User user); ServerResponse<User> getInformation(Integer userId); ServerResponse checkAdminRole(User user); }
MD5Util:
package com.mmall.util; import org.springframework.util.StringUtils; import java.security.MessageDigest; /** * Created by geely */ public class MD5Util { private static String byteArrayToHexString(byte b[]) { StringBuffer resultSb = new StringBuffer(); for (int i = 0; i < b.length; i++) resultSb.append(byteToHexString(b[i])); return resultSb.toString(); } private static String byteToHexString(byte b) { int n = b; if (n < 0) n += 256; int d1 = n / 16; int d2 = n % 16; return hexDigits[d1] + hexDigits[d2]; } /** * 返回大写MD5 * * @param origin * @param charsetname * @return */ private static String MD5Encode(String origin, String charsetname) { String resultString = null; try { resultString = new String(origin); MessageDigest md = MessageDigest.getInstance("MD5"); if (charsetname == null || "".equals(charsetname)) resultString = byteArrayToHexString(md.digest(resultString.getBytes())); else resultString = byteArrayToHexString(md.digest(resultString.getBytes(charsetname))); } catch (Exception exception) { } return resultString.toUpperCase(); } public static String MD5EncodeUtf8(String origin) { origin = origin + PropertiesUtil.getProperty("password.salt", ""); return MD5Encode(origin, "utf-8"); } private static final String hexDigits[] = {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"}; }
PropertiesUtil:
package com.mmall.util; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.io.IOException; import java.io.InputStreamReader; import java.util.Properties; /** * Created by geely */ public class PropertiesUtil { private static Logger logger = LoggerFactory.getLogger(PropertiesUtil.class); private static Properties props; static { String fileName = "mmall.properties"; props = new Properties(); try { props.load(new InputStreamReader(PropertiesUtil.class.getClassLoader().getResourceAsStream(fileName),"UTF-8")); } catch (IOException e) { logger.error("配置文件读取异常",e); } } public static String getProperty(String key){ String value = props.getProperty(key.trim()); if(StringUtils.isBlank(value)){ return null; } return value.trim(); } public static String getProperty(String key,String defaultValue){ String value = props.getProperty(key.trim()); if(StringUtils.isBlank(value)){ value = defaultValue; } return value.trim(); } }
mmall.properties:
ftp.server.ip=192.168.80.130 ftp.user=ftpuser ftp.pass=ftpuser ftp.server.http.prefix=http://img.happymmall.com/ password.salt = ouyan12433rewfdsc3sad!@#$%
UserManageController:
package com.mmall.controller.backend; import com.mmall.common.Const; import com.mmall.common.ServerResponse; import com.mmall.pojo.User; import com.mmall.service.IUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpSession; /** * Created by geely */ @Controller @RequestMapping("/manage/user") public class UserManageController { @Autowired private IUserService iUserService; @RequestMapping(value="login.do",method = RequestMethod.POST) @ResponseBody public ServerResponse<User> login(String username, String password, HttpSession session){ ServerResponse<User> response = iUserService.login(username,password); if(response.isSuccess()){ User user = response.getData(); if(user.getRole() == Const.Role.ROLE_ADMIN){ //说明登录的是管理员 session.setAttribute(Const.CURRENT_USER,user); return response; }else{ return ServerResponse.createByErrorMessage("不是管理员,无法登录"); } } return response; } }