<div style="display: none;" hidden="true" aria-hidden="true" data-nosnippet>Are you an LLM? You can read better optimized documentation at /pages/2d5f32.md for this page in Markdown format</div>
分类
后台添加分类
创建controller,CategoryController
java@Controller public class CategoryController { @Autowired CategoryService categoryService; // 后台添加目录 @PostMapping("/admin/category/add") @ResponseBody public ApiRestResponse addCategory(HttpSession session, @RequestBody AddCategoryReq addCategoryReq) { } }单独创建类:model/request/AddCategory
javapackage com.izhaong.mall.model.request; public class AddCategoryReq { private String name; private Integer type; private Integer parentId; private Integer orderNum; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public Integer getParentId() { return parentId; } public void setParentId(Integer parentId) { this.parentId = parentId; } public Integer getOrderNum() { return orderNum; } public void setOrderNum(Integer orderNum) { this.orderNum = orderNum; } }创建selectByName mapper
javapublic interface CategoryMapper { ... Category selectByName(String name); ... }xml<select id="selectByName" parameterType="java.lang.String" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from imooc_mall_category where name = #{name,jdbcType=VARCHAR} </select>
创建service接口及实现类CategoryService,CategoryServiceImpl
java
package com.izhaong.mall.service.impl;
import com.izhaong.mall.exception.MallException;
import com.izhaong.mall.exception.MallExceptionEnum;
import com.izhaong.mall.model.dao.CategoryMapper;
import com.izhaong.mall.model.pojo.Category;
import com.izhaong.mall.model.request.AddCategoryReq;
import com.izhaong.mall.service.CategoryService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
@Service
public class CategoryServiceImpl implements CategoryService {
CategoryMapper categoryMapper;
@Override
public void add(AddCategoryReq addCategoryReq) {
// 判断是否重名
Category category = new Category();
BeanUtils.copyProperties(addCategoryReq, category);
Category oldCate = categoryMapper.selectByName(addCategoryReq.getName());
// 是抛出异常 不添加
if (oldCate != null) {
throw new MallException(MallExceptionEnum.NAME_EXISTED);
} else {
// 不是重名就插入数据
int count = categoryMapper.insertSelective(category);
if (count == 0) {
throw new MallException(MallExceptionEnum.INSERT_FAILED);
}
}
}
}添加参数校验

在全局异常中处理
java@ExceptionHandler(MethodArgumentNotValidException.class) @ResponseBody public ApiRestResponse handleMethodArgumentNotValidException(MethodArgumentNotValidException e) { logger.error("MethodArgumentNotValidException:", e); return handleBindingResult(e.getBindingResult()); } private ApiRestResponse handleBindingResult(BindingResult result) { //把异常处理为对外暴露的提示 List<String> list = new ArrayList<>(); if (result.hasErrors()) { List<ObjectError> allErrors = result.getAllErrors(); // itli for (ObjectError objectError : allErrors) { String message = objectError.getDefaultMessage(); list.add(message); } } if (list.size() == 0) { return ApiRestResponse.error(MallExceptionEnum.REQUEST_PARAM_ERROR); } return ApiRestResponse.error(MallExceptionEnum.REQUEST_PARAM_ERROR.getCode(), list.toString()); }
swagger 整合
引入依赖
xml<dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> <version>2.9.2</version> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.9.2</version> </dependency>在mainApplication 中开启使用
java@EnableSwagger2 public class MallApplication { public static void main(String[] args) { SpringApplication.run(MallApplication.class, args); } }添加配置文件
java// com.izhaong.mall/config/SpringFoxConfig public class SpringFoxConfig { //访问http://localhost:8083/swagger-ui.html可以看到API文档 @Bean public Docket api() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } private ApiInfo apiInfo() { return new ApiInfoBuilder() .title("生鲜") .description("") .termsOfServiceUrl("") .build(); } }配置地址映射
java@Configuration public class MallWebMvcConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } }
添加注解使用
java// 后台添加目录 @ApiOperation("后台添加目录") @PostMapping("/admin/category/add") @ResponseBody public ApiRestResponse addCategory(HttpSession session, @Valid @RequestBody AddCategoryReq addCategoryReq) { ... }
更新分类
注意点:
更新时需要对名称做校验
java
// service
@Override
public void update(Category updateCategory) {
if (updateCategory.getName() != null) {
Category categoryOld = categoryMapper.selectByName(updateCategory.getName());
if (categoryOld != null && categoryOld.getId().equals(updateCategory.getId())) {
throw new MallException(MallExceptionEnum.NAME_EXISTED);
}
}
int count = categoryMapper.updateByPrimaryKeySelective(updateCategory);
if (count == 0) {
throw new MallException(MallExceptionEnum.UPDATE_FAILD);
}
}封装管理员校验过滤器
创建过滤器 AdminFilter
javapackage com.izhaong.mall.filter; public class AdminFilter implements Filter { ... }引入重写javax.servlet Filter
javapublic class AdminFilter implements Filter { @Autowired UserService userService; @Override public void init(FilterConfig filterConfig) throws ServletException { Filter.super.init(filterConfig); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpSession session = request.getSession(); User currentUser = (User) session.getAttribute(Constant.IMOOC_MALL_USER); if (currentUser == null) { PrintWriter out = new HttpServletResponseWrapper( (HttpServletResponse) servletResponse).getWriter(); out.write("{\n" + " \"status\": 10007,\n" + " \"msg\": \"NEED_LOGIN\",\n" + " \"data\": null\n" + "}"); out.flush(); out.close(); return; } //校验是否是管理员 boolean adminRole = userService.checkAdminRole(currentUser); if (adminRole) { filterChain.doFilter(servletRequest, servletResponse); } else { PrintWriter out = new HttpServletResponseWrapper( (HttpServletResponse) servletResponse).getWriter(); out.write("{\n" + " \"status\": 10009,\n" + " \"msg\": \"NEED_ADMIN\",\n" + " \"data\": null\n" + "}"); out.flush(); out.close(); } } @Override public void destroy() { Filter.super.destroy(); } }过滤器配置
javapackage com.imooc.mall.config; import com.imooc.mall.filter.AdminFilter; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; /** * 描述: Admin过滤器的配置 */ @Configuration public class AdminFilterConfig { @Bean public AdminFilter adminFilter() { return new AdminFilter(); } @Bean(name = "adminFilterConf") public FilterRegistrationBean adminFilterConfig() { FilterRegistrationBean filterRegistrationBean = new FilterRegistrationBean(); filterRegistrationBean.setFilter(adminFilter()); filterRegistrationBean.addUrlPatterns("/admin/category/*"); filterRegistrationBean.addUrlPatterns("/admin/product/*"); filterRegistrationBean.addUrlPatterns("/admin/order/*"); filterRegistrationBean.setName("adminFilterConf"); return filterRegistrationBean; } }在删除功能中测试
controller
javapackage com.izhaong.mall.contraoller; ... @ApiOperation("后台删除目录") @DeleteMapping("/admin/category/delete") @ResponseBody public ApiRestResponse updateCategory(@RequestParam Integer id) { categoryService.delete(id); return ApiRestResponse.success(); }service
javapackage com.izhaong.mall.service.impl; ... @Override public void delete(Integer id) { if (categoryMapper.selectByPrimaryKey(id) == null) { throw new MallException(MallExceptionEnum.DELETE_FAILED); } int i = categoryMapper.deleteByPrimaryKey(id); if (i == 0) { throw new MallException(MallExceptionEnum.DELETE_FAILED); } }
后台目录列表
controller
java@ApiOperation("后台目录列表") @GetMapping("/admin/category/list") @ResponseBody public ApiRestResponse listCategory(@RequestParam Integer pageNum, @RequestParam Integer pageSize) { PageInfo pageinfo = categoryService.listForAdmin(pageNum, pageSize); return ApiRestResponse.success(pageinfo); }service
java@Override public PageInfo listForAdmin(Integer pageNum, Integer pageSize) { ... }引入分页依赖
xml<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.13</version> </dependency>使用分页
java@Override public PageInfo listForAdmin(Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum, pageSize, "type,order_num"); List<Category> list = categoryMapper.selectList(); return new PageInfo(list); }添加list mapper
java@Mapper public interface CategoryMapper { ... List<Category> selectList(); ... }xml<select id="selectList" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from imooc_mall_category </select>
前台列表
controller
java@ApiOperation("前台目录列表") @GetMapping("/category/list") @ResponseBody public ApiRestResponse listCategory() { List<CategoryVO> list = categoryService.listForCustomer(); return ApiRestResponse.success(list); }service
java@Override public List<CategoryVO> listForCustomer() { return recursSelectList(0); } public List<CategoryVO> recursSelectList(Integer parentId) { List<CategoryVO> categoryVOList = new ArrayList<>(); List<Category> list = categoryMapper.selectByParentId(parentId); if (!CollectionUtils.isEmpty(list)) { for (int i = 0; i < list.size(); i++) { Category category = list.get(i); CategoryVO categoryVO = new CategoryVO(); BeanUtils.copyProperties(category, categoryVO); categoryVOList.add(categoryVO); categoryVO.setChildCategory(recursSelectList(categoryVO.getId())); } } return categoryVOList; }mapper
java@Repository public interface CategoryMapper { ... List<Category> selectCategoriesByParentId(Integer parentId); ... }xml<select id="selectByParentId" resultMap="BaseResultMap"> select <include refid="Base_Column_List" /> from imooc_mall_category where parent_id = #{parentId,jdbcType=INTEGER} </select>新建vo包,经过转换之后返回给前端的类
javapackage com.izhaong.mall.model.vo; import java.util.ArrayList; import java.util.Date; import java.util.List; public class CategoryVO { private Integer id; private String name; private Integer type; private Integer parentId; private Integer orderNum; private List<CategoryVO> childCategory = new ArrayList<>(); private Date createTime; private Date updateTime; public List<CategoryVO> getChildCategory() { return childCategory; } public void setChildCategory(List<CategoryVO> childCategory) { this.childCategory = childCategory; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name == null ? null : name.trim(); } public Integer getType() { return type; } public void setType(Integer type) { this.type = type; } public Integer getParentId() { return parentId; } public void setParentId(Integer parentId) { this.parentId = parentId; } public Integer getOrderNum() { return orderNum; } public void setOrderNum(Integer orderNum) { this.orderNum = orderNum; } public Date getCreateTime() { return createTime; } public void setCreateTime(Date createTime) { this.createTime = createTime; } public Date getUpdateTime() { return updateTime; } public void setUpdateTime(Date updateTime) { this.updateTime = updateTime; } }
redis 提高缓存
sprintboot集成redis
引入依赖
xml<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-cache</artifactId> </dependency>配置redis 连接
propertiesspring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=redispasswordmain注入 打开缓存功能
java@EnableCaching public class MallApplication { public static void main(String[] args) { SpringApplication.run(MallApplication.class, args); } }缓存配置
javapackage com.izhaong.mall.config; import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.cache.RedisCacheManager; import org.springframework.data.redis.cache.RedisCacheWriter; import org.springframework.data.redis.connection.RedisConnectionFactory; import java.time.Duration; /** * 描述: 缓存的配置类 */ @Configuration @EnableCaching public class CachingConfig { @Bean public RedisCacheManager redisCacheManager(RedisConnectionFactory connectionFactory) { RedisCacheWriter redisCacheWriter = RedisCacheWriter.lockingRedisCacheWriter(connectionFactory); RedisCacheConfiguration cacheConfiguration = RedisCacheConfiguration.defaultCacheConfig(); cacheConfiguration = cacheConfiguration.entryTtl(Duration.ofSeconds(30)); RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, cacheConfiguration); return redisCacheManager; } }使用,序列化class
javapackage com.imooc.mall.service.impl; ... @Override @Cacheable(value = "listForCustomer") public List<CategoryVO> listForCustomer() { return recursSelectList(0); } ...javapackage com.izhaong.mall.model.vo; import java.io.Serializable; ... public class CategoryVO implements Serializable { ... } ...
