Spring Data REST JPA:将自动CRUD操作与手动控制器集成

时间:2015-05-28 09:43:52

标签: java json spring jpa

我使用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);
}

现在我想修改返回的内容&#34;仅#34; 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数据自动生成的响应不再存在。例如,我得到&#34;方法不允许&#34;如果我转发GET请求。

此外,我如何从控制器访问JSON有效负载?

更新

现在,只有一个公开的资源返回到我自己的控制器中未手动处理的请求的默认方法。但是我不知道它为什么会这样做以及为什么这对任何其他资源都不会发生。* 尽管它们的实体属性只有不同。

以下特定资源是对我在控制器中声明的非POST扫描/或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>
}

虽然以下半完全相同的资源&#34;规则&#34;不会返回任何默认请求处理程序。它返回&#34;方法不允许&#34;与POST /规则不同的任何内容:

@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还没有为&#34;规则&#34;暴露默认的请求处理程序。对于我的控制器类中没有手动指定的任何请求?

如果你能指出原因,我真的很感激。非常感谢你!

1 个答案:

答案 0 :(得分:0)

我已经弄清楚如何从控制器访问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。 我通过请求&#34;卷曲http://localhost:8080&#34;

获得了正确使用的网址列表

但是,可以使用

设置任何自动生成的操作的首选URL
@RepositoryRestResource(collectionResourceRel = pref_URL_suffix, path = pref_URL_suffix)

^^在我尝试的所有变化中,不知怎的,上面的那条线丢失了。