1+ package com .baeldung .blockingnonblocking ;
2+
3+ import com .github .tomakehurst .wiremock .junit .WireMockRule ;
4+ import org .junit .Before ;
5+ import org .junit .Rule ;
6+ import org .junit .Test ;
7+
8+ import java .io .IOException ;
9+ import java .net .InetSocketAddress ;
10+ import java .nio .ByteBuffer ;
11+ import java .nio .CharBuffer ;
12+ import java .nio .channels .SocketChannel ;
13+ import java .nio .charset .Charset ;
14+ import java .nio .charset .CharsetDecoder ;
15+ import java .nio .charset .StandardCharsets ;
16+
17+ import static com .github .tomakehurst .wiremock .client .WireMock .*;
18+ import static com .github .tomakehurst .wiremock .core .WireMockConfiguration .wireMockConfig ;
19+ import static org .junit .Assert .assertTrue ;
20+
21+ public class NonBlockingClientUnitTest {
22+ private String REQUESTED_RESOURCE = "/test.json" ;
23+
24+ @ Rule public WireMockRule wireMockRule = new WireMockRule (wireMockConfig ().dynamicPort ());
25+
26+ @ Before
27+ public void setup () {
28+ stubFor (get (urlEqualTo (REQUESTED_RESOURCE )).willReturn (aResponse ()
29+ .withStatus (200 )
30+ .withBody ("{ \" response\" : \" It worked!\" }" )));
31+ }
32+
33+ @ Test
34+ public void givenJavaNIOSocketChannel_whenReadingAndWriting_thenUseBuffers () throws IOException {
35+ // given a NIO SocketChannel and a charset
36+ InetSocketAddress address = new InetSocketAddress ("localhost" , wireMockRule .port ());
37+ SocketChannel socketChannel = SocketChannel .open (address );
38+ Charset charset = StandardCharsets .UTF_8 ;
39+
40+ // when we write and read using buffers
41+ socketChannel .write (charset .encode (CharBuffer .wrap ("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r \n \r \n " )));
42+
43+ ByteBuffer buffer = ByteBuffer .allocate (8 ); // or allocateDirect if we need direct memory access
44+ CharBuffer charBuffer = CharBuffer .allocate (8192 );
45+ CharsetDecoder decoder = charset .newDecoder ();
46+ StringBuilder ourStore = new StringBuilder ();
47+ while (socketChannel .read (buffer ) != -1 || buffer .position () > 0 ) {
48+ buffer .flip ();
49+ storeBufferContents (buffer , charBuffer , decoder , ourStore );
50+ buffer .compact ();
51+ }
52+ socketChannel .close ();
53+
54+ // then we read and saved our data
55+ assertTrue (ourStore
56+ .toString ()
57+ .contains ("It worked!" ));
58+ }
59+
60+ @ Test
61+ public void givenJavaNIO_whenReadingAndWriting_thenSmallBuffers () throws IOException {
62+ // given a NIO SocketChannel and a charset
63+ InetSocketAddress address = new InetSocketAddress ("localhost" , wireMockRule .port ());
64+ SocketChannel socket = SocketChannel .open (address );
65+ Charset charset = StandardCharsets .UTF_8 ;
66+
67+ // when we write and read using buffers that are too small for our message
68+ socket .write (charset .encode (CharBuffer .wrap ("GET " + REQUESTED_RESOURCE + " HTTP/1.0\r \n \r \n " )));
69+
70+ ByteBuffer buffer = ByteBuffer .allocate (8 ); // or allocateDirect if we need direct memory access
71+ CharBuffer charBuffer = CharBuffer .allocate (8 );
72+ CharsetDecoder decoder = charset .newDecoder ();
73+ StringBuilder ourStore = new StringBuilder ();
74+ while (socket .read (buffer ) != -1 || buffer .position () > 0 ) {
75+ buffer .flip ();
76+ storeBufferContents (buffer , charBuffer , decoder , ourStore );
77+ buffer .compact ();
78+ }
79+ socket .close ();
80+
81+ // then we read and saved our data
82+ assertTrue (ourStore
83+ .toString ()
84+ .contains ("It worked!" ));
85+ }
86+
87+ void storeBufferContents (ByteBuffer buffer , CharBuffer charBuffer , CharsetDecoder decoder , StringBuilder ourStore ) {
88+ decoder .decode (buffer , charBuffer , true );
89+ charBuffer .flip ();
90+ ourStore .append (charBuffer );
91+ charBuffer .clear ();
92+ }
93+
94+ }
0 commit comments