目录
LoginInterceptorConfigurer.java
AddressCountLimitException.java
PasswordNotMatchException.java
UsernameDuplicateException.java
项目结构
src/main/java
cn.tedu.store
ServletInitializer.java
package cn.tedu.store;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
public class ServletInitializer extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(StoreApplication.class);
}
}
StoreApplication.java
package cn.tedu.store;
import javax.servlet.MultipartConfigElement;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.MultipartConfigFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.util.unit.DataSize;
@Configuration
@SpringBootApplication
@MapperScan("cn.tedu.store.mapper")
public class StoreApplication {
public static void main(String[] args) {
SpringApplication.run(StoreApplication.class, args);
}
@Bean
public MultipartConfigElement getMultipartConfigElement() {
MultipartConfigFactory factory
= new MultipartConfigFactory();
DataSize dataSize = DataSize.ofMegabytes(100);
factory.setMaxFileSize(dataSize);
factory.setMaxRequestSize(dataSize);
return factory.createMultipartConfig();
}
}
cn.tedu.store.aop
TimerAspect.java
package cn.tedu.store.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimerAspect {
@Around("execution(* cn.tedu.store.service.impl.*.*(..))")
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
// 记录起始时间
long start = System.currentTimeMillis();
// 执行连接点方法,即切面所在位置对应的方法
// 本例中表示执行注册或执行登录等
Object result = pjp.proceed();
// 记录结果时间
long end = System.currentTimeMillis();
// 计算耗时
System.err.println("耗时:" + (end - start) + "ms.");
// 返回连接点方法的返回值
return result;
}
}
cn.tedu.store.config
LoginInterceptorConfigurer.java
package cn.tedu.store.config;
import java.util.ArrayList;
import java.util.List;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import cn.tedu.store.interceptor.LoginInterceptor;
@Configuration
public class LoginInterceptorConfigurer
implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 创建拦截器对象
HandlerInterceptor interceptor
= new LoginInterceptor();
// 白名单
List<String> patterns = new ArrayList<>();
patterns.add("/bootstrap3/**");
patterns.add("/js/**");
patterns.add("/css/**");
patterns.add("/images/**");
patterns.add("/web/register.html");
patterns.add("/web/login.html");
patterns.add("/web/index.html");
patterns.add("/web/product.html");
patterns.add("/users/reg");
patterns.add("/users/login");
patterns.add("/districts/**");
patterns.add("/products/**");
// 通过注册工具添加拦截器
registry.addInterceptor(interceptor)
.addPathPatterns("/**")
.excludePathPatterns(patterns);
}
}
cn.tedu.store.controller
BaseController.java
package cn.tedu.store.controller;
import javax.servlet.http.HttpSession;
import org.springframework.web.bind.annotation.ExceptionHandler;
import cn.tedu.store.controller.ex.FileEmptyException;
import cn.tedu.store.controller.ex.FileSizeException;
import cn.tedu.store.controller.ex.FileStateException;
import cn.tedu.store.controller.ex.FileTypeException;
import cn.tedu.store.controller.ex.FileUploadException;
import cn.tedu.store.controller.ex.FileUploadIOException;
import cn.tedu.store.service.ex.AccessDeniedException;
import cn.tedu.store.service.ex.AddressCountLimitException;
import cn.tedu.store.service.ex.AddressNotFoundException;
import cn.tedu.store.service.ex.CartNotFoundException;
import cn.tedu.store.service.ex.DeleteException;
import cn.tedu.store.service.ex.InsertException;
import cn.tedu.store.service.ex.PasswordNotMatchException;
import cn.tedu.store.service.ex.ProductNotFoundException;
import cn.tedu.store.service.ex.ServiceException;
import cn.tedu.store.service.ex.UpdateException;
import cn.tedu.store.service.ex.UserNotFoundException;
import cn.tedu.store.service.ex.UsernameDuplicateException;
import cn.tedu.store.util.JsonResult;
/**
* 控制器类的基类
*/
public class BaseController {
/**
* 操作成功的状态码
*/
public static final int OK = 2000;
/**
* 从Session中获取uid
* @param session HttpSession对象
* @return 当前登录的用户的id
*/
protected final Integer getUidFromSession(HttpSession session) {
return Integer.valueOf(
session.getAttribute("uid").toString());
}
/**
* 从Session中获取用户名
* @param session HttpSession对象
* @return 当前登录的用户名
*/
protected final String getUsernameFromSession(HttpSession session) {
return session.getAttribute("username").toString();
}
@ExceptionHandler({ServiceException.class, FileUploadException.class})
public JsonResult<Void> handleException(Throwable e) {
JsonResult<Void> jr = new JsonResult<>(e);
if (e instanceof UsernameDuplicateException) {
jr.setState(4000);
} else if (e instanceof UserNotFoundException) {
jr.setState(4001);
} else if (e instanceof PasswordNotMatchException) {
jr.setState(4002);
} else if (e instanceof AddressCountLimitException) {
jr.setState(4003);
} else if (e instanceof AddressNotFoundException) {
jr.setState(4004);
} else if (e instanceof AccessDeniedException) {
jr.setState(4005);
} else if (e instanceof ProductNotFoundException) {
jr.setState(4006);
} else if (e instanceof CartNotFoundException) {
jr.setState(4007);
} else if (e instanceof InsertException) {
jr.setState(5000);
} else if (e instanceof UpdateException) {
jr.setState(5001);
} else if (e instanceof DeleteException) {
jr.setState(5002);
} else if (e instanceof FileEmptyException) {
jr.setState(6000);
} else if (e instanceof FileSizeException) {
jr.setState(6001);
} else if (e instanceof FileTypeException) {
jr.setState(6002);
} else if (e instanceof FileStateException) {
jr.setState(6003);
} else if (e instanceof FileUploadIOException) {
jr.setState(6004);
}
return jr;
}
}
AddressController.java
package cn.tedu.store.controller;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.store.entity.Address;
import cn.tedu.store.service.IAddressService;
import cn.tedu.store.util.JsonResult;
@RequestMapping("addresses")
@RestController
public class AddressController extends BaseController {
@Autowired
private IAddressService addressService;
@RequestMapping("addnew")
public JsonResult<Void> addnew(Address address, HttpSession session) {
// 从Session中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象的方法执行业务
addressService.addnew(uid, username, address);
// 响应成功
return new JsonResult<>(OK);
}
@GetMapping({"", "/"})
public JsonResult<List<Address>> getByUid(HttpSession session) {
Integer uid = getUidFromSession(session);
List<Address> data = addressService.getByUid(uid);
return new JsonResult<>(OK, data);
}
@RequestMapping("{aid}/set_default")
public JsonResult<Void> setDefault(
@PathVariable("aid") Integer aid,
HttpSession session) {
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
addressService.setDefault(aid, uid, username);
return new JsonResult<>(OK);
}
@RequestMapping("{aid}/delete")
public JsonResult<Void> delete(
@PathVariable("aid") Integer aid,
HttpSession session) {
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
addressService.delete(aid, uid, username);
return new JsonResult<>(OK);
}
}
CartController.java
package cn.tedu.store.controller;
import java.util.List;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.store.service.ICartService;
import cn.tedu.store.util.JsonResult;
import cn.tedu.store.vo.CartVO;
@RequestMapping("carts")
@RestController
public class CartController extends BaseController {
@Autowired
private ICartService cartService;
@RequestMapping("add_to_cart")
public JsonResult<Void> addToCart(Integer pid, Integer amount, HttpSession session) {
// 从Session中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象执行添加到购物车
cartService.addToCart(pid, amount, uid, username);
// 返回成功
return new JsonResult<>(OK);
}
@GetMapping({"", "/"})
public JsonResult<List<CartVO>> getVOByUid(HttpSession session) {
// 从Session中获取uid
Integer uid = getUidFromSession(session);
// 调用业务对象执行查询数据
List<CartVO> data = cartService.getVOByUid(uid);
// 返回成功与数据
return new JsonResult<>(OK, data);
}
@RequestMapping("{cid}/num/add")
public JsonResult<Integer> addNum(
@PathVariable("cid") Integer cid,
HttpSession session) {
// 从Session中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象执行增加数量
Integer data = cartService.addNum(cid, uid, username);
// 返回成功
return new JsonResult<>(OK, data);
}
@GetMapping("list")
public JsonResult<List<CartVO>> getVOByCids(Integer[] cids, HttpSession session) {
// 从Session中获取uid
Integer uid = getUidFromSession(session);
// 调用业务对象执行查询数据
List<CartVO> data = cartService.getVOByCids(cids, uid);
// 返回成功与数据
return new JsonResult<>(OK, data);
}
}
DistrictController.java
package cn.tedu.store.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.store.entity.District;
import cn.tedu.store.service.IDistrictService;
import cn.tedu.store.util.JsonResult;
@RestController
@RequestMapping("districts")
public class DistrictController extends BaseController {
@Autowired
private IDistrictService districtService;
@GetMapping({"", "/"})
public JsonResult<List<District>> getByParent(String parent) {
List<District> data = districtService.getByParent(parent);
return new JsonResult<>(OK, data);
}
}
OrderController.java
package cn.tedu.store.controller;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.store.entity.Order;
import cn.tedu.store.service.IOrderService;
import cn.tedu.store.util.JsonResult;
@RestController
@RequestMapping("orders")
public class OrderController extends BaseController {
@Autowired
private IOrderService orderService;
@RequestMapping("create")
public JsonResult<Order> create(
Integer aid, Integer[] cids,
HttpSession session) {
// 从Session中取出uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象执行业务
Order data = orderService.create(aid, cids, uid, username);
// 返回成功与数据
return new JsonResult<>(OK, data);
}
}
ProductController.java
package cn.tedu.store.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.store.entity.Product;
import cn.tedu.store.service.IProductService;
import cn.tedu.store.util.JsonResult;
@RestController
@RequestMapping("products")
public class ProductController extends BaseController {
@Autowired
private IProductService productService;
@RequestMapping("hot_list")
public JsonResult<List<Product>> getHotList() {
List<Product> data = productService.getHotList();
return new JsonResult<>(OK, data);
}
@GetMapping("{id}/details")
public JsonResult<Product> getById(@PathVariable("id") Integer id) {
// 调用业务对象执行获取数据
Product data = productService.getById(id);
// 返回成功和数据
return new JsonResult<>(OK, data);
}
}
TestController.java
package cn.tedu.store.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.store.service.ex.UsernameDuplicateException;
import cn.tedu.store.util.JsonResult;
@RestController
@Deprecated
public class TestController {
@RequestMapping("test")
public JsonResult<Void> test() {
throw new UsernameDuplicateException("xxx");
}
}
UserController.java
package cn.tedu.store.controller;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import cn.tedu.store.controller.ex.FileEmptyException;
import cn.tedu.store.controller.ex.FileSizeException;
import cn.tedu.store.controller.ex.FileStateException;
import cn.tedu.store.controller.ex.FileTypeException;
import cn.tedu.store.controller.ex.FileUploadIOException;
import cn.tedu.store.entity.User;
import cn.tedu.store.service.IUserService;
import cn.tedu.store.util.JsonResult;
/**
* 处理用户相关请求的控制器类
*/
@RequestMapping("users")
@RestController
public class UserController extends BaseController {
@Autowired
private IUserService userService;
@RequestMapping("reg")
public JsonResult<Void> reg(User user) {
// 调用业务对象执行注册
userService.reg(user);
// 返回
return new JsonResult<>(OK);
}
@RequestMapping("login")
public JsonResult<User> login(
String username, String password,
HttpSession session) {
// 调用业务对象的方法执行登录,并获取返回值
User data = userService.login(username, password);
System.err.println("UserController.login()");
System.err.println("\t成功登录的用户:" + data);
// 登录成功,将uid和username存入到Session中
session.setAttribute("uid", data.getUid());
session.setAttribute("username", data.getUsername());
Integer uid = getUidFromSession(session);
System.err.println("\tSession中的uid=" + uid);
// 将以上返回值和状态码OK封装到响应结果中,并返回
return new JsonResult<>(OK, data);
}
@RequestMapping("change_password")
public JsonResult<Void> changePassword(
String oldPassword, String newPassword,
HttpSession session) {
// 调用session.getAttribute()获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象执行修改密码
userService.changePassword(uid, username, oldPassword, newPassword);
// 返回成功
return new JsonResult<>(OK);
}
@GetMapping("get_by_uid")
public JsonResult<User> getByUid(HttpSession session) {
// 从Session中获取uid
Integer uid = getUidFromSession(session);
// 调用业务对象执行获取数据
User data = userService.getByUid(uid);
// 响应成功和数据
return new JsonResult<>(OK, data);
}
@RequestMapping("change_info")
public JsonResult<Void> changeInfo(User user, HttpSession session) {
// 从Session中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 调用业务对象执行修改用户资料
userService.changeInfo(uid, username, user);
// 响应成功
return new JsonResult<>(OK);
}
/**
* 头像文件大小的上限值
*/
public static final int AVATAR_MAX_SIZE = 600 * 1024;
/**
* 允许上传的头像的文件类型
*/
public static final List<String> AVATAR_TYPES = new ArrayList<String>();
/**
* 初始化允许上传的头像的文件类型
*/
static {
AVATAR_TYPES.add("image/jpeg");
AVATAR_TYPES.add("image/png");
AVATAR_TYPES.add("image/bmp");
AVATAR_TYPES.add("image/gif");
}
@PostMapping("change_avatar")
public JsonResult<String> changeAvatar(
@RequestParam("file") MultipartFile file,
HttpSession session) {
// 判断上传的文件是否为空
if (file.isEmpty()) {
// 是:抛出异常
throw new FileEmptyException("上传的头像文件不允许为空");
}
// 判断上传的文件大小是否超出限制值
if (file.getSize() > AVATAR_MAX_SIZE) {
// 是:抛出异常
throw new FileSizeException("不允许上传超过" + (AVATAR_MAX_SIZE / 1024) + "KB的头像文件");
}
// 判断上传的文件类型是否超出限制
String contentType = file.getContentType();
if (!AVATAR_TYPES.contains(contentType)) {
// 是:抛出异常
throw new FileTypeException("不支持使用该类型的文件作为头像,允许的文件类型:\n" + AVATAR_TYPES);
}
// 保存头像文件的文件夹
String parent = session.getServletContext().getRealPath("upload");
File dir = new File(parent);
if (!dir.exists()) {
dir.mkdirs();
}
// 保存的头像文件的文件名
String suffix = "";
String originalFilename = file.getOriginalFilename();
int i = originalFilename.lastIndexOf(".");
if (i > 0) {
suffix = originalFilename.substring(i);
}
String filename = UUID.randomUUID().toString() + suffix;
// 创建文件对象,表示保存的头像文件
File dest = new File(dir, filename);
// 执行保存头像文件
try {
file.transferTo(dest);
} catch (IllegalStateException e) {
// 抛出异常
throw new FileStateException(
"文件状态异常,可能文件已被移动或删除");
} catch (IOException e) {
// 抛出异常
throw new FileUploadIOException(
"上传文件时读写错误,请稍后再次尝试");
}
// 头像路径
String avatar = "/upload/" + filename;
// 从Session中获取uid和username
Integer uid = getUidFromSession(session);
String username = getUsernameFromSession(session);
// 将头像写入到数据库中
userService.changeAvatar(uid, username, avatar);
// 返回成功与头像路径
return new JsonResult<>(OK, avatar);
}
}
cn.tedu.store.controller.ex
FileUploadException.java
package cn.tedu.store.controller.ex;
/**
* 文件上传相关异常的基类
*/
public class FileUploadException extends RuntimeException {
private static final long serialVersionUID = -4816421833308748249L;
public FileUploadException() {
super();
}
public FileUploadException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public FileUploadException(String message, Throwable cause) {
super(message, cause);
}
public FileUploadException(String message) {
super(message);
}
public FileUploadException(Throwable cause) {
super(cause);
}
}
FileUploadIOException.java
package cn.tedu.store.controller.ex;
/**
* 上传文件时出现读写异常
*/
public class FileUploadIOException extends FileUploadException {
private static final long serialVersionUID = -1234089097804788587L;
public FileUploadIOException() {
super();
}
public FileUploadIOException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
}
public FileUploadIOException(String message, Throwable cause) {
super(message, cause);
}
public FileUploadIOException(String message) {
super(message);
}
public FileUploadIOException(Throwable cause) {
super(cause);
}
}
FileEmptyException.java
FileSizeException.java
FileStateException.java
FileTypeException.java
cn.tedu.store.entity
BaseEntity.java
package cn.tedu.store.entity;
import java.io.Serializable;
import java.util.Date;
/**
* 实体类的基类
*/
abstract class BaseEntity implements Serializable {
private static final long serialVersionUID = -3122958702938259476L;
private String createdUser;
private Date createdTime;
private String modifiedUser;
private Date modifiedTime;
public String getCreatedUser() {
return createdUser;
}
public void setCreatedUser(String createdUser) {
this.createdUser = createdUser;
}
public Date getCreatedTime() {
return createdTime;
}
public void setCreatedTime(Date createdTime) {
this.createdTime = createdTime;
}
public String getModifiedUser() {
return modifiedUser;
}
public void setModifiedUser(String modifiedUser) {
this.modifiedUser = modifiedUser;
}
public Date getModifiedTime() {
return modifiedTime;
}
public void setModifiedTime(Date modifiedTime) {
this.modifiedTime = modifiedTime;
}
@Override
public String toString() {
return "BaseEntity [createdUser=" + createdUser + ", createdTime=" + createdTime + ", modifiedUser="
+ modifiedUser + ", modifiedTime=" + modifiedTime + "]";
}
}
User.java
package cn.tedu.st