![](/img/trans.png)
[英]JPA + Spring Boot: TransactionRequiredException on CRUD operations
[英]Spring Data REST JPA: Integrate automatic CRUD operations with manual controller
我正在使用Spring Data REST JPA构建RESTful Web服务。 到目前为止,Spring会为所有可能的方法自动生成所有响应,并列出所有可用资源甚至搜索它们:
@RepositoryRestResource(collectionResourceRel = "scans", path = "scans")
public interface ScanRepository extends PagingAndSortingRepository<Scan, Long> {
List<Scan> findByProjectId(@Param("pid") String pid);
}
现在,我想修改“仅”返回到POST请求的内容,同时保留对所有其他请求的完整支持。 我以为会为此目的创建一个控制器,如下所示:
@Controller
public class ScanController {
@RequestMapping(value = "/scans", method = POST, produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody Result parseScan(@RequestParam String projectId, @RequestParam String tool) {
return null;
}
但是,当我这样做时,对于所有其他方法和搜索等的JPA数据自动生成的响应将不复存在。 例如,如果转发GET请求,则会显示“不允许使用方法”。
此外,如何从控制器访问JSON有效负载?
更新
现在,对于在我自己的控制器中未手动处理的请求,仅公开资源之一会返回默认方法。 但是,我不知道为什么其他资源会这样做,为什么不会发生这种情况。*尽管它们的唯一区别只是它们的实体属性不同。
以下特定资源是对我在控制器中声明的不是POST scan /或GET / scan ///的所有内容返回默认请求处理程序的资源:
@Controller
public class ScanController {
@Autowired
private ScanService scanService;
@RequestMapping(
value = "/scan",
method = POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Scan parseScan(@RequestBody Scan rbody) {
<...do something...>
}
@RequestMapping(value = "/scans/{id}/{totvuln}/{nth}", method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Scan getScan(@PathVariable String id, @PathVariable int totvuln, @PathVariable int nth) throws ScanNotFound {
<...do something...>
}
它具有以下存储库接口:
public interface ScanRepository extends PagingAndSortingRepository<Scan, Long> {}
以及以下服务:
@Service
public class ScanServiceImpl implements ScanService {
@Resource
private ScanRepository scanRepository;
@Resource
private ResultRepository resultRepository;
@Override
@Transactional
public Scan create(Scan shop) {
<some code>
}
@Override
@Transactional
public Scan findById(long id) {
<some code>
}
@Override
@Transactional(rollbackFor = ScanNotFound.class)
public Scan delete(long id) throws ScanNotFound {
<some code>
}
@Override
@Transactional
public List<Scan> findAll() {
<some code>
}
@Override
@Transactional(rollbackFor = ScanNotFound.class)
public Scan update(Scan scan) throws ScanNotFound {
<some code>
}
}
资源本身具有以下属性:
@Entity
public class Scan {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Long projectId;
@OneToMany
private Collection<Result> result;
private int totV;
<getters and setters>
}
尽管以下半相同的资源“规则”不返回任何默认请求处理程序。 对于POST / rule以外的任何内容,它返回“不允许的方法”:
@Controller
public class RulesController {
@Autowired
private RulesService rService;
@Resource
private ScanRepository scanRepository;
@RequestMapping(
value = "/rule",
method = POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Rules generateRules(@RequestBody Scan rbody) throws Exception {
<do something>
}
}
它具有相同的存储库接口:
public interface RulesRepository extends PagingAndSortingRepository<Rules, Long> {}
以及相同的服务实现:
@Service
public class RulesServiceImpl implements RulesService {
@Resource
private RulesRepository rRepository;
@Resource
private ResultRepository resultRepository;
@Override
@Transactional
public Rules create(Rules shop) {
<do something>
}
@Override
@Transactional
public Rules findById(long id) {
<do something>
}
@Override
@Transactional(rollbackFor = RulesNotFound.class)
public Rules delete(long id) throws RulesNotFound {
<do something>
}
@Override
@Transactional
public List<Rules> findAll() {
<do something>
}
@Override
@Transactional
public Rules findByScanId(long id) throws RulesNotFound {
<do something>
}
@Override
@Transactional(rollbackFor = RulesNotFound.class)
public Rules update(Rules scan) throws RulesNotFound {
<do something>
}
}
资源规则本身具有以下属性:
@Entity
public class Rules {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne
private Scan scan;
@OneToMany
private Collection<Result> result;
private String rules;
<getters and setters>
}
对于未在我的控制器类中手动指定的任何请求,Spring为什么不对“规则”也公开默认请求处理程序?
如果您能指出原因,我将不胜感激。 非常感谢!
我已经弄清楚了如何从控制器访问JSON负载:
@RequestMapping(
value = "/scan",
method = POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Scan parseScan(@RequestBody Scan rbody) {
Scan scan = new Scan();
scan.setProjectId(rbody.getProjectId());
scan.setTool(rbody.getTool());
return scan;
}
我还意识到实际上我的控制器未处理的每个请求实际上都已支持自动CRUD操作:我只是在请求错误的URL。 通过请求“ curl http:// localhost:8080 ”,我可以使用正确的URL列表
但是,可以使用以下命令设置任何自动生成的操作的首选URL
@RepositoryRestResource(collectionResourceRel = pref_URL_suffix, path = pref_URL_suffix)
^^在我尝试的所有更改中,上面的那一行都丢失了。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.