format/parse ISO 8601 ignoring the fraction


    static Instant parseIsoInstant(final String formatted) {
        return Instant.from(DateTimeFormatter.ISO_INSTANT.parse(formatted))
                .with(ChronoField.NANO_OF_SECOND, 0L);
    }

    static String formatIsoInstant(final TemporalAccessor parsed) {
        return DateTimeFormatter.ISO_INSTANT.format(
                Instant.from(parsed).with(ChronoField.NANO_OF_SECOND, 0L));
    }

    static Date parseIsoDate(final String formatted) {
        return Date.from(parseIsoInstant(formatted));
    }

    static String formatIsoDate(final Date parsed) {
        return formatIsoInstant(parsed.toInstant());
    }

ISO 8601 Date/Time


RFC-3339 / 5.6. Internet Date/Time Format에 ISO-8601 Date/Time 에서 대해 설명하고 있다.
년년년년-월월-일일T시시:분분:초초 까지는 대충 쓰면 되는데 그 뒤의 부분들이 문제다. (초초 부분도 0~59 만 사용되는 것이 아니지만 일단 넘어가자.)

time-secfrac

time-secfrac    = "." 1*DIGIT

초초 뒤에 . 을 붙이고 1개 이상의 초 단위 이하의 값을 사용할 수가 있다.

1976-10-31T10:00:00.2134213213213213213213Z

“Z” / time-numoffset

보통의 경우에 다음과 같이 오프셋을 사용할 수 있다.

1976-10-31T10:00:00+09:00
1976-10-31T10:00:00-08:00

근데 00:00 앞에는 + 를 붙여야 하는가 - 를 붙여야 하는가?
머리를 어떻게 굴렸는지는 잘 모르겠지만 Z 를 사용하기로 했나보다.

1976-10-31T10:00:00Z

4.3. Unknown Local Offset Convention 에 보면 Z+00:00 과 같고 -00:00 은 TimeZone 을 모를(unknown) 때 사용한다고 한다.

ResourceContext#getResource and ResourceContext#initResource work differently


Following two codes work differently, I don’t know why.

return locateOperator(
        operatorId_,
        (operatorId, operator) -> resourceContext.initResource(
                new DevicesResource()
                .operatorId(operatorId)
                .operator(operator))
);
return locateOperator(
        operatorId_,
        (operatorId, operator) -> resourceContext.getResource(
                DevicesResource.class)
        .operatorId(operatorId)
        .operator(operator)
);

The DevicesResource class has a field.

@PersistenceContext
private EntityManger entityManager

getResource properly injects while initResource don’t.

getResource

The resolved resource instance is properly initialized in the context of the current request processing scope. The scope of the resolved resource instance depends on the managing container. For resources managed by JAX-RS container the default scope is per-request.

initResource

Initialize the resource or sub-resource instance. All JAX-RS injectable fields in the resource instance will be properly initialized in the context of the current request processing scope.

중복된 HTTP 헤더는 모든 경우에 가능한가?


references

rfc-2616

4.2 Message Headers 에 다음과 같이 씨부라려져 있다.

Multiple message-header fields with the same field-name MAY be
present in a message if and only if the entire field-value for that
header field is defined as a comma-separated list [i.e., #(values)].
It MUST be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma. The order in which header fields with the same
field-name are received is therefore significant to the
interpretation of the combined field value, and thus a proxy MUST NOT
change the order of these field values when a message is forwarded.

잘못된 해석을 한 번 하자면 다음과 같다.

그냥 됨.

간단하게 쓰면 될 일을 왜 저렇게 썼는지 곰곰히 살펴보도록 하자.

Multiple message-header fields with the same field-name MAY be
present in a message

여기까지는 좋다. 근데..

                     if and only if the entire field-value for that
header field is defined as a comma-separated list [i.e., #(values)].

if and only if 와 그 뒤의 내용이 좀 껄쩍지근한 건 단지 느낌일 뿐인걸까?

It MUST be possible to combine the multiple header fields into one
"field-name: field-value" pair, without changing the semantics of the
message, by appending each subsequent field-value to the first, each
separated by a comma.

이 부분이 좀 중요한 것 같다. 역설적으로, 만약 다음과 같은 사용될 수 있다면,

My-Awesome-Header: value1
My-Awesome-Header: value2
My-Awesome-Header: value3

다음과 같이 콤마(‘,’)로 분리해서 한꺼번에 사용해도 동일한 의미와 순서를 가지는 헤더에 한해서, 위에 있는 것 처럼, 같은 이름으로 나눠서 사용할 수(MAY) 있다는 얘기다.

My-Awesome-Header: value1,value2,value3

Accept 헤더를 다음과 같이 사용하면

Accept: application/xml
Accept: application/json

원래는 아래와 같이 사용해야 하는데 (그렇게 정의되어 있다.) 위처럼 사용할 수 있다는 의미다.

Accept: application/xml,application/json

하지만 Content-Type 를 다음과 같이 사용하면 안될 듯 하다.

PUT /items/1 HTTP/1.1
Host: whatever
Content-Type: application/xml
Content-Type: application/json

ㅋㅋㅋ

다음과 같은 응답메시지를 볼 수 있을지도…

HTTP/1.1 400 씨발새꺄 장난하냐?

using transitive-dependency’s version


problem

다음과 같은 dependency-tree 가 있다고 하자.

A <- B <- C

C 에서 Aversion 값을 사용하고자 할 때 어떻게 하면 될까?

solution

add direct (redundant) dependency

// C/pom.xml
<properties>
  <a.version>x.y.z</a.version>
</properties>
<dependencies>
  <dependency>
    <artifactId>A</artifactId>
    <version>${a.vresion}</version>
    <scope>compile</scope>
  </dependency>
  <dependency>
    <artifactId>B</artifactId>
    <version>x.y.z</version>
    <scope>compile</scope>
  </dependency>
</dependencies>

Now we can use the value of ${a.version} in other files.

A's version is ${a.version}.

enforce dependency convergence

<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-enforcer-plugin</artifactId>
  <executions>
    <execution>
      <id>enforce</id>
      <configuration>
        <rules>
           <dependencyConvergence/>
        </rules>
      </configuration>
      <goals>
        <goal>enforce</goal>
      </goals>
    </execution>
  </executions>
</plugin>