Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
208 views
in Technique[技术] by (71.8m points)

How to apply Spring Data projections in a Spring MVC controllers?

Is it possible to specify projection when calling data repository method directly? Here's repository code - note I would not like to expose it via REST, instead I would like to be able to call it from a service or controller:

@RepositoryRestResource(exported = false)
public interface UsersRepository extends PagingAndSortingRepository<User, Long> {

    @Query(value = "SELECT u FROM User u WHERE ....")
    public Page<User> findEmployeeUsers(Pageable p);
}

Then in a controller I do this:

@PreAuthorize(value = "hasRole('ROLE_ADMIN')")
@RequestMapping(value = "/users/employee")
public Page<User> listEmployees(Pageable pageable) {
    return usersRepository.findEmployeeUsers(pageable);
}

Is there any way to specify projection for findEmployeeUsers method when it is called directly like above?

I realise that the code above might look odd for someone... it would be possible to expose the repository via REST and put the @PreAuthorize thing in the repository. Thought controller is the more right place to do security checks - it is more natural as well as simpler to test.

So, can projection thing be somehow passed into a repository method called directly?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

No it's not, especially as projections are usually applied to the result of a query execution on a case by case basis. Thus they're currently designed to be selectively applied to domain types.

As of the latest Spring Data Fowler release train GA release the projection infrastructure can be used programmatically in Spring MVC controllers. Simply declare a Spring bean for SpelAwareProxyProjectionFactory:

@Configuration
class SomeConfig {

  @Bean
  public SpelAwareProxyProjectionFactory projectionFactory() {
    return new SpelAwareProxyProjectionFactory();
  }
}

Then inject it into your controller and use it:

@Controller
class SampleController {

  private final ProjectionFactory projectionFactory;

  @Autowired
  public SampleController(ProjectionFactory projectionFactory) {
    this.projectionFactory = projectionFactory;
  }

  @PreAuthorize(value = "hasRole('ROLE_ADMIN')")
  @RequestMapping(value = "/users/employee")
  public Page<?> listEmployees(Pageable pageable) {

    return usersRepository.findEmployeeUsers(pageable).//
      map(user -> projectionFactory.createProjection(Projection.class, user);
  }
}

See how as of the latest release Page has a map(…) method that can be used to transform the page content on the fly. We use a JDK 8 lambda to provide a conversion step using the ProjectionFactory.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...