Asymmetries between FilterInputStream and FilterOutputStream


Constructors

FilterInputStream(in) is protected and FilterOutputStream(out) is public.

protected FilterInputStream(InputStream in) {
    this.in = in;
}
public FilterOutputStream(OutputStream out) {
    this.out = out;
}

Methods

FilterInputStream#read(b, off, len) performs in.read(b, off, len) and returns the result and FilterOutputStream#write(b, off, len), on the other hand, calls the write method of one argument on each byte to output.

public int read(byte b[], int off, int len) throws IOException {
    return in.read(b, off, len);
}
public void write(byte b[], int off, int len) throws IOException {
    if ((off | len | (b.length - (len + off)) | (off + len)) < 0)
        throw new IndexOutOfBoundsException();

    for (int i = 0 ; i < len ; i++) {
       write(b[off + i]);
    }
}

Loading BeanConfig from a file


{
  "schemes": [${swagger.config.schemes}],
  "host": "${swagger.config.host}",
  "basePath": "${swagger.config.basePath}",
  "description": "description",
  "resourcePackage": "your.pkg.to.jax.rs.resources",
  "scan": true,
  "version": "${api.version}",
  "info": {
    "title": "title"
  }
}
final ObjectMapper mapper = new ObjectMapper();
try {
    final BeanConfig config = mapper.readValue(
        getClass().getResource("/swagger/config.json"),
        BeanConfig.class);
} catch (final IOException ioe) {
    ioe.printStackTrace(System.err);
}

Redirecting to swagger-ui from JAX-RS


references

WebApp

swagger-ui를 다음과 같이 src/main/webapp 아래에 설치하였다.

.
|-- LICENSE
|-- nb-configuration.xml
|-- pom.xml
|-- README.md
`-- src
    |-- main
    |   |-- java
    |   |   `-- com
    |   |-- resources
    |   |   |-- com
    |   |   |-- META-INF
    |   |   `-- swagger
    |   |-- webapp
    |   |   |-- swagger-ui
    |   |   `-- WEB-INF
    |   `-- webapp-embedded-glassfish
    |       `-- WEB-INF
    `-- test
        `-- java

다음과 같은 주소들이 존재한다.

...://.../<context-root>/swagger-ui                 // swagger-ui path
...://.../<context-root>/<api-path>/swagger.json    // on-demand swagger.json
...://.../<context-root>/<api-path>/*               // jax-rs root resources

Post/Redirect/Get

@Path("/swagger-ui")
public class SwaggerUiResource {

    @GET
    public Response read() throws IOException {

        // ...://.../<context-root>/<application-path>/swagger.json
        final URI swaggerJson
            = uriInfo.getBaseUriBuilder()
            .path("swagger.json")
            .build();

        // ...://.../<context-root>
        final URI contextRoot
            = URI.create(servletRequest.getRequestURL().toString())
            .resolve(servletRequest.getContextPath());

        // ...://.../<context-root>/swagger-ui/index.html?url=swaggerJson
        final URI swaggerUi
            = UriBuilder.fromUri(contextRoot)
            .path("swagger-ui")
            .path("index.html")
            .queryParam("url", swaggerJson).build();

        // Post/Redirect/Get
        return Response.seeOther(swaggerUi).build();
    }

    @Context
    private UriInfo uriInfo;

    @Context
    private HttpServletRequest servletRequest;
}

Now when a user accesses to
.../<context-root>/<application-path>/swagger-ui
it redirects to
.../<context-root>/swagger-ui/index.html?url=.../<context-root>/<application-path>/swagger.json

Swagger-Core JAX-RS Project Setup (KOR)


본 문서는 Swagger Core JAX RS Project Setup 1.5.X을 적용하면서 얻은 경험을 기술합니다.
원본의 내용과는 다른 부분이 있습니다.

references

dependency

swagger-jersey2-jaxrs가 아닌 swagger-jarx를 추가한다.

<dependency>
  <groupId>io.swagger</groupId>
  <!--artifactId>swagger-jersey2-jaxrs</artifactId-->
  <artifactId>swagger-jaxrs</artifactId>
  <version>1.5.4</version>
  <scope>compile</scope>
</dependency>

WorldApplication

이 부분은 어쩔 수 없이 모든 리소스 클래스와 swagger와 관련된 클래스 두개를 추가했다.

@ApplicationPath("/api")
public class WorldApplication extends Application {
    @Override
    public Set<Class<?>> getClasses() {
        final Set<Class<?>> classes = new HashSet();
        // add my own resource classes here
        classes.add(ApiListingResource.class);
        classes.add(SwaggerSerializers.class);
        return classes;
    }
}

BeanConfiguration

Target environment를 구분하기 위해 다음과 같이 json파일을 하나 생성하고 Jackson을 통해 읽어드린다.

{
  "basePath": "${swagger.config.basePath}",
  "description": "description",
  "host": "${swagger.config.host}",
  "resourcePackage": "com.github.jinahya.mysql.world.ws.rs",
  "scan": true,
  "schemes": [${swagger.config.schemes}],
  "version": "${api.version}",
  "info": {
    "title": "MySQL World Database API"
  }
}
public WorldApplication() {
    super();
//        BeanConfig beanConfig = new BeanConfig();
//        beanConfig.setTitle("world");
//        beanConfig.setVersion("1.0.0");
//        beanConfig.setSchemes(new String[]{"http"});
//        beanConfig.setHost("localhost:8080");
//        beanConfig.setBasePath("world/api");
//        beanConfig.setResourcePackage("com.github.jinahya.mysql.world.ws.rs");
//        beanConfig.setScan(true);
    final ObjectMapper mapper = new ObjectMapper();
    try {
        mapper.readValue(
            getClass().getResource("/bean-config.json"), BeanConfig.class);
    } catch (final IOException ioe) {
        ioe.printStackTrace(System.err);
    }
}

Swagger-UI

swagger-uisrc/main/webapp 아래에 복사하고 다음과 같이 filtering를 준비한다.

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript">
      $(function () {
        var url = window.location.search.match(/url=([^&]+)/);
        if (url && url.length > 1) {
          url = decodeURIComponent(url[1]);
        } else {
          url = "${app.contextUrl}/swagger.json";
        }
    </script>
  </head>
</html>

Dagger with TestNG


It’s just simple.

public class MyTest {

    @BeforeClass
    public void inject() {
        ObjectGraph.create(new MyModule()).inject(this);
    }

    @Inject
    String injected;
}

New Kids On The Block

I wrote a simple library works with an annotation.

@Dagger(modules = MyModule.class)
public class MyTest {

//    @BeforeClass
//    public void inject() {
//        ObjectGraph.create(new MyModule()).inject(this);
//    }

    @Inject
    String injected;
}