Chcę przechwycić żądanie w filtrze/serwecie i dodać do niego kilka parametrów. Jednak żądanie nie ujawnia metody "setParameter", a mapa parametrów podczas manipulowania powoduje zgłoszenie błędu z informacją, że jest zablokowana. Czy istnieje alternatywa, którą mogę spróbować?Czy jest możliwe dodanie do dostępnych parametrów żądania (HttpServletRequest)?
Odpowiedz
podklasa HttpServletRequestWrapper
i zastąpić metody getParameter
. Opis tej klasy brzmi:
zapewnia wygodny implementacji interfejsu HttpServletRequest, które mogą być podklasy przez programistów chcących dostosować żądania do serwletu.
W filtrze zawij żądanie w instancji swojej podklasy.
Najpierw należy odebrać żądanie i przeczytać wszystkie jego parametry. Następnie skonstruuj inne żądanie z oryginalnymi parametrami + nowe i wyślij je ponownie.
HttpServletRequest jest niezmienny i nie ma sposobu na jego zmianę.
Ja zwykle zawijamy oryginalny HttpServletRequest do nowego CustomHttpServletRequest, który działa jako proxy do pierwotnego żądania, a następnie przekazujemy ten nowy CustomHttpServletRequest do łańcucha filtrów.
W tym CustomHttpServletRequest można zastąpić metody getParameterNames, getParameter, getParameterMap, które zwrócą pożądane parametry.
ten jest przykładem filtra:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) request;
HttpServletRequest customRequest = new CustomHttpServletRequest(httpRequest);
customRequest.addParameter(xxx, "xxx");
chain.doFilter(customRequest, response);
}
Dziękuję :). To zadziałało. –
W przeciwnym razie można użyć metody setAttribute(), która jest silnie wpisana. Dlatego można użyć metody getAttribute() ...
Dodaję to jako mechanizm oparty na plikach właściwości, który modyfikuje zwykłe żądanie. Zarówno interfejs użytkownika, jak i rzeczywisty serwlet nie mogą zostać zmienione, aby spełnić te wymagania - jest przejrzysty. –
Dlaczego po prostu nie przechowujesz zmiennych jako atrybutów Zakresu żądań zamiast próbować dołączać je do parametrów żądania?
Dodaję to jako mechanizm oparty na plikach właściwości, który modyfikuje zwykłe żądanie. Zarówno interfejs użytkownika, jak i rzeczywisty serwlet nie mogą zostać zmienione, aby spełnić te wymagania - jest przejrzysty. –
Możesz zawinąć HttpServletRequest do nowego obiektu HttpServletRequestWrapper i nadpisać niektóre metody.
Poniższy kod pochodzi z http://www.ocpsoft.org/opensource/how-to-safely-add-modify-servlet-request-parameter-values/.
Aby dodać parametr w filtrze:
public class MyFilter implements Filter {
...
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
if (request instanceof HttpServletRequest) {
HttpServletRequest httprequest = (HttpServletRequest) request;
Map<String, String[]> extraParams = new HashMap<String, String[]>();
extraParams.put("myparamname", String[] { "myparamvalue" });
request = new WrappedRequestWithParameter(httprequest, extraParams);
}
chain.doFilter(request, response);
}
...
class WrappedRequestWithParameter extends HttpServletRequestWrapper {
private final Map<String, String[]> modifiableParameters;
private Map<String, String[]> allParameters = null;
public WrappedRequestWithParameter(final HttpServletRequest request, final Map<String, String[]> additionalParams) {
super(request);
modifiableParameters = new TreeMap<String, String[]>();
modifiableParameters.putAll(additionalParams);
}
@Override
public String getParameter(final String name) {
String[] strings = getParameterMap().get(name);
if (strings != null) {
return strings[0];
}
return super.getParameter(name);
}
@Override
public Map<String, String[]> getParameterMap() {
if (allParameters == null) {
allParameters = new TreeMap<String, String[]>();
allParameters.putAll(super.getParameterMap());
allParameters.putAll(modifiableParameters);
}
// Return an unmodifiable collection because we need to uphold the interface contract.
return Collections.unmodifiableMap(allParameters);
}
@Override
public Enumeration<String> getParameterNames() {
return Collections.enumeration(getParameterMap().keySet());
}
@Override
public String[] getParameterValues(final String name) {
return getParameterMap().get(name);
}
}
}
Dziękuję :). To zadziałało. –
Czy możesz podać przykład? –
klasa publiczna CustomHttpServletRequestWrapper rozszerza HttpServletRequestWrapper { \t prywatna mapa customParameters; \t public CustomHttpServletRequestWrapper (żądanie HttpServletRequest) { \t \t super (zapytanie); \t} \t public void addCustomParameter (String name, String value) { \t \t customParameters.put (nazwa, wartość); \t} \t @Override \t ciąg getParameter publiczne (nazwa string) { \t \t ciąg originalParameter = super.getParameter (nazwa); \t if (originalParameter! = Null) { \t \t \t return originalParameter; \t } else { \t \t \t return customParameters.get (name); \t \t} \t} } –
Riccati