Java与前端技术结合:Java + Vue.js实现前后端分离架构实践

举报
江南清风起 发表于 2025/06/10 18:04:46 2025/06/10
【摘要】 Java与前端技术结合:Java + Vue.js实现前后端分离架构实践 一、前后端分离架构概述在传统Web开发中,前后端代码通常耦合在一起(如JSP、Thymeleaf等模板技术),这导致开发效率低下、职责不清。现代Web开发已普遍采用前后端分离架构,其核心优势在于:职责分离:前端专注UI和交互,后端专注业务逻辑和数据处理并行开发:前后端可同时进行开发,通过接口契约进行协作技术栈自由:前...

Java与前端技术结合:Java + Vue.js实现前后端分离架构实践

一、前后端分离架构概述

在传统Web开发中,前后端代码通常耦合在一起(如JSP、Thymeleaf等模板技术),这导致开发效率低下、职责不清。现代Web开发已普遍采用前后端分离架构,其核心优势在于:

  1. 职责分离:前端专注UI和交互,后端专注业务逻辑和数据处理
  2. 并行开发:前后端可同时进行开发,通过接口契约进行协作
  3. 技术栈自由:前后端可独立选择最适合的技术栈
  4. 更好的可扩展性:前端可独立部署,后端可服务多个客户端

二、技术栈选型与项目搭建

2.1 后端技术栈

  • Java 17:使用最新LTS版本
  • Spring Boot 3.x:快速构建微服务
  • Spring Security:认证与授权
  • MyBatis-Plus:高效数据访问
  • Lombok:简化JavaBean编写

2.2 前端技术栈

  • Vue 3:组合式API
  • TypeScript:类型安全
  • Pinia:状态管理
  • Axios:HTTP客户端
  • Element Plus:UI组件库

2.3 项目初始化

后端项目结构

mvn archetype:generate -DgroupId=com.example -DartifactId=java-vue-demo \
-DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false

前端项目初始化

npm init vue@latest java-vue-demo-frontend
# 选择TypeScript, Pinia, Router等特性

三、后端API开发实战

3.1 用户管理模块实现

UserController.java

@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
    
    private final UserService userService;
    
    @GetMapping
    public ResponseEntity<PageResult<UserVO>> listUsers(
            @RequestParam(required = false) String username,
            @RequestParam(defaultValue = "1") Integer page,
            @RequestParam(defaultValue = "10") Integer size) {
        return ResponseEntity.ok(userService.listUsers(username, page, size));
    }
    
    @PostMapping
    public ResponseEntity<UserVO> createUser(@Valid @RequestBody UserCreateDTO dto) {
        return ResponseEntity.status(HttpStatus.CREATED)
                .body(userService.createUser(dto));
    }
    
    @GetMapping("/{id}")
    public ResponseEntity<UserVO> getUser(@PathVariable Long id) {
        return ResponseEntity.ok(userService.getUserById(id));
    }
}

统一响应封装

public class R<T> implements Serializable {
    private int code;
    private String msg;
    private T data;
    private long timestamp;
    
    public static <T> R<T> ok(T data) {
        return new R<T>()
                .setCode(200)
                .setMsg("success")
                .setData(data)
                .setTimestamp(System.currentTimeMillis());
    }
    
    // 其他响应方法...
}

3.2 Spring Security配置

@Configuration
@EnableWebSecurity
@RequiredArgsConstructor
public class SecurityConfig {
    
    private final JwtAuthenticationFilter jwtAuthFilter;
    
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .csrf(AbstractHttpConfigurer::disable)
            .authorizeHttpRequests(auth -> auth
                .requestMatchers("/api/auth/**").permitAll()
                .anyRequest().authenticated()
            )
            .sessionManagement(sess -> sess
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
            )
            .addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
        
        return http.build();
    }
    
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

四、前端Vue.js集成开发

4.1 Axios封装与API调用

http.ts (Axios实例封装)

import axios, { type InternalAxiosRequestConfig } from 'axios'

const service = axios.create({
  baseURL: import.meta.env.VITE_APP_API_BASE_URL,
  timeout: 5000
})

