Java 商城后台管理系统

### 构建一个健壮的商城后台管理系统

使用Java Spring Boot框架和MySQL数据库,逐步构建一个健壮、安全、高效的商城后台管理系统。本文涵盖用户管理、商品管理、订单管理、分类管理、权限控制、日志记录、分页和排序、文件上传、缓存以及国际化。

---

#### 项目初始化

首先,我们使用Spring Initializr创建项目,选择以下依赖:
- Spring Web
- Spring Data JPA
- MySQL Driver
- Spring Security
- Spring Boot DevTools

#### 配置文件
在`src/main/resources/application.properties`中配置数据库连接:
```properties
spring.datasource.url=jdbc:mysql://localhost:3306/yourdatabase
spring.datasource.username=yourusername
spring.datasource.password=yourpassword
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
```

---

### 基本功能实现

#### 数据库模型

**用户实体**
```java
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String username;
    private String password;
    private String role;

    // getters and setters
}
```

**商品实体**
```java
@Entity
public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private BigDecimal price;
    private String description;
    private String category;

    // getters and setters
}
```

**订单实体**
```java
@Entity
public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private Long userId;
    private Long productId;
    private Integer quantity;
    private String status;

    // getters and setters
}
```

---

#### Repository接口

**UserRepository**
```java
public interface UserRepository extends JpaRepository<User, Long> {
    User findByUsername(String username);
}
```

**ProductRepository**
```java
public interface ProductRepository extends JpaRepository<Product, Long> {
}
```

**OrderRepository**
```java
public interface OrderRepository extends JpaRepository<Order, Long> {
}
```

---

#### 服务层

**UserService**
```java
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public User save(User user) {
        return userRepository.save(user);
    }

    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }
}
```

**ProductService**
```java
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public Product save(Product product) {
        return productRepository.save(product);
    }

    public List<Product> findAll() {
        return productRepository.findAll();
    }
}
```

**OrderService**
```java
@Service
public class OrderService {
    @Autowired
    private OrderRepository orderRepository;

    public Order save(Order order) {
        return orderRepository.save(order);
    }

    public List<Order> findAll() {
        return orderRepository.findAll();
    }
}
```

---

#### 控制器层

**UserController**
```java
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/register")
    public User register(@RequestBody User user) {
        return userService.save(user);
    }

    @GetMapping("/{username}")
    public User findByUsername(@PathVariable String username) {
        return userService.findByUsername(username);
    }
}
```

**ProductController**
```java
@RestController
@RequestMapping("/products")
public class ProductController {
    @Autowired
    private ProductService productService;

    @PostMapping
    public Product addProduct(@RequestBody Product product) {
        return productService.save(product);
    }

    @GetMapping
    public List<Product> getAllProducts() {
        return productService.findAll();
    }
}
```

**OrderController**
```java
@RestController
@RequestMapping("/orders")
public class OrderController {
    @Autowired
    private OrderService orderService;

    @PostMapping
    public Order createOrder(@RequestBody Order order) {
        return orderService.save(order);
    }

    @GetMapping
    public List<Order> getAllOrders() {
        return orderService.findAll();
    }
}
```

---

### 分类管理

**分类实体**
```java
@Entity
public class Category {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    private String name;

    // getters and setters
}
```

**CategoryRepository**
```java
public interface CategoryRepository extends JpaRepository<Category, Long> {
}
```

**CategoryService**
```java
@Service
public class CategoryService {
    @Autowired
    private CategoryRepository categoryRepository;

    public Category save(Category category) {
        return categoryRepository.save(category);
    }

    public List<Category> findAll() {
        return categoryRepository.findAll();
    }

    public void delete(Long id) {
        categoryRepository.deleteById(id);
    }
}
```

**CategoryController**
```java
@RestController
@RequestMapping("/categories")
public class CategoryController {
    @Autowired
    private CategoryService categoryService;

    @PostMapping
    public Category addCategory(@RequestBody Category category) {
        return categoryService.save(category);
    }

    @GetMapping
    public List<Category> getAllCategories() {
        return categoryService.findAll();
    }

    @DeleteMapping("/{id}")
    public void deleteCategory(@PathVariable Long id) {
        categoryService.delete(id);
    }
}
```

