实施约20个休息控制器&服务,我发现自己很多代码都被重复了,所以我想出了这个装置。
CrudController.java 包app.controllers;
import org.springframework.data.repository.CrudRepository;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import app.models.Model;
import app.services.CrudService;
@RestController
public abstract class CrudController<M extends Model, S extends CrudService<M, ? extends CrudRepository<M,Long>>> {
S service;
public abstract void setService(S service);
public abstract Boolean isAuthorized(Long entityId, S service);
@RequestMapping(value="/create", method = RequestMethod.POST)
public M create(M object) {
if(isAuthorized(object.getId(), service)) {
return service.save(object);
}
logUnauthorizedAccess();
return null;
}
@RequestMapping(value="/update", method = RequestMethod.POST)
public M update(M object) {
if(isAuthorized(object.getId(), service)) {
return service.update(object);
}
logUnauthorizedAccess();
return null;
}
@RequestMapping(value="/delete", method = RequestMethod.POST)
public Boolean delete(Long id) {
if(isAuthorized(id, service)) {
return service.delete(id);
}
logUnauthorizedAccess();
return null;
}
@RequestMapping(value="/get", method = RequestMethod.GET)
public @ResponseBody M get(Long id) {
if(isAuthorized(id, service)) {
return service.get(id);
}
logUnauthorizedAccess();
return null;
}
@RequestMapping(value="/json", method = RequestMethod.GET)
public @ResponseBody Iterable<M> json(ModelMap map) {
return service.getAll();
}
private void logUnauthorizedAccess() {
System.out.println("!!UN-AUTHORIZED ACCESS DETECTED!!");
}
}
CrudService.java
package app.services;
import org.springframework.data.repository.CrudRepository;
public abstract class CrudService<M extends app.models.Model, R extends CrudRepository<M, Long>> {
R repo;
public abstract void setRepo(R repo);
/**
* Define the parameters that you want to save to the DB when calling the update() method
* @param from source object
* @param to DB object that gets saves, "return to" in this method
* @return
*/
public abstract M copy(M from, M to);
public Iterable<M> getAll() {
return this.repo.findAll();
}
/**
* Mainly used to create a new entity
* however, can also be used to save something without using the
* update() method.
* @param model
* @return saved entity model
*/
public M save(M model) {
return this.repo.save(model);
}
public M get(Long id) {
return this.repo.findOne(id);
}
public M update(M model) {
M updated = this.repo.findOne(model.getId());
updated = copy(model, updated);
return this.repo.save(updated);
}
public Boolean delete(Long id) {
this.repo.delete(id);
return true;
}
}
Model.java
package app.models;
import java.sql.Timestamp;
import java.util.Date;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
import javax.persistence.PrePersist;
import javax.persistence.Version;
@MappedSuperclass
public abstract class Model {
@GeneratedValue
@Id
private Long id;
private Date dateCreated;
@Version
private Timestamp dateModified;
@PrePersist
void createdAt() {
this.setDateCreated(new Date());
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Date getDateCreated() {
return dateCreated;
}
public void setDateCreated(Date dateCreated) {
this.dateCreated = dateCreated;
}
public Timestamp getDateModified() {
return dateModified;
}
public void setDateModified(Timestamp dateModified) {
this.dateModified = dateModified;
}
}
现在我的所有控制器在给我的时候看起来像下面这样。 / create / get / update / delete / json
package app.controllers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import app.models.Sample;
import app.services.SampleService;
@RestController
@RequestMapping("/sample")
public class SampleController extends CrudController<Sample, SampleService> {
@Autowired
@Override
public void setService(SampleService service) {
this.service = service;
}
@Override
public Boolean isAuthorized(Long entityId, SampleService service) {
return true;
}
}
https://github.com/ddalcu/spring-starter/commit/27fb2a0719c4780d7cf648852d93b8fd3d8759c8
你们怎么想,好坏,更好的方法呢?
答案 0 :(得分:4)
您应该查看Spring Data REST。
答案 1 :(得分:1)
Spring能够处理泛型:
你真的不需要为每个CrudController
创建Model
的子类,只要内部的实现没有改变。
例如,您可以使用一个使用PathVariable
的控制器。
然后,CrudService
和Dao
也有同样的可能性。
如果你现在看到对于某些实体你需要在这个控制器(或服务,dao)中进行特殊处理,你至少有两种方法我知道:
第二层或第三层的分叉主要取决于你需要有特殊可能性的地方。
我已经看过两种方法,目前我在春季项目中使用了这种方法。 由于调度程序servlet根据您拥有的变量排序请求映射,因此只需使用专用控制器的pathvariable对代码进行硬编码即可轻松创建更具体的映射。