Un serveur Web multithread petit mais puissant écrit complètement dans Java SE puis porté sur Android.
Le serveur implémente la plupart des spécifications HTTP 1.1 et fournit une API de servlet personnalisée qui peut être utilisée pour gérer les pages dynamiques. L'API Servlet est conçue après l'API officielle javax.servlet mais elle n'est pas compatible. Les pages dynamiques prennent en charge les cookies, les sessions, les téléchargements de fichiers et toute autre chose pour créer une application Web commune.
Le wrapper gradle fourni doit être utilisé pour construire l'application:
./gradlew clean build Lorsque vous exécutez la version complète pour la première fois, vous devez d'abord installer le SDK Android. Vous pouvez soit l'installer manuellement, soit utiliser le script suivant qui télécharge et installe toutes les dépendances requises sur ~/android-sdk .
./installsdk.sh Pour que les choses fonctionnent après la déconnexion et la connexion, configurez la variable d'environnement ANDROID_HOME :
echo " export ANDROID_HOME=~/android-sdk " >> ~ /.bashrc && source ~ /.bashrcLe sous-projet HTTP est le cœur de l'application et il est indépendant sur la plate-forme Android.
En fait, l'application Android n'était qu'une tentative de trouver une utilisation plus pratique de l'implémentation expérimentale du protocole HTTP.
L'un des objectifs de conception était de maintenir l'artefact résultant de petite taille et minimaliste en termes de dépendance à l'égard d'autres bibliothèques - il ne nécessite aucun composant tiers , toute la mise en œuvre du protocole HTTP est basée sur des données d'analyse lues par les prises TCP brutes.
Une fois que le package ro.polak.http est suffisamment mature, il sera publié en tant qu'artefact indépendant.
Le sous-projet peut être testé de la manière suivante:
./gradlew :http:clean :http:check -PskipAndroidBuildLe code de package d'origine a été refactorisé et recouvert de tests d'unité et d'intégration. La couverture du code doit être maintenue supérieure à 90%.
Tout le code d'application est ciblé sur Java 7. Il compile également pour les versions Android SDK <19 (essayez avec les ressources n'est pas prise en charge, utilisez ioutilities.closely (fermé) dans un bloc finally comme alternative lors de la fermeture des flux).
Une autre contrainte de compatibilité est que Random au lieu du ThreadLocalRandom est utilisé pour générer des séquences aléatoires en stringutilities
Les tests de mutation peuvent être exécutés en exécutant la commande suivante:
./gradlew :http:clean :http:pitest -PskipAndroidBuild Les résultats peuvent ensuite être trouvés sous http/build/reports/pitest/ro.polak.http/index.html et http/build/reports/pitest/ro.polak.http/mutation.xml .
Le serveur autonome peut être utilisé pour regrouper le sous-projet http dans une implémentation de serveur exécutable. Le sous-projet CLI est également indépendant sur la plate-forme Android, il n'est pas regroupé avec l'APK principal.
./gradlew :cli:bootRun -PskipAndroidBuildIl est également possible de créer un "Uber-Jar" et de l'utiliser comme une application autonome:
./gradlew :cli:fatJar -PskipAndroidBuild L'artefact résultant peut ensuite être saisi de ./cli/build/libs/cli-all.jar .
Le pot de serveur autonome peut être exécuté sur n'importe quelle machine avec la commande suivante:
java -jar ./cli/build/libs/cli-all.jarjava -jar ./cli/build/libs/cli-all.jar
-Dserver.port=8888
-Dserver.static.path=/www/public_htmlPour une liste complète des paramètres disponibles, reportez-vous à httpd.properties.

Une application de démonstration est automatiquement déployée sur Heroku et peut être atteinte à:
Veuillez noter que l'application déployée ne contient pas l'application d'administration car cela n'est disponible que pour Android. Voir ProCFile pour la description du déploiement.
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 );
}
}Des exemples de servlets peuvent être trouvés dans HTTP / SRC / Main / Java / Exemple.
Une utilisation pratique des filtres peut être vérifiée sur SecurityFilter.java et LogoutFilter.java de l'application Admin.
DeploymentDescriptorBuilder est une alternative API à l'approche traditionnelle web.xml qui vise à faciliter la cartographie des servlets et l'enregistrement des filtres. Voir l'exemple de code ci-dessous.
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 ();
}
}Le service des ressources statiques est implémenté à l'aide de DefaultServlet
Le chargement réel des ressources est implémenté en enregistrant une instance ResourceProvider dans la configuration du serveur.
Actuellement, deux fournisseurs de ressources sont mis en œuvre
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 () {
}
}L'exemple suivant présente comment intégrer le moteur de modèles JTWIG.
Vous devez d'abord ajouter de la dépendance JTWig dans votre fichier gradle:
// ...
dependencies {
// ...
compile ' org.jtwig:jtwig-core:5.87.0.RELEASE '
}
// ...Ensuite, cela fonctionne hors de la boîte:
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 ());
}
}






Si vous souhaitez envoyer un vrai SMS, veuillez supprimer "& test = 1" des paramètres du post.
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/sendAndroid HTTP Server utilise des icônes du pack de "icônes Web de Farm-Fresh" magnifiquement conçu par l'hébergement Web Fatcow! Ces ensembles d'icônes sont autorisés sous une licence Creative Commons Attribution 3.0.
Le projet est partagé sur la licence GNU GPLV3.
Si vous êtes intéressé par une licence commerciale dédiée, veuillez me laisser une ligne chez piotr [at] polak [dot] ro