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;
}
看起来它现在正在工作。