网站防止盗图北海哪里做网站
为了实现一个功能完善的个人博客系统,我们将使用Spring Boot作为框架,MySQL作为数据库,并引入Spring Security来处理用户认证和授权。以下是系统的详细设计和实现步骤:
## 项目结构
- `src/main/java/com/blog`
   - `controller`
   - `service`
   - `repository`
   - `model`
 - `src/main/resources`
   - `application.properties`
 - `pom.xml`
## 主要功能
1. 用户注册和登录
 2. 文章的增删改查(CRUD)
 3. 评论系统
 4. 标签系统
 5. 分页和搜索
 6. 富文本编辑器支持
## 项目初始化
### 1. `pom.xml` 配置
```xml
 <dependencies>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-data-jpa</artifactId>
     </dependency>
     <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-security</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-thymeleaf</artifactId>
     </dependency>
     <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-validation</artifactId>
     </dependency>
 </dependencies>
 ```
### 2. `application.properties` 配置
```properties
 spring.datasource.url=jdbc:mysql://localhost:3306/blog
 spring.datasource.username=root
 spring.datasource.password=root
spring.jpa.hibernate.ddl-auto=update
 spring.jpa.show-sql=true
 spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5Dialect
 ```
### 3. 数据库模型
#### 3.1 用户模型
```java
 @Entity
 public class User {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
    private String username;
     private String password;
     private String email;
    // Getters and Setters
 }
 ```
#### 3.2 文章模型
```java
 @Entity
 public class Post {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
    private String title;
     private String content;
     private LocalDateTime createdAt;
    @ManyToOne
     @JoinColumn(name = "user_id")
     private User user;
    @ManyToMany
     @JoinTable(
       name = "post_tag", 
       joinColumns = @JoinColumn(name = "post_id"), 
       inverseJoinColumns = @JoinColumn(name = "tag_id"))
     private Set<Tag> tags = new HashSet<>();
    // Getters and Setters
 }
 ```
#### 3.3 评论模型
```java
 @Entity
 public class Comment {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
    private String content;
     private LocalDateTime createdAt;
    @ManyToOne
     @JoinColumn(name = "post_id")
     private Post post;
    @ManyToOne
     @JoinColumn(name = "user_id")
     private User user;
    @ManyToOne
     @JoinColumn(name = "parent_comment_id")
     private Comment parentComment;
    @OneToMany(mappedBy = "parentComment", cascade = CascadeType.ALL)
     private List<Comment> replies = new ArrayList<>();
    // Getters and Setters
 }
 ```
#### 3.4 标签模型
```java
 @Entity
 public class Tag {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     private Long id;
private String name;
    @ManyToMany(mappedBy = "tags")
     private Set<Post> posts = new HashSet<>();
    // Getters and Setters
 }
 ```
### 4. 数据库仓库
#### 4.1 用户仓库
```java
 public interface UserRepository extends JpaRepository<User, Long> {
     Optional<User> findByUsername(String username);
 }
 ```
#### 4.2 文章仓库
```java
 public interface PostRepository extends JpaRepository<Post, Long> {
     Page<Post> findAll(Pageable pageable);
 }
 ```
#### 4.3 评论仓库
```java
 public interface CommentRepository extends JpaRepository<Comment, Long> {
     List<Comment> findByPostId(Long postId);
     List<Comment> findByParentCommentId(Long parentCommentId);
 }
 ```
#### 4.4 标签仓库
```java
 public interface TagRepository extends JpaRepository<Tag, Long> {
 }
 ```
### 5. 服务层
#### 5.1 用户服务
```java
 @Service
 public class UserService {
    @Autowired
     private UserRepository userRepository;
    @Autowired
     private PasswordEncoder passwordEncoder;
    public User save(User user) {
         user.setPassword(passwordEncoder.encode(user.getPassword()));
         return userRepository.save(user);
     }
    public Optional<User> findByUsername(String username) {
         return userRepository.findByUsername(username);
     }
 }
 ```
#### 5.2 文章服务
```java
 @Service
 public class PostService {
    @Autowired
     private PostRepository postRepository;
    public Post save(Post post) {
         post.setCreatedAt(LocalDateTime.now());
         return postRepository.save(post);
     }
    public Page<Post> findAll(Pageable pageable) {
         return postRepository.findAll(pageable);
     }
 }
 ```
#### 5.3 评论服务
```java
 @Service
 public class CommentService {
    @Autowired
     private CommentRepository commentRepository;
    public Comment save(Comment comment) {
         comment.setCreatedAt(LocalDateTime.now());
         return commentRepository.save(comment);
     }
    public List<Comment> findByPostId(Long postId) {
         return commentRepository.findByPostId(postId);
     }
    public List<Comment> findByParentCommentId(Long parentCommentId) {
         return commentRepository.findByParentCommentId(parentCommentId);
     }
 }
 ```
