如何在 java/groovy 中减少自定义 API 端点的输出
How to reduce output for a custom API Endpoint in java/groovy
我正在努力改进我们的 Confluence-Server 平台的自定义搜索。
我们有一个名为 Scriptrunner 的插件,它允许我们使用 Groovy 而不是 Java 作为代码。
我正在处理的代码是一个搜索 API 端点,它目前工作正常但是 returns 很多不必要的信息甚至重复,所以我想缩小搜索输出以最有效的方式。
该平台有一个我试图用于实现的 javadoc,link:https://docs.atlassian.com/ConfluenceServer/javadoc/7.8.1/com/atlassian/confluence/search/v2/SearchManager.html
我想实现以下部分
search(ISearch search, Set<String> requestedFields)
Perform a search with a given criteria, the returns searchResults only have the fields requested in the projection filled out, no other fields are valid in the searchResult.
但我无法理解如何正确生成 Set<String> requestedFields
.
这是我的尝试:
import...
def searchManager = ComponentLocator.getComponent(SearchManager)
def paramQueryString = "ArticleThatWillBeDeleted"
def query = BooleanQuery.andQuery(new TextQuery(paramQueryString));
def sort = new RelevanceSort();
def searchFilter = SiteSearchPermissionsSearchFilter.getInstance();
def searchContent = new ContentSearch(query, sort, searchFilter, 0, 100);
Set<String> requestedFields = new HashSet<String>();
requestedFields.add("displayTitle");
def searchresult = searchManager.search(searchContent,requestedFields)
return searchresult.getAll()
如果我想使用其他方法
search(ISearch search)
Perform a search with a given criteria.
脚本工作得很好,但是returns很多信息我想删减。
除了我想要实现的方法之外,我也愿意接受任何其他类型的建议,我可以只指定我想要输出的信息,这样我就可以保证输出大小和处理能力。
P.S。
我已经尝试在他们的社区页面上详细询问同样的问题,但我想我可以使用一些开发人员的帮助,因为我刚刚从工作中了解到 Java/Groovy。
更新:
这是作为 API 端点实现的工作代码:
import com.atlassian.seraph.auth.DefaultAuthenticator
import com.atlassian.confluence.user.UserAccessor
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.search.service.ContentTypeEnum
import com.atlassian.confluence.search.v2.SearchManager
import com.atlassian.confluence.search.v2.searchfilter.SiteSearchPermissionsSearchFilter
import com.atlassian.confluence.search.v2.ContentSearch
import com.atlassian.confluence.search.v2.query.*
import com.atlassian.confluence.search.v2.sort.RelevanceSort
import com.atlassian.confluence.search.v2.SearchSort
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import org.codehaus.jackson.map.ObjectMapper
import java.util.HashSet
@BaseScript CustomEndpointDelegate delegate
testSearch(
httpMethod: "GET", groups: ["access_group_1","access_group_2"]
) { MultivaluedMap queryParams, String body ->
def searchManager = ComponentLocator.getComponent(SearchManager)
// Query can be of any type noted here:
//https://developer.atlassian.com/server/confluence/searching-using-the-v2-search-api/
def paramQueryString = (queryParams.get(new String("q"))).get(0)
def query = BooleanQuery.andQuery(new TextQuery(paramQueryString));
def sort = new RelevanceSort();
def searchFilter = SiteSearchPermissionsSearchFilter.getInstance();
def searchContent = new ContentSearch(query, sort, searchFilter, 0, 100);
def searchresult = searchManager.search(searchContent)
return Response.ok(new JsonBuilder([results: searchresult.getAll()]).toString()).build()
}
当我调用 API
http://10.10.10.11:8080/rest/scriptrunner/latest/custom/testSearch?q=ArticleThatWillBeDeleted
我收到以下 JSON 响应
{
"results": [
{
"displayTitle": "ArticleThatWillBeDeleted",
"handle": {
"className": "com.atlassian.confluence.pages.Page",
"id": 359071873
},
"lastUpdateDescription": "",
"ownerTitle": null,
"spaceName": "Employee Team Space",
"creatorUser": {
"backingUser": {
"active": true,
"lowerName": "vnikolov",
"directoryId": 142049281,
"fullName": "Vasil Nikolov",
"emailAddress": "vnikolov@domain.com",
"email": "vnikolov@domain.com",
"name": "vnikolov",
"displayName": "Vasil Nikolov"
},
"lowerName": "vnikolov",
"key": {
"stringValue": "8a606c8c56a371040156a37301341285"
},
"fullName": "Vasil Nikolov",
"email": "vnikolov@domain.com",
"name": "vnikolov"
},
"resultExcerpt": "this is the body of the article that will be delted.",
"ownerType": null,
"lastModifier": "vnikolov",
"urlPath": "/display/WIT/ArticleThatWillBeDeleted",
"resultExcerptWithHighlights": "this is the body of the article that will be delted.",
"explain": {
"present": false,
"empty": true
},
"lastModifierUser": {
"backingUser": {
"active": true,
"lowerName": "vnikolov",
"directoryId": 142049281,
"fullName": "Vasil Nikolov",
"emailAddress": "vnikolov@domain.com",
"email": "vnikolov@domain.com",
"name": "vnikolov",
"displayName": "Vasil Nikolov"
},
"lowerName": "vnikolov",
"key": {
"stringValue": "8a606c8c56a371040156a37301341285"
},
"fullName": "Vasil Nikolov",
"email": "vnikolov@domain.com",
"name": "vnikolov"
},
"extraFields": {
"content-version": "1"
},
"lastModificationDate": "2020-10-20T20:42:27+0000",
"type": "page",
"content": " \nthis is the body of the article that will be delted.\n ",
"creationDate": "2020-10-20T20:41:46+0000",
"personalLabels": [],
"status": "current",
"spaceKey": "WIT",
"contentVersion": 1,
"creator": "vnikolov",
"displayTitleWithHighlights": "ArticleThatWillBeDeleted",
"homePage": false,
"sanitisedContent": "this is the body of the article that will be delted."
}
]
}
我得到了正文的 4 倍(resultExcerpt、resultExcerptWithHighlights、content、sanitisedContent)
我所需要的只是 content
,如果可能的话,将其砍掉一个有限的大小或字符长度。
当我尝试通过添加以下行来实现 requestedFields
并修改 searchresult
def requestedFields = [ 'content', 'displaytitle' ] as Set
def searchresult = searchManager.search(searchContent,requestedFields)
我得到的 JSON 回复是:
{
"results": [
{
"resultExcerpt": "",
"explain": {
"present": false,
"empty": true
},
"resultExcerptWithHighlights": "",
"extraFields": {},
"displayTitleWithHighlights": ""
}
]
}
我注意到的另一件事是,在工作示例中,返回的 class 是:
com.atlassian.confluence.search.v2.lucene.LuceneSearchResult@1233a8a4
在 requestedFields
尝试中,结果 class 是:
com.atlassian.confluence.search.v2.ProjectedSearchResult@6c688cdd
我想找到一种方法来控制 API 的输出,它不一定是我要实现的 requestedFields
方法。
JsonBuilder
呈现所有对象属性,而不仅仅是您从服务器请求的字段。
我看到呈现请求字段的最简单方法:
def requestedFields = [ 'content', 'displaytitle' ] as Set
def searchresult = searchManager.search(searchContent,requestedFields)
def table = searchresult.getAll().collect{row->
requestedFields.collectEntries{fldName->
[ fldName , row.getField(fldName) ]
}
}
def json = new groovy.json.JsonBuilder(table).toPrettyString()
Response.ok(json).build()
我正在努力改进我们的 Confluence-Server 平台的自定义搜索。 我们有一个名为 Scriptrunner 的插件,它允许我们使用 Groovy 而不是 Java 作为代码。
我正在处理的代码是一个搜索 API 端点,它目前工作正常但是 returns 很多不必要的信息甚至重复,所以我想缩小搜索输出以最有效的方式。
该平台有一个我试图用于实现的 javadoc,link:https://docs.atlassian.com/ConfluenceServer/javadoc/7.8.1/com/atlassian/confluence/search/v2/SearchManager.html
我想实现以下部分
search(ISearch search, Set<String> requestedFields)
Perform a search with a given criteria, the returns searchResults only have the fields requested in the projection filled out, no other fields are valid in the searchResult.
但我无法理解如何正确生成 Set<String> requestedFields
.
这是我的尝试:
import...
def searchManager = ComponentLocator.getComponent(SearchManager)
def paramQueryString = "ArticleThatWillBeDeleted"
def query = BooleanQuery.andQuery(new TextQuery(paramQueryString));
def sort = new RelevanceSort();
def searchFilter = SiteSearchPermissionsSearchFilter.getInstance();
def searchContent = new ContentSearch(query, sort, searchFilter, 0, 100);
Set<String> requestedFields = new HashSet<String>();
requestedFields.add("displayTitle");
def searchresult = searchManager.search(searchContent,requestedFields)
return searchresult.getAll()
如果我想使用其他方法
search(ISearch search)
Perform a search with a given criteria.
脚本工作得很好,但是returns很多信息我想删减。
除了我想要实现的方法之外,我也愿意接受任何其他类型的建议,我可以只指定我想要输出的信息,这样我就可以保证输出大小和处理能力。
P.S。 我已经尝试在他们的社区页面上详细询问同样的问题,但我想我可以使用一些开发人员的帮助,因为我刚刚从工作中了解到 Java/Groovy。
更新:
这是作为 API 端点实现的工作代码:
import com.atlassian.seraph.auth.DefaultAuthenticator
import com.atlassian.confluence.user.UserAccessor
import com.atlassian.confluence.user.AuthenticatedUserThreadLocal
import com.atlassian.confluence.spaces.SpaceManager
import com.atlassian.sal.api.component.ComponentLocator
import com.atlassian.confluence.search.service.ContentTypeEnum
import com.atlassian.confluence.search.v2.SearchManager
import com.atlassian.confluence.search.v2.searchfilter.SiteSearchPermissionsSearchFilter
import com.atlassian.confluence.search.v2.ContentSearch
import com.atlassian.confluence.search.v2.query.*
import com.atlassian.confluence.search.v2.sort.RelevanceSort
import com.atlassian.confluence.search.v2.SearchSort
import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
import groovy.json.JsonBuilder
import groovy.transform.BaseScript
import javax.ws.rs.core.MultivaluedMap
import javax.ws.rs.core.Response
import org.codehaus.jackson.map.ObjectMapper
import java.util.HashSet
@BaseScript CustomEndpointDelegate delegate
testSearch(
httpMethod: "GET", groups: ["access_group_1","access_group_2"]
) { MultivaluedMap queryParams, String body ->
def searchManager = ComponentLocator.getComponent(SearchManager)
// Query can be of any type noted here:
//https://developer.atlassian.com/server/confluence/searching-using-the-v2-search-api/
def paramQueryString = (queryParams.get(new String("q"))).get(0)
def query = BooleanQuery.andQuery(new TextQuery(paramQueryString));
def sort = new RelevanceSort();
def searchFilter = SiteSearchPermissionsSearchFilter.getInstance();
def searchContent = new ContentSearch(query, sort, searchFilter, 0, 100);
def searchresult = searchManager.search(searchContent)
return Response.ok(new JsonBuilder([results: searchresult.getAll()]).toString()).build()
}
当我调用 API
http://10.10.10.11:8080/rest/scriptrunner/latest/custom/testSearch?q=ArticleThatWillBeDeleted
我收到以下 JSON 响应
{
"results": [
{
"displayTitle": "ArticleThatWillBeDeleted",
"handle": {
"className": "com.atlassian.confluence.pages.Page",
"id": 359071873
},
"lastUpdateDescription": "",
"ownerTitle": null,
"spaceName": "Employee Team Space",
"creatorUser": {
"backingUser": {
"active": true,
"lowerName": "vnikolov",
"directoryId": 142049281,
"fullName": "Vasil Nikolov",
"emailAddress": "vnikolov@domain.com",
"email": "vnikolov@domain.com",
"name": "vnikolov",
"displayName": "Vasil Nikolov"
},
"lowerName": "vnikolov",
"key": {
"stringValue": "8a606c8c56a371040156a37301341285"
},
"fullName": "Vasil Nikolov",
"email": "vnikolov@domain.com",
"name": "vnikolov"
},
"resultExcerpt": "this is the body of the article that will be delted.",
"ownerType": null,
"lastModifier": "vnikolov",
"urlPath": "/display/WIT/ArticleThatWillBeDeleted",
"resultExcerptWithHighlights": "this is the body of the article that will be delted.",
"explain": {
"present": false,
"empty": true
},
"lastModifierUser": {
"backingUser": {
"active": true,
"lowerName": "vnikolov",
"directoryId": 142049281,
"fullName": "Vasil Nikolov",
"emailAddress": "vnikolov@domain.com",
"email": "vnikolov@domain.com",
"name": "vnikolov",
"displayName": "Vasil Nikolov"
},
"lowerName": "vnikolov",
"key": {
"stringValue": "8a606c8c56a371040156a37301341285"
},
"fullName": "Vasil Nikolov",
"email": "vnikolov@domain.com",
"name": "vnikolov"
},
"extraFields": {
"content-version": "1"
},
"lastModificationDate": "2020-10-20T20:42:27+0000",
"type": "page",
"content": " \nthis is the body of the article that will be delted.\n ",
"creationDate": "2020-10-20T20:41:46+0000",
"personalLabels": [],
"status": "current",
"spaceKey": "WIT",
"contentVersion": 1,
"creator": "vnikolov",
"displayTitleWithHighlights": "ArticleThatWillBeDeleted",
"homePage": false,
"sanitisedContent": "this is the body of the article that will be delted."
}
]
}
我得到了正文的 4 倍(resultExcerpt、resultExcerptWithHighlights、content、sanitisedContent)
我所需要的只是 content
,如果可能的话,将其砍掉一个有限的大小或字符长度。
当我尝试通过添加以下行来实现 requestedFields
并修改 searchresult
def requestedFields = [ 'content', 'displaytitle' ] as Set
def searchresult = searchManager.search(searchContent,requestedFields)
我得到的 JSON 回复是:
{
"results": [
{
"resultExcerpt": "",
"explain": {
"present": false,
"empty": true
},
"resultExcerptWithHighlights": "",
"extraFields": {},
"displayTitleWithHighlights": ""
}
]
}
我注意到的另一件事是,在工作示例中,返回的 class 是:
com.atlassian.confluence.search.v2.lucene.LuceneSearchResult@1233a8a4
在 requestedFields
尝试中,结果 class 是:
com.atlassian.confluence.search.v2.ProjectedSearchResult@6c688cdd
我想找到一种方法来控制 API 的输出,它不一定是我要实现的 requestedFields
方法。
JsonBuilder
呈现所有对象属性,而不仅仅是您从服务器请求的字段。
我看到呈现请求字段的最简单方法:
def requestedFields = [ 'content', 'displaytitle' ] as Set
def searchresult = searchManager.search(searchContent,requestedFields)
def table = searchresult.getAll().collect{row->
requestedFields.collectEntries{fldName->
[ fldName , row.getField(fldName) ]
}
}
def json = new groovy.json.JsonBuilder(table).toPrettyString()
Response.ok(json).build()