O pequeno mas poderoso servidor web multithreaded escrito completamente em Java SE e depois transportado para o Android.
O servidor implementa a maioria das especificações HTTP 1.1 e fornece API de servlet personalizada que pode ser usada para lidar com páginas dinâmicas. A API do servlet foi projetada após a API oficial javax.servlet , mas não é compatível. As páginas dinâmicas suportam cookies, sessões, uploads de arquivos e qualquer outra coisa para criar um aplicativo da Web comum.
O invólucro Gradle fornecido deve ser usado para construir o aplicativo:
./gradlew clean build Ao executar a compilação completa pela primeira vez, você deve primeiro instalar o Android SDK. Você pode instalá-lo manualmente ou usar o seguinte script que download e instala todas as dependências necessárias para ~/android-sdk .
./installsdk.sh Para fazer as coisas funcionarem após o logout e fazer o login, configure a variável de ambiente ANDROID_HOME :
echo " export ANDROID_HOME=~/android-sdk " >> ~ /.bashrc && source ~ /.bashrcO subprojeto HTTP é o coração do aplicativo e é independente na plataforma Android.
De fato, o aplicativo Android foi apenas uma tentativa de encontrar um uso mais prático da implementação experimental do protocolo HTTP.
Uma das metas de design era manter o artefato resultante pequeno em tamanho e minimalista em termos de dependência de outras bibliotecas - ele não requer nenhum componente de terceiros , toda a implementação do protocolo HTTP é baseada na análise de dados lidos nos soquetes RAW TCP.
Depois que o pacote ro.polak.http estiver maduro o suficiente, ele será lançado como um artefato independente.
O subprojeto pode ser testado da seguinte maneira:
./gradlew :http:clean :http:check -PskipAndroidBuildO código do pacote original foi refaturado e coberto com testes de unidade e integração. A cobertura do código deve ser mantida acima de 90%.
Todo o código do aplicativo é direcionado para o Java 7. Ele também compila para as versões SDK Android <19 (tente com recursos não é suportado, use ioutities.closesilly (fechado) em um bloco finally como uma alternativa ao fechar fluxos).
Outra restrição de compatibilidade é que Random em vez de ThreadLocalRandom é usado para gerar seqüências aleatórias em stringutities
Os testes de mutação podem ser executados executando o seguinte comando:
./gradlew :http:clean :http:pitest -PskipAndroidBuild Os resultados podem ser encontrados em http/build/reports/pitest/ro.polak.http/index.html e http/build/reports/pitest/ro.polak.http/mutation.xml .
O servidor independente pode ser usado para agrupar o subprojeto http em uma implementação do servidor executável. O subproject da CLI também é independente na plataforma Android, não é empacotada com o APK principal.
./gradlew :cli:bootRun -PskipAndroidBuildTambém é possível construir um "Uber-jar" e usá-lo como um aplicativo independente:
./gradlew :cli:fatJar -PskipAndroidBuild O artefato resultante pode então ser capturado em ./cli/build/libs/cli-all.jar .
O frasco de servidor independente pode ser executado em qualquer máquina com o seguinte comando:
java -jar ./cli/build/libs/cli-all.jarjava -jar ./cli/build/libs/cli-all.jar
-Dserver.port=8888
-Dserver.static.path=/www/public_htmlPara uma lista completa dos parâmetros disponíveis, consulte httpd.properties.