---

### 权限控制

**Spring Security 配置**
```java
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private UserService userService;

    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(userService).passwordEncoder(bCryptPasswordEncoder);
    }

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.csrf().disable()
            .authorizeRequests()
            .antMatchers("/users/register").permitAll()
            .antMatchers("/admin/**").hasRole("ADMIN")
            .anyRequest().authenticated()
            .and()
            .formLogin().permitAll()
            .and()
            .logout().permitAll();
    }
}
```

**密码编码器配置**
```java
@Configuration
public class WebConfig {
    @Bean
    public BCryptPasswordEncoder bCryptPasswordEncoder() {
        return new BCryptPasswordEncoder();
    }
}
```

**修改UserService以实现UserDetailsService**
```java
@Service
public class UserService implements UserDetailsService {
    @Autowired
    private UserRepository userRepository;

    public User save(User user) {
        user.setPassword(bCryptPasswordEncoder().encode(user.getPassword()));
        return userRepository.save(user);
    }

    public User findByUsername(String username) {
        return userRepository.findByUsername(username);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username);
        if (user == null) {
            throw new UsernameNotFoundException("User not found");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                AuthorityUtils.createAuthorityList(user.getRole()));
    }
}
```

---

### 统一异常处理

**自定义异常类**
```java
public class ResourceNotFoundException extends RuntimeException {
    public ResourceNotFoundException(String message) {
        super(message);
    }
}
```

**异常处理器**
```java
@ControllerAdvice
public class GlobalExceptionHandler {
    
    @ExceptionHandler(ResourceNotFoundException.class)
    public ResponseEntity<String> handleResourceNotFoundException(ResourceNotFoundException ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.NOT_FOUND);
    }

    @ExceptionHandler(Exception.class)
    public ResponseEntity<String> handleException(Exception ex) {
        return new ResponseEntity<>(ex.getMessage(), HttpStatus.INTERNAL_SERVER_ERROR);
    }
}
```

---

### 数据验证

**在实体类中添加验证注解**
```java
@Entity
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotBlank
    private String username;

    @NotBlank
    @Size(min = 6)
    private String password;

    private String role;

    // getters and setters
}
```

**在控制器方法中进行验证**
```java
@RestController
@RequestMapping("/users")
public class UserController {
    @Autowired
    private UserService userService;

    @PostMapping("/register")
    public User register(@Valid @RequestBody User user) {
        return userService.save(user);
    }

    @GetMapping("/{username}")
    public User findByUsername(@PathVariable String username) {
        return userService.findByUsername(username);
    }
}
```

**添加验证错误处理**
```java
@ControllerAdvice
public class ValidationExceptionHandler {

    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<Map<String, String>> handleValidationExceptions(MethodArgumentNotValidException ex) {
        Map<String, String> errors = new HashMap<>();
        ex.getBindingResult().getAllErrors().forEach(error -> {
            String fieldName = ((FieldError) error).getField();
            String errorMessage = error.getDefaultMessage();
            errors.put(fieldName, errorMessage);
        });
        return new ResponseEntity<>(errors, HttpStatus.BAD_REQUEST);
    }
}
```

---

### 日志记录

**添加日志依赖**
在`pom.xml`中添加依赖:
```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-logging</artifactId>
</dependency>
```

**创建日志配置**
在`src/main/resources/application.properties`中配置日志级别:
```properties
logging.level.root=INFO
logging.level.org.springframework.web=DEBUG
logging.file.name=app.log
```

**在各层添加日志**
例如在`UserService`中添加日志:
```java
@Service
public class UserService implements UserDetailsService {
    private static final Logger logger = LoggerFactory.getLogger(UserService.class);

    @Autowired
    private UserRepository userRepository;

    public User save(User user) {
        logger.info("Saving user: {}", user.getUsername());
        user.setPassword(bCryptPasswordEncoder().encode(user.getPassword()));
        return userRepository.save(user);
    }

    public User findByUsername(String username) {
        logger.info("Finding user by username: {}", username);
        return userRepository.findByUsername(username);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        logger.info("Loading user by username: {}", username);
        User user = userRepository.findByUsername(username);
        if (user == null) {
            logger.error("User not found: {}", username);
            throw new UsernameNotFoundException("User not found");
        }
        return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
                AuthorityUtils.createAuthorityList(user.getRole()));
    }
}
```

