1. 项目概述
这个基于Java Spring Boot和Android的宠物中心信息管理系统,是我在开发实践中遇到的一个非常典型的移动端+服务端综合项目。系统主要解决宠物领养过程中信息不对称、流程繁琐的问题,通过数字化手段连接宠物救助中心和潜在领养者。
从技术架构上看,后端采用Spring Boot框架提供RESTful API服务,前端使用Android原生开发,同时通过uni-app实现了多端适配。这种架构组合既保证了后端服务的高效稳定,又能充分利用Android原生体验,还能覆盖更广泛的用户群体。
2. 技术架构解析
2.1 后端技术选型
选择Spring Boot作为后端框架主要基于以下几个考虑:
- 快速开发:Spring Boot的自动配置和起步依赖大大减少了样板代码
- 生态丰富:可以方便集成MyBatis、Redis等常用组件
- 微服务友好:便于后期扩展为微服务架构
核心依赖包括:
xml复制<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
2.2 前端技术方案
Android端采用标准MVVM架构:
kotlin复制class PetListViewModel : ViewModel() {
private val _pets = MutableLiveData<List<Pet>>()
val pets: LiveData<List<Pet>> = _pets
fun loadPets() {
viewModelScope.launch {
val response = petRepository.getPets()
_pets.value = response.data
}
}
}
uni-app部分使用Vue.js开发,关键配置:
javascript复制// main.js
import Vue from 'vue'
import App from './App'
Vue.config.productionTip = false
App.mpType = 'app'
const app = new Vue({
...App
})
app.$mount()
3. 核心功能实现
3.1 宠物信息管理
后端实体类设计:
java复制@Entity
@Table(name = "pets")
public class Pet {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private Integer age;
private String breed;
@Lob
private String description;
// Getters and setters
}
前端展示采用分页加载:
kotlin复制val layoutManager = LinearLayoutManager(this)
recyclerView.layoutManager = layoutManager
recyclerView.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
if (!viewModel.isLoading && layoutManager.findLastVisibleItemPosition() == adapter.itemCount - 1) {
viewModel.loadNextPage()
}
}
})
3.2 领养申请流程
领养申请状态机设计:
java复制public enum AdoptionStatus {
PENDING, // 待审核
APPROVED, // 已批准
REJECTED, // 已拒绝
COMPLETED // 已完成
}
申请审核接口:
java复制@PostMapping("/adoptions/{id}/review")
public ResponseEntity<?> reviewAdoption(
@PathVariable Long id,
@RequestParam boolean approved,
@RequestParam(required = false) String comment) {
Adoption adoption = adoptionService.findById(id);
if (adoption == null) {
return ResponseEntity.notFound().build();
}
if (approved) {
adoptionService.approve(adoption, comment);
} else {
adoptionService.reject(adoption, comment);
}
return ResponseEntity.ok().build();
}
4. 安全与权限控制
4.1 JWT认证实现
Token生成逻辑:
java复制public String generateToken(User user) {
Date now = new Date();
Date expiryDate = new Date(now.getTime() + jwtExpirationInMs);
return Jwts.builder()
.setSubject(user.getId().toString())
.setIssuedAt(now)
.setExpiration(expiryDate)
.signWith(SignatureAlgorithm.HS512, jwtSecret)
.compact();
}
拦截器配置:
java复制@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(authenticationInterceptor)
.addPathPatterns("/api/**")
.excludePathPatterns("/api/auth/**");
}
4.2 权限控制
基于注解的权限检查:
java复制@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresRole {
String[] value();
}
@Aspect
@Component
public class RoleCheckAspect {
@Before("@annotation(requiresRole)")
public void checkRole(RequiresRole requiresRole) {
// 获取当前用户角色并验证
}
}
5. 性能优化实践
5.1 图片处理
使用Thumbnailator进行图片压缩:
java复制Thumbnails.of(originalImage)
.size(800, 800)
.outputQuality(0.7)
.toFile(compressedImage);
前端懒加载实现:
xml复制<ImageView
android:id="@+id/pet_image"
android:layout_width="match_parent"
android:layout_height="200dp"
app:imageUrl="@{pet.imageUrl}"
app:placeholder="@{@drawable/placeholder}" />
5.2 缓存策略
Redis缓存配置:
java复制@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {
@Bean
public RedisCacheManager cacheManager(RedisConnectionFactory connectionFactory) {
return RedisCacheManager.builder(connectionFactory)
.cacheDefaults(RedisCacheConfiguration.defaultCacheConfig()
.entryTtl(Duration.ofMinutes(10)))
.build();
}
}
6. 测试与部署
6.1 自动化测试
集成测试示例:
java复制@SpringBootTest
@AutoConfigureMockMvc
class AdoptionControllerTest {
@Autowired
private MockMvc mockMvc;
@Test
void shouldCreateAdoption() throws Exception {
mockMvc.perform(post("/api/adoptions")
.contentType(MediaType.APPLICATION_JSON)
.content("{\"petId\":1,\"userId\":1}"))
.andExpect(status().isCreated());
}
}
6.2 部署方案
Docker部署配置:
dockerfile复制FROM openjdk:11-jre-slim
COPY target/pet-adoption.jar /app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Nginx反向代理配置:
nginx复制server {
listen 80;
server_name api.petadoption.com;
location / {
proxy_pass http://localhost:8080;
proxy_set_header Host $host;
}
}
7. 项目经验总结
在实际开发过程中,有几个关键点值得特别注意:
-
数据一致性:领养状态变更时需要同步更新多个关联实体,建议使用@Transactional确保原子性
-
移动端适配:不同Android版本对权限请求的处理有差异,需要做好兼容性测试
-
安全防护:除了基础的认证授权外,还需要防范CSRF、XSS等常见Web攻击
-
性能监控:建议集成Prometheus和Grafana进行系统监控
这个项目从技术选型到最终落地,涉及了现代Web开发的多个关键环节。通过这个实践,我深刻体会到良好的架构设计对项目可维护性的重要性,特别是在业务逻辑逐渐复杂后,清晰的模块划分能大大降低维护成本。