用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/doanchienthangdev/omgkit --skill spring命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | spring |
| description | Enterprise Spring Boot development with JPA, security, testing, and microservices patterns |
| category | frameworks |
| triggers | ["spring","spring boot","java spring","spring mvc","spring security","jpa","hibernate","java api"] |
Enterprise-grade Spring Boot development following industry best practices. This skill covers Spring Data JPA, Spring Security, REST APIs, validation, testing patterns, and microservices configurations used by top engineering teams.
Build scalable Java applications with confidence:
// src/main/java/com/example/model/User.java
package com.example.model;
import jakarta.persistence.*;
import lombok.*;
import org.hibernate.annotations.CreationTimestamp;
import org.hibernate.annotations.UpdateTimestamp;
import org.hibernate.annotations.UuidGenerator;
import java.time.LocalDateTime;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Entity
@Table(name = "users")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@Builder
public class User {
@Id
@UuidGenerator
private UUID id;
@Column(nullable = false, unique = true)
private String email;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String password;
@Enumerated(EnumType.STRING)
@Builder.Default
private UserRole role = UserRole.USER;
@Builder.Default
private Boolean isActive = true;
@CreationTimestamp
private LocalDateTime createdAt;
@UpdateTimestamp
private LocalDateTime updatedAt;
@OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
@Builder.Default
private Set<Membership> memberships = new HashSet<>();
public boolean isAdmin() {
return this.role == UserRole.ADMIN;
}
}
// src/main/java/com/example/model/Organization.java
@Entity
@Table(name = "organizations")
@Getter @Setter
@NoArgsConstructor @AllArgsConstructor
@Builder
public class Organization {
@Id
@UuidGenerator
private UUID id;
@Column(nullable = false)
private String name;
@Column(nullable = false, unique = true)
private String slug;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "owner_id", nullable = false)
private User owner;
@OneToMany(mappedBy = "organization", cascade = CascadeType.ALL)
@Builder.Default
private Set<Membership> memberships = new HashSet<>();
@CreationTimestamp
private LocalDateTime createdAt;
}
// src/main/java/com/example/dto/user/CreateUserRequest.java
package com.example.dto.user;
import jakarta.validation.constraints.*;
import lombok.Data;
@Data
public class CreateUserRequest {
@NotBlank(message = "Name is required")
@Size(min = 2, max = 100)
private String name;
@NotBlank(message = "Email is required")
@Email(message = "Invalid email format")
private String email;
@NotBlank(message = "Password is required")
@Size(min = 8, max = 128)
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d)(?=.*[@$!%*?&]).*$",
message = "Password must contain uppercase, lowercase, number and special character")
private String password;
private String role;
}
// src/main/java/com/example/dto/user/UserResponse.java
@Data
@Builder
public class UserResponse {
private UUID id;
private String email;
private String name;
private UserRole role;
private Boolean isActive;
private LocalDateTime createdAt;
public static UserResponse fromEntity(User user) {
return UserResponse.builder()
.id(user.getId())
.email(user.getEmail())
.name(user.getName())
.role(user.getRole())
.isActive(user.getIsActive())
.createdAt(user.getCreatedAt())
.build();
}
}
// src/main/java/com/example/dto/common/PaginatedResponse.java
<T> {
List<T> data;
page;
limit;
total;
totalPages;
hasMore;
<T, E> PaginatedResponse<T> {
PaginatedResponse.<T>builder()
.data(page.getContent().stream().map(mapper).toList())
.page(page.getNumber() + )
.limit(page.getSize())
.total(page.getTotalElements())
.totalPages(page.getTotalPages())
.hasMore(page.hasNext())
.build();
}
}
// src/main/java/com/example/repository/UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, UUID> {
Optional<User> findByEmail(String email);
boolean existsByEmail(String email);
@Query("""
SELECT u FROM User u
WHERE u.isActive = true
AND (:search IS NULL OR LOWER(u.name) LIKE LOWER(CONCAT('%', :search, '%'))
OR LOWER(u.email) LIKE LOWER(CONCAT('%', :search, '%')))
AND (:role IS NULL OR u.role = :role)
""")
Page<User> findAllWithFilters(
@Param("search") String search,
@Param("role") UserRole role,
Pageable pageable
);
}
// src/main/java/com/example/service/UserService.java
@Service
@RequiredArgsConstructor
@Transactional(readOnly = true)
public class UserService {
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
public PaginatedResponse<UserResponse> findAll(String search, String role, int page, int limit) {
UserRole userRole = role != null ? UserRole.valueOf(role.toUpperCase()) : null;
PageRequest pageRequest = PageRequest.of(page - 1, limit, Sort.by("createdAt").descending());
Page<User> users = userRepository.findAllWithFilters(search, userRole, pageRequest);
return PaginatedResponse.fromPage(users, UserResponse::fromEntity);
}
public UserResponse findById(UUID id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User not found with id: " + id));
return UserResponse.fromEntity(user);
}
@Transactional
public UserResponse create(CreateUserRequest request) {
if (userRepository.existsByEmail(request.getEmail())) {
throw ();
}
User.builder()
.email(request.getEmail().toLowerCase())
.name(request.getName())
.password(passwordEncoder.encode(request.getPassword()))
.role(request.getRole() != ? UserRole.valueOf(request.getRole().toUpperCase()) : UserRole.USER)
.build();
UserResponse.fromEntity(userRepository.save(user));
}
UserResponse {
userRepository.findById(id)
.orElseThrow(() -> ());
(request.getEmail() != && !request.getEmail().equals(user.getEmail())) {
(userRepository.existsByEmail(request.getEmail())) {
();
}
user.setEmail(request.getEmail().toLowerCase());
}
(request.getName() != ) user.setName(request.getName());
(request.getIsActive() != ) user.setIsActive(request.getIsActive());
UserResponse.fromEntity(userRepository.save(user));
}
{
(!userRepository.existsById(id)) {
();
}
userRepository.deleteById(id);
}
}
// src/main/java/com/example/controller/UserController.java
@RestController
@RequestMapping("/api/v1/users")
@RequiredArgsConstructor
@Tag(name = "Users", description = "User management endpoints")
public class UserController {
private final UserService userService;
@GetMapping
@PreAuthorize("hasRole('ADMIN')")
@Operation(summary = "List all users")
public ResponseEntity<PaginatedResponse<UserResponse>> findAll(
@RequestParam(required = false) String search,
@RequestParam(required = false) String role,
@RequestParam(defaultValue = "1") int page,
@RequestParam(defaultValue = "20") int limit
) {
return ResponseEntity.ok(userService.findAll(search, role, page, limit));
}
@GetMapping("/me")
@Operation(summary = "Get current user profile")
public ResponseEntity<UserResponse> getCurrentUser(@AuthenticationPrincipal User currentUser) {
return ResponseEntity.ok(userService.findById(currentUser.getId()));
}
@GetMapping("/{id}")
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<UserResponse> findById(@PathVariable UUID id) {
return ResponseEntity.ok(userService.findById(id));
}
@PostMapping
@PreAuthorize("hasRole('ADMIN')")
public ResponseEntity<UserResponse> {
ResponseEntity.status(HttpStatus.CREATED).body(userService.create(request));
}
ResponseEntity<UserResponse> {
ResponseEntity.ok(userService.update(id, request));
}
{
userService.delete(id);
}
}
// src/main/java/com/example/config/SecurityConfig.java
@Configuration
@EnableWebSecurity
@EnableMethodSecurity
@RequiredArgsConstructor
public class SecurityConfig {
private final JwtAuthenticationFilter jwtAuthFilter;
@Bean
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
http
.csrf(csrf -> csrf.disable())
.sessionManagement(session -> session.sessionCreationPolicy(SessionCreationPolicy.STATELESS))
.authorizeHttpRequests(auth -> auth
.requestMatchers("/api/v1/auth/**").permitAll()
.requestMatchers("/actuator/health").permitAll()
.requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
.anyRequest().authenticated()
)
.addFilterBefore(jwtAuthFilter, UsernamePasswordAuthenticationFilter.class);
return http.build();
}
@Bean
public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
}
// src/test/java/com/example/service/UserServiceTest.java
@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@Mock
private UserRepository userRepository;
@Mock
private PasswordEncoder passwordEncoder;
@InjectMocks
private UserService userService;
private User testUser;
@BeforeEach
void setUp() {
testUser = User.builder()
.id(UUID.randomUUID())
.email("test@example.com")
.name("Test User")
.role(UserRole.USER)
.isActive(true)
.build();
}
@Test
void findById_ShouldReturnUser_WhenUserExists() {
when(userRepository.findById(testUser.getId())).thenReturn(Optional.of(testUser));
UserResponse result = userService.findById(testUser.getId());
assertThat(result.getEmail()).isEqualTo(testUser.getEmail());
}
@Test
void findById_ShouldThrowNotFoundException_WhenUserNotFound() {
UUID id = UUID.randomUUID();
when(userRepository.findById(id)).thenReturn(Optional.empty());
assertThatThrownBy(() -> userService.findById(id))
.isInstanceOf(NotFoundException.class);
}
@Test
void create_ShouldCreateUser_WhenEmailIsUnique() {
CreateUserRequest request ();
request.setEmail();
request.setName();
request.setPassword();
(userRepository.existsByEmail(request.getEmail())).thenReturn();
(passwordEncoder.encode(request.getPassword())).thenReturn();
(userRepository.save(any(User.class))).thenReturn(testUser);
userService.create(request);
assertThat(result).isNotNull();
verify(userRepository).save(any(User.class));
}
{
();
request.setEmail();
(userRepository.existsByEmail(request.getEmail())).thenReturn();
assertThatThrownBy(() -> userService.create(request))
.isInstanceOf(ConflictException.class);
}
}
{
MockMvc mockMvc;
ObjectMapper objectMapper;
UserService userService;
Exception {
();
request.setEmail();
request.setName();
request.setPassword();
UserResponse.builder()
.email()
.name()
.build();
(userService.create(any())).thenReturn(response);
mockMvc.perform(post()
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(request)))
.andExpect(status().isCreated())
.andExpect(jsonPath().value());
}
Exception {
mockMvc.perform(get())
.andExpect(status().isForbidden());
}
}
@Service
@RequiredArgsConstructor
public class CachedUserService {
private final UserRepository userRepository;
@Cacheable(value = "users", key = "#id")
public UserResponse findById(UUID id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new NotFoundException("User not found"));
return UserResponse.fromEntity(user);
}
@CacheEvict(value = "users", key = "#id")
public void evictCache(UUID id) {}
}