Java:在使用HTTP GET

时间:2019-03-25 13:16:15

标签: java rest spring-boot spring-mvc arraylist

使用Java 1.8和Spring Boot 1.5.6.RELEASE。

我的要求是创建一个HTTP GET端点,该端点采用带有可选请求参数的查询字符串:

HTTP GET /groups/query[?name=<nq>][&gid=<gq>][&member=<mq1>[&member=<mq2>][&.
..]]

需要返回与所有指定查询字段匹配的组列表。括号表示可以提供以下任何查询参数:

  • 名称
  • gid
  • 成员(重复)

应返回任何包含所有指定成员的组,即当查询成员是组成员的子集时。

Example Query: GET /groups/query?member=_analyticsd&member=_networkd

示例响应:

[
  {
    “name”: “_analyticsusers”,
    “gid”: 250,
    “members”: [“_analyticsd’, ”_networkd”, ”_timed”]
  }
]

RestController:

@RestController
public class GroupController {

    @Autowired
    GroupService groupService;
    private HttpHeaders headers = null;

    @Autowired
    public GroupController() {
        headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
    }

    @RequestMapping(value = {"/groups/query" }, method = RequestMethod.GET, produces = "APPLICATION/JSON")
    public ResponseEntity<Object> getGroupsBasedOnRequestParams(@RequestParam(value = "name", required = false) String name, 
                                                           @RequestParam(value = "gid", required = false) Integer gid,
                                                           @RequestParam(value ="member", required = false) String member) {

        List<Group> groups = groupService.findUsingRequestParams("/etc/group", name, gid, member);

        if (groups == null) {
            return new ResponseEntity<Object>(HttpStatus.NOT_FOUND);
        }
        return new ResponseEntity<Object>(groups, headers, HttpStatus.OK);
    }
}

组:

public class Group {
    private Integer gid;
    private String name;
    private List<String> members;

    public Group(String line) {
        String[] items = line.split(":");

        this.name = items[0];
        this.gid = Integer.parseInt(items[2]);

        if (items.length > 3){
            this.members = Arrays.asList(items[3]);
        }
    }

GroupServiceImpl:

@Service
public class GroupServiceImpl implements GroupService {

    @Override
    public List<Group> findUsingRequestParams(String line, String name, Integer gid, String member) {
        List<Group> allGroups = FileParserUtils.parseFileForGroups(line);
        List<Group> matchedGroups = new ArrayList<>();

        // this works for name and gid
        for (Group group : allGroups) {
            if (group.getName().equals(name) || group.getGid() == gid) {
                matchedGroups.add(group);
            }
        }

        return matchedGroups;
    }

但是当检查String成员时,它不起作用:

    for (Group group : allGroups) {
        if (group.getName().equals(name) || group.getGid() == gid || group.getMembers().contains(member)) {
            matchedGroups.add(group);
        }
    }

这会导致NPE:

2019-03-25 05:43:42,695 ERROR [http-nio-8080-exec-3] org.apache.juli.logging.DirectJDKLog: Servlet.service() for servlet [dispatcherServlet] in context with path [/MyService] threw exception [Request processing failed; nested exception is java.lang.NullPointerException] with root cause
java.lang.NullPointerException: null
    at com.myapp.service.GroupServiceImpl.findUsingRequestParams(GroupServiceImpl.java:33)
    at com.myapp.controller.GroupController.getGroupsBasedOnRequestParams(GroupController.java:72)

问题:

为什么这样做:

for (Group group : allGroups) {
    if (group.getName().equals(name) || group.getGid() == gid) {
        matchedGroups.add(group);
    }
}

但这不是(这会导致NullPointerException):

for (Group group : allGroups) {
    if (group.getName().equals(name) || group.getGid() == gid || group.getMembers().contains(member)) {
        matchedGroups.add(group);
    }
}

此外,当仅使用成员内部的一个子集时,如何返回整个群组?

查询示例:

GET /groups/query?member=_analyticsd&member=_networkd

示例响应:

[
  {
    “name”: “_analyticsusers”,
    “gid”: 250,
    “members”: [“_analyticsd’, ”_networkd”, ”_timed”]
  }
]

另外,如何设置它以便在GroupController中重复成员?

GET /groups/query?member=_analyticsd&member=_networkd&member=_timed 

2 个答案:

答案 0 :(得分:0)

您的组构造函数是错误的:

public class Group {

    private Integer gid;
    private String name;
    private List<String> members;

    public Group(String line) {
        String[] items = line.split(":");

        this.name = items[0];
        this.gid = Integer.parseInt(items[2]);
        this.members = new ArrayList<>(items.length - 3);

        for (int i = 3; i < items.length; i++) {
            this.members.add(items[i]);
        }
    }
}

答案 1 :(得分:0)

除了将我的Group构造函数更改为@ codeflush.dev建议的内容之外,我还更改了内部实现:

@Override
public List<Group> findUsingRequestParams(String line, String name, Integer gid, String member) {
    List<Group> allGroups = FileParserUtils.parseFileForGroups(line);
    List<Group> matchedGroups = new ArrayList<>();

    for (Group group : allGroups) {
        if (group.getMembers() != null) {
            if (group.getName().equals(name) || group.getGid() == gid || group.getMembers().contains(member)) {
                matchedGroups.add(group);
            }
        }
    }
    return matchedGroups;
}

现在喜欢它的工作。