// 请求拦截
service.interceptors.request.use(
  (config: InternalAxiosRequestConfig) => {
    const token = localStorage.getItem('access_token')
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  error => {
    return Promise.reject(error)
  }
)

// 响应拦截
service.interceptors.response.use(
  response => {
    const res = response.data
    if (res.code !== 200) {
      return Promise.reject(new Error(res.msg || 'Error'))
    }
    return res
  },
  error => {
    return Promise.reject(error)
  }
)

export default service

userApi.ts (用户接口封装)

import http from './http'

export interface User {
  id: number
  username: string
  email: string
  roles: string[]
}

export const getUsers = (params?: any) => {
  return http.get<{ list: User[]; total: number }>('/api/users', { params })
}

export const createUser = (data: Omit<User, 'id'>) => {
  return http.post<User>('/api/users', data)
}

4.2 Pinia状态管理

useUserStore.ts

import { defineStore } from 'pinia'
import { getUsers, type User } from '@/api/userApi'

interface UserState {
  users: User[]
  total: number
  loading: boolean
}

export const useUserStore = defineStore('user', {
  state: (): UserState => ({
    users: [],
    total: 0,
    loading: false
  }),
  actions: {
    async fetchUsers(params?: any) {
      this.loading = true
      try {
        const res = await getUsers(params)
        this.users = res.data.list
        this.total = res.data.total
      } finally {
        this.loading = false
      }
    }
  },
  getters: {
    adminUsers: (state) => state.users.filter(user => 
      user.roles.includes('ADMIN'))
  }
})

五、前后端联调与优化

5.1 跨域解决方案

后端CORS配置

@Configuration
public class CorsConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("*")
                .allowedMethods("GET", "POST", "PUT", "DELETE")
                .allowedHeaders("*")
                .maxAge(3600);
    }
}

开发环境代理配置 (vite.config.ts)

export default defineConfig({
  server: {
    proxy: {
      '/api': {
        target: 'http://localhost:8080',
        changeOrigin: true,
        rewrite: (path) => path.replace(/^\/api/, '')
      }
    }
  }
})

5.2 接口文档集成

SpringDoc OpenAPI配置

@Configuration
@OpenAPIDefinition(
    info = @Info(
        title = "Java+Vue Demo API",
        version = "1.0",
        description = "前后端分离项目接口文档"
    )
)
public class OpenApiConfig {
    @Bean
    public OpenAPI customOpenAPI() {
        return new OpenAPI()
                .addSecurityItem(new SecurityRequirement().addList("JWT"))
                .components(new Components()
                        .addSecuritySchemes("JWT", new SecurityScheme()
                                .type(SecurityScheme.Type.HTTP)
                                .scheme("bearer")
                                .bearerFormat("JWT")));
    }
}

六、部署方案

6.1 生产环境部署架构

                          +-----------------+
                          |   Nginx (80)    |
                          +--------+--------+
                                   |
                   +---------------+---------------+
                   |                               |
           +-------+-------+               +-------+-------+
           |  Frontend    |               |  Backend      |
           |  (Vue Dist)  |               |  (Jar)       |
           +--------------+               +--------------+

6.2 Nginx配置示例

server {
    listen 80;
    server_name example.com;
    
    location / {
        root /var/www/html;
        try_files $uri $uri/ /index.html;
    }
    
    location /api {
        proxy_pass http://127.0.0.1:8080;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
    }
}

七、进阶优化方向

  1. 性能优化

    • 前端:路由懒加载、组件异步加载
    • 后端:缓存策略(Redis)、数据库优化
  2. 安全加固

    • JWT刷新机制
    • 接口防刷
    • XSS防护
  3. 微服务演进

    • Spring Cloud集成
    • 前端微应用架构(qiankun)
  4. DevOps集成

    • CI/CD流水线
    • 容器化部署(Docker+K8s)

结语

Java+Vue.js的前后端分离架构结合了Java生态的稳健性和Vue.js的灵活高效,是现代Web开发的优选方案。通过本文的实践,我们实现了:

  • 清晰的架构分层
  • 高效的开发体验
  • 完善的工程化实践
  • 可扩展的技术基础

随着技术的不断发展,前后端分离架构将继续演进,但核心的"关注点分离"思想将长期指导我们构建更高质量的Web应用系统。

image.png

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。