---

### 分页和排序

**在Repository接口中添加分页和排序方法**
```java
public interface ProductRepository extends JpaRepository<Product, Long> {
    Page<Product> findAll(Pageable pageable);
}
```

**在服务层添加分页和排序方法**
```java
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    public Page<Product> findAll(Pageable pageable) {
        return productRepository.findAll(pageable);
    }
}
```

**在控制器层添加分页和排序接口**
```java
@RestController
@RequestMapping("/products")
public class ProductController {
    @Autowired
    private ProductService productService;

    @GetMapping
    public Page<Product> getAllProducts(@RequestParam int page, @RequestParam int size) {
        Pageable pageable = PageRequest.of(page, size);
        return productService.findAll(pageable);
    }
}
```

---

### 文件上传

**添加文件上传依赖**
在`pom.xml`中添加依赖:
```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
```

**文件上传配置**
在`src/main/resources/application.properties`中配置文件上传路径:
```properties
spring.servlet.multipart.max-file-size=2MB
spring.servlet.multipart.max-request-size=2MB
file.upload-dir=uploads/
```

**创建文件上传控制器**
```java
@RestController
@RequestMapping("/files")
public class FileController {

    @Value("${file.upload-dir}")
    private String uploadDir;

    @PostMapping("/upload")
    public ResponseEntity<String> uploadFile(@RequestParam("file") MultipartFile file) {
        try {
            Path copyLocation = Paths
                .get(uploadDir + File.separator + StringUtils.cleanPath(file.getOriginalFilename()));
            Files.copy(file.getInputStream(), copyLocation, StandardCopyOption.REPLACE_EXISTING);
            return ResponseEntity.ok("File uploaded successfully: " + file.getOriginalFilename());
        } catch (Exception e) {
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Could not upload file: " + file.getOriginalFilename());
        }
    }
}
```

---

### 缓存

**添加缓存依赖**
在`pom.xml`中添加依赖:
```xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
```

**配置缓存**
在`src/main/resources/application.properties`中配置Redis:
```properties
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
```

**启用缓存**
在启动类中启用缓存:
```java
@SpringBootApplication
@EnableCaching
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
```

**在服务层使用缓存**
```java
@Service
public class ProductService {
    @Autowired
    private ProductRepository productRepository;

    @Cacheable("products")
    public List<Product> findAll() {
        return productRepository.findAll();
    }
}
```

---

### 国际化

**配置国际化资源文件**
在`src/main/resources`下创建国际化资源文件,如`messages.properties`和`messages_zh.properties`。

**配置国际化**
在`src/main/resources/application.properties`中配置国际化:
```properties
spring.messages.basename=messages
```

**创建国际化配置类**
```java
@Configuration
public class InternationalizationConfig {

    @Bean
    public LocaleResolver localeResolver() {
        SessionLocaleResolver localeResolver = new SessionLocaleResolver();
        localeResolver.setDefaultLocale(Locale.US);
        return localeResolver;
    }

    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor() {
        LocaleChangeInterceptor interceptor = new LocaleChangeInterceptor();
        interceptor.setParamName("lang");
        return interceptor;
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(localeChangeInterceptor());
    }
}
```

**在控制器中使用国际化**
```java
@RestController
public class GreetingController {

    @Autowired
    private MessageSource messageSource;

    @GetMapping("/greeting")
    public String greeting(@RequestParam(name = "lang", required = false) String lang) {
        return messageSource.getMessage("greeting.message", null, LocaleContextHolder.getLocale());
    }
}
```

---

通过这些步骤,构建了一个健壮的商城后台管理系统。该系统不仅包括基本的用户、商品和订单管理,还添加了分类管理、权限控制、统一异常处理、数据验证、日志记录、分页和排序、文件上传、缓存和国际化等功能,使系统更加完善和高效。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/761483.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