### 6. 控制器
#### 6.1 用户控制器
```java
 @Controller
 @RequestMapping("/users")
 public class UserController {
    @Autowired
     private UserService userService;
    @PostMapping("/register")
     public String register(@ModelAttribute User user) {
         userService.save(user);
         return "redirect:/login";
     }
 }
 ```
#### 6.2 文章控制器
```java
 @Controller
 @RequestMapping("/posts")
 public class PostController {
    @Autowired
     private PostService postService;
    @GetMapping
     public String list(Model model, Pageable pageable) {
         Page<Post> posts = postService.findAll(pageable);
         model.addAttribute("posts", posts);
         return "posts/list";
     }
    @PostMapping
     public String save(@ModelAttribute Post post) {
         postService.save(post);
         return "redirect:/posts";
     }
 }
 ```
#### 6.3 评论控制器
```java
 @Controller
 @RequestMapping("/comments")
 public class CommentController {
    @Autowired
     private CommentService commentService;
    @PostMapping
     public String save(@ModelAttribute Comment comment) {
         commentService.save(comment);
         return "redirect:/posts/" + comment.getPost().getId();
     }
 }
 ```
### 7. 前端模板(使用Thymeleaf)
#### 7.1 登录页面
```html
 <!DOCTYPE html>
 <html xmlns:th="http://www.thymeleaf.org">
 <head>
     <title>Login</title>
 </head>
 <body>
     <form th:action="@{/login}" method="post">
         <div>
             <label for="username">Username:</label>
             <input type="text" id="username" name="username" />
         </div>
         <div>
             <label for="password">Password:</label>
             <input type="password" id="password" name="password" />
         </div>
         <div>
             <button type="submit">Login</button>
         </div>
     </form>
 </body>
 </html>
 ```
#### 7.2 文章列表页面
```html
 <!DOCTYPE html>
 <html xmlns:th="http://www.thymeleaf.org">
 <head>
     <title>Posts</title>
 </head>
 <body>
     <div>
         <a th:href="@{/posts/new}">New Post</a>
     </div>
     <div>
         <ul>
             <li th:each="post : ${posts}">
                 <h2 th:text="${post.title}"></h2>
                 <p th:text="${post.content}"></p>
                 <p>By: <span th:text="${post.user.username}"></span></p>
                 <a th:href="@{/posts/{id}(id=${post.id})}">Read more</a>
             </li>
         </ul>
     </div>
 </body>
 </html>
 #### 7.3 文章详情页面
```html
 <!DOCTYPE html>
 <html xmlns:th="http://www.thymeleaf.org">
 <head>
     <title>Post Details</title>
 </head>
 <body>
     <h1 th:text="${post.title}"></h1>
     <p th:text="${post.content}"></p>
     <h2>Comments</h2>
     <div th:each="comment : ${comments}">
         <p th:text="${comment.content}"></p>
         <p>By: <span th:text="${comment.user.username}"></span></p>
         <div th:each="reply : ${comment.replies}">
             <p th:text="${reply.content}"></p>
             <p>By: <span th:text="${reply.user.username}"></span></p>
         </div>
         <form th:action="@{/comments}" method="post">
             <input type="hidden" th:value="${comment.id}" name="parentComment.id" />
             <textarea name="content"></textarea>
             <button type="submit">Reply</button>
         </form>
     </div>
 </body>
 </html>
 ### 8. 富文本编辑器支持
在Thymeleaf模板中添加TinyMCE的支持:
```html
 <!DOCTYPE html>
 <html xmlns:th="http://www.thymeleaf.org">
 <head>
     <title>New Post</title>
     <script src="https://cdn.tiny.cloud/1/no-api-key/tinymce/5/tinymce.min.js"></script>
     <script>
         tinymce.init({
             selector: '#content'
         });
     </script>
 </head>
 <body>
     <form th:action="@{/posts}" method="post">
         <div>
             <label for="title">Title:</label>
             <input type="text" id="title" name="title" />
         </div>
         <div>
             <label for="content">Content:</label>
             <textarea id="content" name="content"></textarea>
         </div>
         <div>
             <button type="submit">Save</button>
         </div>
     </form>
 </body>
 </html>
 ```
通过上述步骤,我们已经建立了一个功能完善的个人博客系统。这个系统包括用户注册和登录、文章的增删改查、评论和标签系统,以及富文本编辑器的支持。
