Je suis en train de créer un Java « Filter » qui détecte une requête HTTP personnalisé en-tête et les en-têtes de réponse des inserts afin que le fichier télécharge automatiquement. L'en-tête de réponse qui est le plus important pour cela est l'en-tête de réponse "Type de contenu = pièce jointe". J'ai créé un objet de demande HTTP qui insère l'en-tête personnalisé: Ceci insérera l'en-tête X-Wria-télécharger dans la demande.
Ensuite, j'ai un filtre Java qui recherche cet en-tête de demande et devrait mettre l'en-tête de réponse à « Content-Type = pièce jointe » p> import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
public class Contenttypefilter implements Filter {
protected FilterConfig filterConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.filterConfig = filterConfig;
}
public void destroy() {
//noop
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
//get the headers we placed in the request
//based on those request headers, set some response headers
if(req.getHeader("X-Wria-Download") != null){
res.setHeader("Content-Type", "application/pdf");
res.setHeader("Content-Disposition", "attachment; filename=success.pdf");
}
chain.doFilter(req,res);
}
}
4 Réponses :
Essayez ceci: Définissez un attribut sur la demande si l'en-tête de la demande est présent. Ensuite, vérifiez l'attribut après le chaîne.dofilter (...) code> et définissez les en-têtes de réponse alors. P>
Ok donc j'ai essayé de faire ça. Pour une raison quelconque, après la chaîne.dofilter, le type de contenu revient toujours au texte / html.
Le problème est l'en-tête (x-wria-télécharger) de votre AjaxRequest (ici XMLHTTPQUBEST) n'est pas défini dans votre objet HTTPServletQuest avant que le filtre ne soit servi. P>
Je pense que la meilleure idée sera de utiliser un servlet dédié pour gérer votre demande Ajax b>. P>
L'en-tête (x-wria-télécharger) semble être appliqué à l'objet de la demande avant d'être transmis au filtre Java. Lorsque vous traversez le filtre en mode de débogage, il détecte l'en-tête de demande personnalisé et exécute ensuite l'instruction IF ci-dessus: Si (req.Getheader ("x-wria-télécharger")! = Null) {}.
Je pense que votre problème est lié à l'ordre du filtre d'exécution de votre contexte Web code>, à savoir quelques filtres, dans votre contexte Web, exécute après votre filtre et remplacer l'en-tête.
Le servlet Filtre est une implémentation du Chaîne de responsabilité motif p>
Vous pouvez donc essayer de: P>
. p> de cette manière, votre code sera exécuté après que le servlet soit appelé et, comme expliqué ci-dessous, si votre filtre est le premier déclaré. Dans web.xml, le code Comme vous pouvez le voir filter1 ( Le premier déclaré dans web.xml) est le premier exécuté avant que le servlet soit exécuté et que le dernier exécuté après l'exécution du servlet est exécuté. Donc, si vous voulez être sûr d'être le dernier filtre Réglage de l'en-tête, déclarez-le comme filtre1. P> L'ordre d'exécution est déterminé par l'ordre de la déclaration dans votre descripteur de déploiement (web.xml): < / p> Spécification de servlet (Section 6.2.4): P>
"La commande utilise le conteneur dans la construction de la chaîne de filtres à être
appliqué pour une demande de demande particulière est la suivante: p>
"1. Premier, les mappages de filtre correspondants dans le même
Ordre que ces éléments apparaissent dans le descripteur de déploiement. p>
"2. Suivant, les mappages de filtre correspondants dans le même
ordonner que ces éléments apparaissent dans le descripteur de déploiement. " P>
BlockQuote> Donc, pour être sûr, déclarez-le simplement comme le premier filtre de votre setheader code> sera le dernier exécuté (voir l'image ci-dessous). P>
p>
web.xml code>. De cette façon, ce sera le dernier filtre définissant l'en-tête. Et, bien sûr, définissez l'en-tête de votre code après avoir appelé
chaîne.dofilter code>, comme indiqué précédemment. P> p>
Merci! Les éléments clés qui m'a aidé à partir de ceci sont que 1) Assurez-vous que votre filtre est ajouté en premier, il sera donc appelé dernier, et 2) assurez-vous de modifier la réponse après i> appelant chaîne.dofilter (Req , res), pas auparavant, ou votre réponse peut être écrasée.
Malheureusement, cela ne fonctionnait pas pour moi à l'aide de Dropwizard 0.6 / Jetty 8. (J'essaie de modifier les valeurs de cookies.) Pour une raison quelconque, où j'ajoute le chaîne.dofilter () code> appel, Ma réponse revient avec les valeurs d'origine des en-têtes. J'ai dû résoudre mon problème de manière différente, moins souhaitable, mais je commente simplement cette réponse au cas où quelqu'un d'autre a eu des problèmes aussi.
Merci pour la bonne description. J'ai essayé de faire un tel filtre avec Jetty 9.2, mais malheureusement, il n'a pas non plus fonctionné, semble être le même problème que @duffj avait. Dans mon cas, le filtre n'a fonctionné que si je le disais comme dernier filtre de mon web.xml code>.
En supposant que vous utilisiez une enveloppe de réponse comme décrit ici par d'autres personnes, tout le secret est quand appeler GetWriter () sur la réponse initiale! C'est parce que l'objet de réponse ignore tous les en-têtes ajoutés après avoir demandé à un écrivain! P>
Ainsi, assurez-vous d'ajouter tous vos en-têtes avant d'appeler GetWriter (). Voici ma séquence recommandée pour DOFILTER (): P>
Créer une enveloppe de réponse p> li>
chaîne.dofilter (origine, emballage); p> li>
Attribuez tous les en-têtes requis à la réponse originale (!) P> li>
Ecrivez l'écrivain de la réponse originale p> li>
Copiez le contenu du wrapper à cet écrivain p> li> ol>
Êtes-vous sûr que X-wria-télécharger est correctement reçu en Java? Pouvez-vous essayer d'imprimer req.gethader ("x-wria-télécharger") et voir s'il est réellement reçu correctement dans le filtre Java?
Oui, il la reçoit correctement. Dans la déclaration ci-dessus "si": si (req.getheader ("x-wria-télécharger")! = Null) {} Il entre dans la déclaration et si je mets dans un système.out.println, il imprimera cette ligne. J'applique également la disposition de contenu au fichier, mais le type de contenu semble être écrasé à la chaîne.Filter Stage. Même si la réponse reçoit la disposition du contenu, elle ne semble pas se comporter comme si elle l'avait fait (ne télécharge pas, mais plutôt le PDF comme une page.) Je vois aussi le "x-wria-télécharger" dans L'en-tête de la demande lors de l'utilisation d'outils de développeur Chrome.
Étrangement si la suivante: res.Setheader ("type de contenu", "application / pdf"); res.Setheader ("disposition de contenu", "pièce jointe; nom de fichier = succès.pdf"); est mis en dehors de la déclaration IF, le filtre fonctionnera ensuite. Cela ne résout pas mon problème car je veux seulement que le filtre appliqué aux servlets que j'ai attaché mon en-tête personnalisé.
Ajouté une réponse avec mes commentaires à ce sujet.