小型语言模型的兴起

过去几年&#xff0c;我们看到人工智能能力呈爆炸式增长&#xff0c;其中很大一部分是由大型语言模型 (LLM) 的进步推动的。GPT-3 等模型包含 1750 亿个参数&#xff0c;已经展示了生成类似人类的文本、回答问题、总结文档等能力。然而&#xff0c;虽然 LLM 的能力令人印象深刻…

海洋海事NEMA2000耐腐蚀不锈钢航空插头插座

海洋海事NEMA2000耐腐蚀不锈钢航空插头插座是为适应海洋环境中船舶使用的特殊要求而设计的。这类插头插座不仅要满足基本的电气连接功能&#xff0c;还要具备耐海水腐蚀、防水、防尘、防震等特性&#xff0c;以确保在恶劣的海上环境下仍能保持稳定的性能。 NMEA 2000插头插座的…

cesium自定义弹框

token记得换成您自己的&#xff01;&#xff01;&#xff01; 申请cesium的token 官网【Cesium: The Platform for 3D Geospatial】 pickEllipsoid在加载地形的情况下有一定误差&#xff0c;地形凹凸程度越大&#xff0c;误差越大。 pickPosition在depthTestAgainstTerrain …

3-数据提取方法1(json)(6节课学会爬虫)

3-数据提取方法1&#xff08;json&#xff09;&#xff08;6节课学会爬虫&#xff09; 1&#xff0c;Json2&#xff0c;哪里会返回json的数据&#xff08;值得尝试的操作&#xff09;3&#xff0c;Json字符串转换成字典或python类型进行数据提取&#xff08;1&#xff09;Json.…

人脸特征68点识别 C++

1、加载一张图片 main函数&#xff1a; cv::Mat img cv::imread("5.jpg");vector<Point2f> points_vec dectectFace68(img);2、人脸68特征识别函数 在这里vector<Point2f> dectectFace68(Mat src) {vector<Point2f> points_vec;int* pResults …

从0到1搭建微服务框架

目录 1.技术栈&#xff1a; 2.模块介绍: 3.关键代码讲解 3.1基础公共模块(common)依赖&#xff1a; 3.3授权模块(auth)依赖: 3.4授权模块核心配置类(AuthrizatonConfig): 3.4 SecurityConfig.java 3.5 bootstrap的核心配置文件(其他服务配置类似这个)&#xff1a; 3.6n…

视频编解码从H.264到H.266:浅析GB28181安防视频汇聚EasyCVR视频压缩技术

随着信息技术的飞速发展&#xff0c;视频编解码技术也在不断革新&#xff0c;以适应高清、超高清甚至8K视频时代的到来。视频编解码技术作为数字多媒体领域的核心技术之一&#xff0c;也在不断地演进和革新。从早期的H.261到现在的H.265、H.266&#xff0c;每一次技术的升级都极…

便携式气象站:科技助力,气象观测的新选择

在气象观测领域&#xff0c;便携式气象站不仅安装方便、操作简单&#xff0c;而且功能齐全、性能稳定&#xff0c;为气象观测带来了极大的便利。 首先&#xff0c;便携式气象站的便携性&#xff0c;与传统的气象站相比&#xff0c;它不需要复杂的安装过程和固定的设备基础&…

收银系统源码-千呼新零售2.0【移动管理端】

千呼新零售2.0系统是零售行业连锁店一体化收银系统&#xff0c;包括线下收银线上商城连锁店管理ERP管理商品管理供应商管理会员营销等功能为一体&#xff0c;线上线下数据全部打通。 适用于商超、便利店、水果、生鲜、母婴、服装、零食、百货、宠物等连锁店使用。 详细介绍请…

昂首资本实例使用价格行为策略,交易翻倍一点都不难

交易翻倍难吗&#xff1f;当Anzo Capital昂首资本使用价格行为策略进行交易时&#xff0c;发现一点都不难&#xff0c;以下是使用价格行为策略的实例分享&#xff1a; 1. 在初次交易信号出现时&#xff0c;推荐在1.00429价位入场&#xff0c;将止损设于1.04399&#xff0c;止盈…

