Java:在使用 HTTP GET 的可选请求参数匹配 ArrayList 中的项目时遇到问题



Using 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
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;
}

但是当检查字符串成员时,它不起作用:

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”]
}
]

另外,如何设置它,以便在我的组控制器中重复成员?

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

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

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]);
}
}
}

除了将我的 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;
}

看起来它现在正在工作。

最新更新