- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我似乎无法进行简单的 REST 客户端集成测试。我正在使用带有 JavaConfig 设置的 Spring 3.1 MVC。我使用 Maven,我可以毫无问题地构建、运行和部署我当前的 webapp。
首先,这里有一些代码和配置
我的 Controller
@Controller
@RequestMapping("/rest")
public class StubRestController {
@Inject
private TestData testData;
@RequestMapping(value=Endpoints.GET_RESOURCES, method=RequestMethod.GET, produces="application/json")
@ResponseStatus(HttpStatus.OK)
public @ResponseBody JSONObject getResources(@RequestParam(value="q") String query, @RequestParam int indexFrom, @RequestParam int indexTo) throws JSONException {
return makeRequest(query, indexFrom, indexTo, testData.getResources());
}
@RequestMapping(value=Endpoints.GET_LOCATIONS, method=RequestMethod.GET, produces="application/json")
@ResponseStatus(HttpStatus.OK)
public @ResponseBody JSONObject getLocations(@RequestParam(value="q") String query, @RequestParam int indexFrom, @RequestParam int indexTo) throws JSONException {
return makeRequest(query, indexFrom, indexTo, testData.getLocations());
}
private JSONObject makeRequest(String query, int indexFrom, int indexTo, String[] data) throws JSONException {
int count = 0;
final JSONArray resources = new JSONArray();
for (final String resourceName: data) {
final String lowerColor = resourceName.toLowerCase();
final int has = lowerColor.indexOf(query.toLowerCase());
if (!query.isEmpty() && (query.equals("*") || has >= 0)) {
final JSONObject resource = new JSONObject();
resource.put("DisplayName", resourceName);
resource.put("Value", resourceName); // shouldn't this be a unique id? e.g., resourceid
resources.put(resource);
count++;
}
}
final JSONArray partial = new JSONArray();
if (resources.length() > 0) {
final int end = count - 1 > indexTo ? indexTo : count - 1;
for (int i = indexFrom; i <= end; i++) {
partial.put(resources.get(i));
}
}
final JSONObject result = new JSONObject();
result.put("TotalSize", count);
result.put("Options", partial);
return result;
}
@ExceptionHandler(JSONException.class)
@ResponseStatus(value = HttpStatus.NOT_FOUND, reason="No data found matching criteria")
public void notFound() { }
}
我的测试
@ContextConfiguration(classes={ RestClientContext.class }, loader=AnnotationConfigContextLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class StubRestClientITCase {
private static final String SCHEME = "http";
private static final String HOST = "localhost";
private static final int PORT = 8081;
// requests must match <url-pattern> in order to be handled by DispatcherServlet
private static final String ENDPOINT_PREFIX = "spp-emkt-mui-experimental/EMKT/services/rest";
private static final String QUERY_KEY = "q";
private static final String INDEX_FROM_KEY = "indexFrom";
private static final String INDEX_TO_KEY = "indexTo";
private static final String TOTAL_SIZE_KEY = "TotalSize";
private Logger log = LoggerFactory.getLogger(StubRestClientITCase.class);
@Inject
RestTemplate restTemplate;
@Test
public void testGetResources() {
// Case 1: Discover all resources using * (asterisk), first 25
final URI uri = buildUri("*", 0, 24, Endpoints.GET_RESOURCES);
final HttpEntity<JSONObject> response = obtainResponse(uri);
try {
Assert.assertTrue(response.hasBody());
Assert.assertEquals(25, Integer.parseInt(response.getBody().getString(TOTAL_SIZE_KEY)));
} catch (final JSONException je) {
fail("Could not obtain \"" + TOTAL_SIZE_KEY + "\" from JSON payload for getResources().\n" + je.getMessage());
}
}
private URI buildUri(String query, int indexFrom, int indexTo, String endPointUrl) {
final UriComponents uriComponents =
UriComponentsBuilder.newInstance()
.scheme(SCHEME).host(HOST).port(PORT).path(ENDPOINT_PREFIX + endPointUrl)
.queryParam(QUERY_KEY, query)
.queryParam(INDEX_FROM_KEY, indexFrom)
.queryParam(INDEX_TO_KEY, indexTo)
.build()
.encode();
final URI uri = uriComponents.toUri();
return uri;
}
private HttpEntity<JSONObject> obtainResponse(URI uri) {
final HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Arrays.asList(new MediaType[] {MediaType.APPLICATION_JSON}));
requestHeaders.setAcceptCharset(Arrays.asList(new Charset[] {Charset.forName("UTF-8")}));
final HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
final HttpEntity<JSONObject> response = restTemplate.exchange(uri, HttpMethod.GET, requestEntity, JSONObject.class);
return response;
}
}
我的 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.spp.mui.gwt.server.config.WebAppContextExperimental</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>gwt</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>gwt</servlet-name>
<url-pattern>/EMKT/service/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>0</session-timeout>
</session-config>
</web-app>
我可以看到我的 Controller 方法映射到服务器启动...
17:48:58,651 INFO [RequestMappingHandlerMapping] Mapped "{[/rest/resources],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}"
17:48:58,651 INFO [RequestMappingHandlerMapping] Mapped "{[/rest/locations],methods=[GET],params=[],headers=[],consumes=[],produces=[application/json],custom=[]}"
当测试运行时,我得到...
17:49:00,617 DEBUG [AutowiredAnnotationBeanPostProcessor] Autowiring by type from bean name 'com.spp.mui.gwt.server.controller.stub.StubRestClientITCase' to bean named 'restTemplate'
17:49:00,648 DEBUG [RestTemplate] Created GET request for "http://localhost:8080/EMKT/services/rest/resources?q=*&indexFrom=0&indexTo=24"
17:49:00,680 DEBUG [RestTemplate] Setting request Accept header to [application/json]
17:49:00,742 WARN [RestTemplate] GET request for "http://localhost:8080/EMKT/services/rest/resources?q=*&indexFrom=0&indexTo=24" resulted in 404 (Not Found); invoking error handler
终于……
Tests in error:
testGetResources(com.spp.mui.gwt.server.controller.stub.StubRestClientITCase): 404 Not Found
可能是什么问题?认为它与 servlet-mapping 中的 url-pattern 有关。我曾尝试在设置上遵循 Spring 文档,但没有成功。注意:虽然我有一个 GWT-SL 设置来映射 RPC 服务接口(interface),但我对此并不灵活。
更新 #1
如果我尝试使用
curl --verbose -H "Accept: application/json" "localhost:8081/spp-emkt-mui-experimental/EMKT/service/rest/resources?q=*&indexFrom=0&indexTo=24"
针对 Tomcat 6 部署(使用 cargo 插件),我得到了不同的结果:
* About to connect() to localhost port 8081 (#0)
* Trying 127.0.0.1... connected
* Connected to localhost (127.0.0.1) port 8081 (#0)
> GET /spp-emkt-mui-experimental/EMKT/service/rest/resources?q=*&indexFrom=0&indexTo=24 HTTP/1.1
> User-Agent: curl/7.21.1 (i686-pc-mingw32) libcurl/7.21.1 OpenSSL/0.9.8r zlib/1.2.3
> Host: localhost:8081
> Accept: */*
>
< HTTP/1.1 406 Not Acceptable
< Server: Apache-Coyote/1.1
< Content-Type: text/html;charset=utf-8
< Content-Length: 1070
< Date: Tue, 28 Feb 2012 05:00:26 GMT
这似乎表明我没有在我的请求中发送适当的 header 信息。嗯嗯嗯。
更新 #2
书面测试返回 404。而 curl 则返回 406。
我搜索了很多看似相关的帖子并尝试了很多东西,我想知道 Spring MVC、GWT-RPC 和 GWT-SL 是否能够组合在同一个容器中。考虑迁移到 RestyGWT,服务器端是 Spring MVC。评论?
最佳答案
这对我来说绝对是一个学习练习。我必须清除一些配置方面的障碍,以便 GWT RPC 和 Spring MVC 可以很好地协同工作。
我现在有一个工作测试。我的“失礼”试图返回一个@ResponseBody 注释的 JSONObject。 不要这样做!我制作了一个自定义 DTO,并使用 @JsonProperty、@JsonSerialize 和 @JsonDeserialize 等 Jackson 注释进行注释,以按照我想要的方式获得 I/O。
如果有人感兴趣,我将在下面展示我的工作测试和配置更新...
测试
@ContextConfiguration(classes={ RestClientContext.class }, loader=AnnotationConfigContextLoader.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class SuggestionsClientITCase {
private static final String SCHEME = "http";
private static final String HOST = "localhost";
private static final int PORT = 8080;
private static final String QUERY_KEY = "q";
private static final String INDEX_FROM_KEY = "indexFrom";
private static final String INDEX_TO_KEY = "indexTo";;
private Logger log = LoggerFactory.getLogger(SuggestionsClientITCase.class);
@Inject
RestTemplate restTemplate;
@Test
public void testGetResources() {
// Case 1: Discover all resources using * (asterisk), first 25
// -- the total # of resources in TestData is 250
// -- the total # of options returned should be constrained by indexTo - indexFrom = 25
happyPathAssertions(Endpoints.GET_RESOURCES, "*", 0, 24, 250, 25);
}
@Test
public void testGetLocations() {
// Case 1: Discover all resources using * (asterisk), first 25
// -- the total # of locations in TestData is 4316
// -- the total # of options returned should be constrained by indexTo - indexFrom = 25
happyPathAssertions(Endpoints.GET_LOCATIONS, "*", 0, 24, 4316, 25);
}
private void happyPathAssertions(String endpointUrl, String query, int indexFrom, int indexTo, int expectedTotal, int expectedOptionsPerPage) {
final URI uri = buildUri(query, indexFrom, indexTo, endpointUrl);
final HttpEntity<SuggestionsPayload> response = obtainResponse(uri);
Assert.assertTrue(response.hasBody());
Assert.assertEquals(expectedTotal, response.getBody().getTotalSize());
Assert.assertEquals(expectedOptionsPerPage, response.getBody().getOptions().size());
}
private URI buildUri(String query, int indexFrom, int indexTo, String endPointUrl) {
final UriComponents uriComponents =
UriComponentsBuilder.newInstance()
.scheme(SCHEME).host(HOST).port(PORT).path(Endpoints.REST_PREFIX + endPointUrl)
.queryParam(QUERY_KEY, query)
.queryParam(INDEX_FROM_KEY, indexFrom)
.queryParam(INDEX_TO_KEY, indexTo)
.build()
.encode();
final URI uri = uriComponents.toUri();
return uri;
}
private HttpEntity<SuggestionsPayload> obtainResponse(URI uri) {
final HttpHeaders requestHeaders = new HttpHeaders();
requestHeaders.setAccept(Arrays.asList(new MediaType[] {MediaType.APPLICATION_JSON}));
requestHeaders.setAcceptCharset(Arrays.asList(new Charset[] {Charset.forName("UTF-8")}));
final HttpEntity<?> requestEntity = new HttpEntity(requestHeaders);
final HttpEntity<SuggestionsPayload> response = restTemplate.exchange(uri, HttpMethod.GET, requestEntity, SuggestionsPayload.class);
return response;
}
}
Controller
@Controller
@RequestMapping("/" + Endpoints.REST_PREFIX)
public class StubSuggestionsController {
@Inject
private TestData testData;
@RequestMapping(value=Endpoints.GET_RESOURCES, method=RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
public @ResponseBody SuggestionsPayload getResources(@RequestParam(value="q") String query, @RequestParam int indexFrom, @RequestParam int indexTo) {
return makeRequest(query, indexFrom, indexTo, testData.getResources());
}
@RequestMapping(value=Endpoints.GET_LOCATIONS, method=RequestMethod.GET, produces = {MediaType.APPLICATION_JSON_VALUE})
@ResponseStatus(HttpStatus.OK)
public @ResponseBody SuggestionsPayload getLocations(@RequestParam(value="q") String query, @RequestParam int indexFrom, @RequestParam int indexTo) {
return makeRequest(query, indexFrom, indexTo, testData.getLocations());
}
private SuggestionsPayload makeRequest(String query, int indexFrom, int indexTo, String[] data) {
int count = 0;
final List<SuggestionOption> possibilities = new ArrayList<SuggestionOption>();
for (final String resourceName: data) {
final String key = resourceName.toLowerCase();
final int has = key.indexOf(query.toLowerCase());
if (!query.isEmpty() && (query.equals("*") || has >= 0)) {
final SuggestionOption possibility = new SuggestionOption();
possibility.setDisplayName(resourceName);
possibility.setValue(resourceName); // shouldn't this be a unique id? e.g., resourceid
possibilities.add(possibility);
count++;
}
}
final List<SuggestionOption> options = new ArrayList<SuggestionOption>();
if (possibilities.size() > 0) {
final int end = count - 1 > indexTo ? indexTo : count - 1;
for (int i = indexFrom; i <= end; i++) {
options.add(possibilities.get(i));
}
// sort the suggestions by display name
Collections.sort(options, new Comparator<SuggestionOption>() {
@Override
public int compare(SuggestionOption o1, SuggestionOption o2) {
final int comparison = o1.getDisplayName().compareTo(o2.getDisplayName());
return comparison;
}
});
}
final SuggestionsPayload result = new SuggestionsPayload();
result.setTotalSize(count);
result.setOptions(options);
return result;
}
}
有效负载
public class SuggestionsPayload {
@JsonProperty("TotalSize")
@JsonSerialize @JsonDeserialize
private int totalSize;
@JsonProperty("Options")
@JsonSerialize @JsonDeserialize
private List<SuggestionOption> options;
public int getTotalSize() {
return totalSize;
}
public void setTotalSize(int totalSize) {
this.totalSize = totalSize;
}
public List<SuggestionOption> getOptions() {
return options;
}
public void setOptions(List<SuggestionOption> options) {
this.options = options;
}
public static class SuggestionOption {
@JsonProperty("Value")
@JsonSerialize @JsonDeserialize
private String value;
@JsonProperty("DisplayName")
@JsonSerialize @JsonDeserialize
private String displayName;
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public String getDisplayName() {
return displayName;
}
public void setDisplayName(String displayName) {
this.displayName = displayName;
}
}
}
WEB.XML
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<!-- Java-based annotation-driven Spring container definition -->
<context-param>
<param-name>contextClass</param-name>
<param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>
<!-- Location of Java @Configuration classes that configure the components that makeup this application -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>com.spp.mui.gwt.server.config.WebAppContextExperimental</param-value>
</context-param>
<!-- Specifies the default mode of this application, to be activated if no other profile (or mode) is specified -->
<context-param>
<param-name>spring.profiles.default</param-name>
<param-value>standard</param-value>
</context-param>
<!-- Creates the Spring Container shared by all Servlets and Filters -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- Exposes request on current thread of execution, required for beans
employing <aop:scoped-proxy /> or e.g., @Scope(value="request", proxyMode=ScopedProxyMode.TARGET_CLASS) -->
<listener>
<listener-class>
org.springframework.web.context.request.RequestContextListener
</listener-class>
</listener>
<!-- Reads request input using UTF-8 encoding -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
<init-param>
<param-name>forceEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Enables support for DELETE and PUT request methods with web browser clients -->
<filter>
<filter-name>hiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>hiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- Secures the application -->
<!--
<filter>
<filter-name>securityFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
<init-param>
<param-name>targetBeanName</param-name>
<param-value>springSecurityFilterChain</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>securityFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
-->
<!-- Handles requests into the application -->
<servlet>
<servlet-name>appServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<!-- No explicit configuration file reference here: everything is configured in the root container for simplicity -->
<param-name>contextConfigLocation</param-name>
<param-value></param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>appServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>Application.html</welcome-file>
</welcome-file-list>
<session-config>
<session-timeout>0</session-timeout>
</session-config>
配置
@Configuration
@Import(value={ AopConfig.class, GwtServiceConfig.class, ComponentConfig.class, MvcConfig.class })
public class WebAppContextExperimental {
// context used for web application
}
在我的 MvcConfig 中,我必须确保添加这些(特别是 GWT 支持的注册表项,因此 Spring 的 DispatcherServlet 将允许对代码生成资源的请求)
// serve static resources
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
// i.e., images, JS, and CSS
registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
// i.e., GWT module code-generated resources
registry.addResourceHandler("/*").addResourceLocations("/");
registry.addResourceHandler("/EMKT/**").addResourceLocations("/EMKT/");
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new MappingJacksonHttpMessageConverter());
}
关于json - Spring MVC、REST、JSON、DispatcherServlet 和 @RequestMapping,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9475500/
最近开始学习MongoDB。今天老师教了我们 mongoexport 命令。在练习时,我遇到了一个典型的问题,包括教练在内的其他同学都没有遇到过。我在我的 Windows 10 机器上使用 Mongo
我是 JSON Schema 的新手,读过什么是 JSON Schema 等等。但我不知道如何将 JSON Schema 链接到 JSON 以针对该 JSON Schema 进行验证。谁能解释一下?
在 xml 中,我可以在另一个 xml 文件中包含一个文件并使用它。如果您的软件从 xml 获取配置文件但没有任何方法来分离配置,如 apache/ngnix(nginx.conf - site-av
我有一个 JSON 对象,其中包含一个本身是 JSON 对象的字符串。我如何反序列化它? 我希望能够做类似的事情: #[derive(Deserialize)] struct B { c: S
考虑以下 JSON { "a": "{\"b\": 12, \"c\": \"test\"}" } 我想定义一个泛型读取 Reads[Outer[T]]对于这种序列化的 Json import
关闭。这个问题不满足Stack Overflow guidelines .它目前不接受答案。 想改善这个问题吗?更新问题,使其成为 on-topic对于堆栈溢出。 11 个月前关闭。 Improve
我的旧项目在 MySQL 中有 Standard JSON 格式的数据。 对于我在 JS (Node.js) 和 DynamoDB 中的全新项目,关于 Standard JSON格式: 是否建议将其转
JSON 值字符串、数字、true、false、null 是否是有效的 JSON? 即,是 true 一个有效的 JSON 文档?还是必须是数组/对象? 一些验证器接受这个(例如 http://jso
我有一个 JSON 字符串,其中一个字段是文本字段。这个文本字段可以包含用户在 UI 中输入的文本,如果他们输入的文本是 JSON 文本,也许是为了说明一些编码,我需要对他们的文本进行编码,以便它不会
我正在通过 IBM MQ 调用处理数据,当由 ColdFusion 10 (10,0,11,285437) 序列化时,0 将作为 +0.0 返回,它会导致无效的 JSON并且无法反序列化。 stPol
我正在从三个数组中生成一个散列,然后尝试构建一个 json。我通过 json object has array 成功了。 require 'json' A = [['A1', 'A2', 'A3'],
我从 API 接收 JSON,响应可以是 30 种类型之一。每种类型都有一组唯一的字段,但所有响应都有一个字段 type 说明它是哪种类型。 我的方法是使用serde .我为每种响应类型创建一个结构并
我正在下载一个 JSON 文件,我已将其检查为带有“https://jsonlint.com”的有效 JSON 到文档目录。然后我打开文件并再次检查,结果显示为无效的 JSON。这怎么可能????这是
我正在尝试根据从 API 接收到的数据动态创建一个 JSON 对象。 收到的示例数据:将数据解码到下面给出的 CiItems 结构中 { "class_name": "test", "
我想从字符串转换为对象。 来自 {"key1": "{\n \"key2\": \"value2\",\n \"key3\": {\n \"key4\": \"value4\"\n }\n
目前我正在使用以下代码将嵌套的 json 转换为扁平化的 json: import ( "fmt" "github.com/nytlabs/gojsonexplode" ) func
我有一个使用来自第三方 API 的数据的应用程序。我需要将 json 解码为一个结构,这需要该结构具有“传入”json 字段的 json 标签。传出的 json 字段具有不同的命名约定,因此我需要不同
我想使用 JSON 架构来验证某些值。我有两个对象,称它们为 trackedItems 和 trackedItemGroups。 trackedItemGroups 是组名称和 trackedItem
考虑以下案例类模式, case class Y (a: String, b: String) case class X (dummy: String, b: Y) 字段b是可选的,我的一些数据集没有字
我正在存储 cat ~/path/to/file/blah | 的输出jq tojson 在一个变量中,稍后在带有 JSON 内容的 curl POST 中使用。它运作良好,但它删除了所有换行符。我知
我是一名优秀的程序员,十分优秀!