微信小程序的在线客服系统源码 附带完整的源代码包以及搭建部署教程

系统概述 微信小程序的在线客服系统源码是一套专门为微信小程序开发的客服解决方案。它通过与微信小程序的紧密集成&#xff0c;为用户提供了便捷、高效的客服沟通渠道。该系统源码采用先进的技术架构&#xff0c;具备良好的稳定性和扩展性&#xff0c;能够满足不同规模企业的…

【数据结构】C语言实现二叉树的基本操作——二叉树的层次遍历、求深度、求结点数……

C语言实现二叉树的基本操作 导读一、层次遍历1.1 算法思路1.2 算法实现1.2.1 存储结构的选择1.2.2 函数的三要素1.2.3 函数的实现 1.3 小结 二、求二叉树的深度2.1 层序遍历2.2 分治思想——递归 三、 求二叉树的结点数3.1 求二叉树的结点总数3.1.1 层序遍历3.1.2 分治思想——…

Cherno 游戏引擎笔记 (45~60)

有几个部分的笔记以图片形式呈现&#xff08;如果没找到文本可以查看是否遗漏了图片笔记&#xff09; My Github REPO(GitHub - JJJJJJJustin/Nut: The game_engine which learned from Cherno) 源码笔记&#xff0c;希望帮到你 :-} ---Shader Library&#xff08;着色器库&…

[机器学习]-4 Transformer介绍和ChatGPT本质

Transformer Transformer是由Vaswani等人在2017年提出的一种深度学习模型架构&#xff0c;最初用于自然语言处理&#xff08;NLP&#xff09;任务&#xff0c;特别是机器翻译。Transformer通过自注意机制和完全基于注意力的架构&#xff0c;核心思想是通过注意力来捕捉输入序列…

什么是接口测试,我们如何实现接口测试?

1. 什么是接口测试 顾名思义&#xff0c;接口测试是对系统或组件之间的接口进行测试&#xff0c;主要是校验数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及相互逻辑依赖关系。其中接口协议分为HTTP,WebService,Dubbo,Thrift,Socket等类型&#xff0c;测试类型又主…

oracle plsql如何debug触发器

进入测试窗口 Test Window 写以下代码 declarebegininsert into tableA values();end; 如果tableA有insert触发器&#xff0c;插入数据的时候&#xff0c;就能进入触发器的代码里面

【区块链+基础设施】区块链服务网络 BSN | FISCO BCOS应用案例

BSN&#xff08;Blockchain-based Service Network&#xff0c;区块链服务网络&#xff09;是一个跨云服务、跨门户、跨底层框架&#xff0c;用于部 署和运行各类区块链应用的全球性基础设施网络&#xff0c;旨在为开发者提供低成本和技术互通的区块链一站式服务。 2019 年 12…

Android LayoutInflater 深度解析

在 Android 开发中&#xff0c;LayoutInflater 是一个非常重要的工具。它允许我们从 XML 布局文件中动态地创建 View 对象&#xff0c;从而使得 UI 的创建和管理更加灵活。本文将深入解析 android.view.LayoutInflater&#xff0c;包括它的基本用法、常见问题以及高级用法。 什…

stm32学习笔记---DMA直接存储器存取(代码部分)DMA数据转运/DMA+AD多通道

目录 第一个代码&#xff1a;DMA数据转运 扩展知识 DMA的配置步骤 DMA的库函数 DMA_DeInit DMA初始化和DMA结构体初始化函数 DMA_Cmd DMA_ITConfig DMA_SetCurrDataCounter DMA_GetCurrDataCounter 四个获取标志位状态函数 代码实现 MyDMA.c 第一步&#xff0c;开…

网站提示不安全怎么办

当您访问一个网站时&#xff0c;如果浏览器提示该网站不安全&#xff0c;这通常意味着以下几个问题之一&#xff0c;以及相应的解决办法&#xff1a; 一、未启用HTTPS协议&#xff1a; 解决方法&#xff1a;确保网站启用了HTTPS协议。这意味着您需要为您的网站部署一个有效的…