Spring+AngularJS教程请求:获取指定Category下的所有Reviews
Hey there! Let's tackle this step by step—since you're working with JHipster-generated code, we can leverage the existing structure to add this feature without reinventing the wheel. I'll split this into backend (Spring Boot) and frontend (AngularJS) implementations to keep things clear.
Backend (Spring Boot)
First, let's make sure our data layer and REST endpoint are set up correctly:
Verify Entity Relationship
Check yourReview.javaentity to ensure it has a many-to-one association withCategory(JHipster should have generated this if you set up the relationship during project creation):@ManyToOne @JoinColumn(name = "category_id") private Category category;If this isn't present, add it and update your database schema (use JHipster's Liquibase migrations or Hibernate auto-ddl for development).
Add Repository Method
OpenReviewRepository.javaand add a Spring Data JPA method to fetch reviews by category ID. You can use either the method naming convention or an explicit JPQL query:// Option 1: Spring Data auto-implemented method List<Review> findByCategoryId(Long categoryId); // Option 2: Explicit JPQL query (great for complex logic) @Query("SELECT r FROM Review r WHERE r.category.id = :categoryId") List<Review> findReviewsByCategoryId(@Param("categoryId") Long categoryId);For pagination support, swap
List<Review>withPage<Review>and add aPageableparameter:Page<Review> findByCategoryId(Long categoryId, Pageable pageable);Create REST Endpoint
OpenReviewResource.java(your REST controller) and add a new endpoint to expose this data:@GetMapping("/reviews/category/{categoryId}") @Timed public ResponseEntity<List<ReviewDTO>> getReviewsByCategory(@PathVariable Long categoryId) { log.debug("REST request to get Reviews for Category : {}", categoryId); List<Review> reviews = reviewRepository.findByCategoryId(categoryId); List<ReviewDTO> reviewDTOs = reviewMapper.toDto(reviews); return ResponseEntity.ok().body(reviewDTOs); }If using pagination, adjust the endpoint to handle page parameters:
@GetMapping("/reviews/category/{categoryId}") @Timed public ResponseEntity<List<ReviewDTO>> getReviewsByCategory(@PathVariable Long categoryId, Pageable pageable) { log.debug("REST request to get paginated Reviews for Category : {}", categoryId); Page<Review> page = reviewRepository.findByCategoryId(categoryId, pageable); HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/reviews/category/" + categoryId); return ResponseEntity.ok().headers(headers).body(reviewMapper.toDto(page.getContent())); }Check Security Permissions
Ensure the new endpoint is accessible under your JHipster security setup. You can add a@PreAuthorizeannotation to the endpoint or updateSecurityConfiguration.javato allow access to/api/reviews/category/**.
Frontend (AngularJS)
Now let's wire up the frontend to call our new endpoint:
Add Service Method
Openapp/shared/review/review.service.jsand add a method to fetch reviews by category ID:function ReviewService($resource) { var service = $resource('api/reviews/:id', {}, { 'query': { method: 'GET', isArray: true}, 'get': { method: 'GET'}, // ... existing methods 'getByCategory': { method: 'GET', url: 'api/reviews/category/:categoryId', isArray: true} }); // ... existing service methods service.getReviewsByCategoryId = function(categoryId) { return this.getByCategory({categoryId: categoryId}); }; return service; }For pagination, adjust the method to accept page parameters:
'getByCategory': { method: 'GET', url: 'api/reviews/category/:categoryId', isArray: false} service.getReviewsByCategoryId = function(categoryId, page, size) { return this.getByCategory({categoryId: categoryId, page: page, size: size}); };Use the Service in a Controller
In your controller (e.g.,app/category/category-detail.controller.js), injectReviewServiceand fetch reviews when the controller loads:function CategoryDetailController($scope, $stateParams, CategoryService, ReviewService) { var vm = this; vm.category = {}; vm.reviews = []; // Load category details first CategoryService.get({id: $stateParams.id}).$promise.then(function(data) { vm.category = data; // Then load reviews for this category return ReviewService.getReviewsByCategoryId(data.id).$promise; }).then(function(reviews) { vm.reviews = reviews; }); }Display Reviews in the View
Update your HTML template (e.g.,app/category/category-detail.html) to show the fetched reviews withng-repeat:<div class="reviews-section" ng-if="vm.reviews.length > 0"> <h3>Reviews for {{vm.category.name}}</h3> <div class="review-card" ng-repeat="review in vm.reviews"> <p><strong>Rating:</strong> {{review.rating}}/5</p> <p>{{review.content}}</p> <p class="text-muted">Posted on: {{review.createdDate | date:'medium'}}</p> <!-- Add existing edit/delete buttons here if needed --> </div> </div> <div class="empty-state" ng-if="vm.reviews.length === 0"> No reviews yet for this category. </div>
Quick Testing Tips
- Backend: Use Postman or curl to test the endpoint directly (e.g.,
GET http://localhost:8080/api/reviews/category/1) to confirm it returns the correct data. - Frontend: Check your browser's dev tools network tab to verify the API call is made and data is received.
内容的提问来源于stack exchange,提问作者Ginel Guiu