Um aplicativo de demonstração é implantado automaticamente para Heroku e pode ser contatado em:
Observe que o aplicativo implantado não contém o aplicativo de administrador , pois está disponível apenas para Android. Consulte Procfile para a descrição da implantação.
package example ;
import ro . polak . http . servlet . HttpServletRequest ;
import ro . polak . http . servlet . HttpServletResponse ;
import ro . polak . http . servlet . HttpServlet ;
public class HelloWorld extends HttpServlet {
@ Override
public void service ( HttpServletRequest request , HttpServletResponse response ) {
response . getWriter (). print ( "Hello World!" );
}
} package example ;
import java . io . IOException ;
import ro . polak . http . exception . ServletException ;
import ro . polak . http . servlet . Filter ;
import ro . polak . http . servlet . FilterChain ;
import ro . polak . http . servlet . FilterConfig ;
import ro . polak . http . servlet . HttpServletRequest ;
import ro . polak . http . servlet . HttpServletResponse ;
public class RequestLoggingFilter implements Filter {
private static final Logger LOGGER = Logger . getLogger ( RequestLoggingFilter . class . getName ());
@ Override
public void init ( FilterConfig filterConfig ) throws ServletException {
// Do nothing
}
@ Override
public void doFilter ( HttpServletRequest request , HttpServletResponse response ,
FilterChain filterChain ) throws IOException , ServletException {
LOGGER . fine ( "Handling incoming request " + request . getRequestURL ());
filterChain . doFilter ( request , response );
}
}Exemplo de servlets pode ser encontrado em http/src/main/java/exemplo.
Um uso prático dos filtros pode ser verificado no SecurityFilter.java e LogoutFilter.java do aplicativo de administrador.
O implantaçãoDescripTorBuilder é uma alternativa da API à abordagem tradicional web.xml que visa facilitar o mapeamento e o registro de filtro de mapeamento de servlet. Veja o código de exemplo abaixo.
package example ;
import java . util . List ;
import java . util . regex . Pattern ;
import ro . polak . http . configuration . DeploymentDescriptorBuilder ;
import ro . polak . http . configuration . ServerConfig ;
import ro . polak . http . session . storage . SessionStorage ;
class DeploymentDescriptorFactory {
public List < ServletContextWrapper > buildDeploymentDescriptor ( SessionStorage sessionStorage ,
ServerConfig serverConfig ) {
return DeploymentDescriptorBuilder . create ()
. withSessionStorage ( sessionStorage )
. withServerConfig ( serverConfig )
. addServletContext ()
. withContextPath ( "/example" )
. addFilter ()
. withUrlPattern ( Pattern . compile ( "^.*$" ))
. withUrlExcludedPattern ( Pattern . compile ( "^/(?:Login|Logout)" ))
. withFilterClass ( SecurityFilter . class )
. end ()
. addFilter ()
. withUrlPattern ( Pattern . compile ( "^/Logout$" ))
. withFilterClass ( LogoutFilter . class )
. end ()
. addServlet ()
. withUrlPattern ( Pattern . compile ( "^/Index$" ))
. withServletClass ( Index . class )
. end ()
. addServlet ()
. withUrlPattern ( Pattern . compile ( "^/$" ))
. withServletClass ( Index . class )
. end ()
. end ()
. build ();
}
}Servir recursos estáticos é implementado usando o padrão
O carregamento real de recursos é implementado registrando um recurso de instância na configuração do servidor.
Atualmente, existem dois provedores de recursos implementados
package ro . polak . http . resource . provider ;
import ro . polak . http . servlet . impl . HttpServletRequestImpl ;
import ro . polak . http . servlet . impl . HttpServletResponseImpl ;
import java . io . IOException ;
public class DummyResourceProvider implements ResourceProvider {
/**
* Tells whether this resource provider can load resource for given path.
*/
@ Override
public boolean canLoad ( final String path ) {
return false ; // TODO Add some logic
}
/**
* Loads the resource for the given path by copying the stream to the response.getOutputStream().
*/
@ Override
public void load ( final String path ,
final HttpServletRequestImpl request ,
final HttpServletResponseImpl response ) throws IOException {
// TODO Load the stream to response.getOutputStream();
}
/**
* Shuts down the resource provider if necessary, usually closes all open resources.
*/
@ Override
public void shutdown () {
}
}O exemplo a seguir apresenta como integrar o motor JTWIG de modelos.
Primeiro, você precisa adicionar a dependência do JTWIG no seu arquivo gradle:
// ...
dependencies {
// ...
compile ' org.jtwig:jtwig-core:5.87.0.RELEASE '
}
// ...Então ele funciona fora da caixa:
package example ;
import org . jtwig . JtwigModel ;
import org . jtwig . JtwigTemplate ;
import ro . polak . http . exception . ServletException ;
import ro . polak . http . servlet . HttpServlet ;
import ro . polak . http . servlet . HttpServletRequest ;
import ro . polak . http . servlet . HttpServletResponse ;
public class Templating extends HttpServlet {
@ Override
public void service ( HttpServletRequest request , HttpServletResponse response )
throws ServletException {
JtwigTemplate template = JtwigTemplate . inlineTemplate ( "Hello {{ var }}" );
JtwigModel model = JtwigModel . newModel (). with ( "var" , "World" );
template . render ( model , response . getOutputStream ());
}
}






Se você deseja enviar um SMS real, remova "& teste = 1" dos parâmetros de postagem.
SERVER_IP=192.168.1.1 ; SERVER_PORT=8080 ;
echo " Phone number: " ; read TO ; echo " Message: " ; read MESSAGE ;
wget -qO- --post-data " to= $TO &message= $MESSAGE &test=1 "
http:// $SERVER_IP : $SERVER_PORT /api/1.0/sms/sendO Android HTTP Server usa ícones do pacote lindamente projetado "Farm-Fresh Web Icons" da Fatcow Web Hosting! Esses conjuntos de ícones são licenciados sob uma licença Creative Commons Attribution 3.0.
O projeto é compartilhado com a licença GNU GPLV3.
Se você estiver interessado em uma licença comercial dedicada, envie -me uma linha no piotr [at] polak [dot] ro