/* * Copyright (c) 2002-2012 Alibaba Group Holding Limited. * All rights reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.alibaba.citrus.service.requestcontext.parser.impl; import static com.alibaba.citrus.util.Assert.*; import java.util.AbstractMap; import java.util.AbstractSet; import java.util.Enumeration; import java.util.Iterator; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import javax.servlet.http.HttpServletRequest; import com.alibaba.citrus.service.requestcontext.RequestContext; import com.alibaba.citrus.service.requestcontext.parser.CookieParser; import com.alibaba.citrus.service.requestcontext.parser.ParameterParser; import com.alibaba.citrus.service.requestcontext.parser.ParameterParserFilter; import com.alibaba.citrus.service.requestcontext.parser.ParserRequestContext; import com.alibaba.citrus.service.requestcontext.support.AbstractRequestContextWrapper; import com.alibaba.citrus.service.requestcontext.support.AbstractRequestWrapper; import com.alibaba.citrus.service.upload.UploadService; import com.alibaba.citrus.util.StringUtil; import org.springframework.beans.PropertyEditorRegistrar; /** 自动解析request parameters和cookie parameters,并透明地处理upload请求的request context实现。 */ public class ParserRequestContextImpl extends AbstractRequestContextWrapper implements ParserRequestContext { private PropertyEditorRegistrar propertyEditorRegistrar; private boolean converterQuiet; private String caseFolding; private boolean autoUpload; private boolean unescapeParameters; private boolean useServletEngineParser; private boolean useBodyEncodingForURI; private String uriEncoding; private boolean trimming; private UploadService upload; private ParameterParser parameters; private ParameterParserFilter[] filters; private String htmlFieldSuffix; private CookieParser cookies; /** * 包装一个<code>RequestContext</code>对象。 * * @param wrappedContext 被包装的<code>RequestContext</code> */ public ParserRequestContextImpl(RequestContext wrappedContext) { super(wrappedContext); setRequest(new RequestWrapper(wrappedContext.getRequest())); } /** 取得用来转换参数类型的propertyEditor注册器。 */ public PropertyEditorRegistrar getPropertyEditorRegistrar() { return propertyEditorRegistrar; } /** 设置用来转换参数类型的propertyEditor注册器。 */ public void setPropertyEditorRegistrar(PropertyEditorRegistrar propertyEditorRegistrar) { this.propertyEditorRegistrar = propertyEditorRegistrar; } /** 类型转换出错时,是否不报错,而是返回默认值。 */ public boolean isConverterQuiet() { return converterQuiet; } /** 设置类型转换出错时,是否不报错,而是返回默认值。 */ public void setConverterQuiet(boolean converterQuiet) { this.converterQuiet = converterQuiet; } /** 是否自动执行Upload。 */ public boolean isAutoUpload() { return autoUpload; } /** 是否自动执行Upload。 */ public void setAutoUpload(boolean autoUpload) { this.autoUpload = autoUpload; } /** 按照指定的风格转换parameters和cookies的名称,默认为“小写加下划线”。 */ public String getCaseFolding() { return caseFolding; } /** 按照指定的风格转换parameters和cookies的名称,默认为“小写加下划线”。 */ public void setCaseFolding(String folding) { this.caseFolding = folding; } /** 是否对参数进行HTML entities解码,默认为<code>false</code>。 */ public boolean isUnescapeParameters() { return unescapeParameters; } /** 是否对参数进行HTML entities解码,默认为<code>false</code>。 */ public void setUnescapeParameters(boolean unescapeParameters) { this.unescapeParameters = unescapeParameters; } /** 是否使用servlet引擎的parser,默认为<code>false</code>。 */ public void setUseServletEngineParser(boolean useServletEngineParser) { this.useServletEngineParser = useServletEngineParser; } /** 是否使用servlet引擎的parser,默认为<code>false</code>。 */ public boolean isUseServletEngineParser() { return useServletEngineParser; } /** 是否以request.setCharacterEncoding所指定的编码来解析query,默认为<code>true</code>。 */ public boolean isUseBodyEncodingForURI() { return useBodyEncodingForURI; } /** 是否以request.setCharacterEncoding所指定的编码来解析query,默认为<code>true</code>。 */ public void setUseBodyEncodingForURI(boolean useBodyEncodingForURI) { this.useBodyEncodingForURI = useBodyEncodingForURI; } /** * 当<code>useServletEngineParser==false</code>并且 * <code>useBodyEncodingForURI=false</code>时,用该编码来解释GET请求的参数。 */ public String getURIEncoding() { return uriEncoding; } /** * 当<code>useServletEngineParser==false</code>并且 * <code>useBodyEncodingForURI=false</code>时,用该编码来解释GET请求的参数。 */ public void setURIEncoding(String uriEncoding) { this.uriEncoding = uriEncoding; } /** 是否对输入参数进行trimming。默认为<code>true</code>。 */ public boolean isTrimming() { return trimming; } /** 是否对输入参数进行trimming。默认为<code>true</code>。 */ public void setTrimming(boolean trimming) { this.trimming = trimming; } /** * 设置upload service。 * * @param upload <code>UploadService</code>对象 */ public void setUploadService(UploadService upload) { this.upload = upload; } /** 设置用于过滤参数的filters。 */ public void setParameterParserFilters(ParameterParserFilter[] filters) { this.filters = filters; } /** 取得代表HTML字段的后缀。 */ public String getHtmlFieldSuffix() { return htmlFieldSuffix; } /** 设置代表HTML字段的后缀。 */ public void setHtmlFieldSuffix(String htmlFieldSuffix) { this.htmlFieldSuffix = htmlFieldSuffix; } /** * 取得所有query参数。第一次执行此方法时,将会解析request,从中取得所有的参数。 * * @return <code>ParameterParser</code>实例 */ public ParameterParser getParameters() { if (parameters == null) { parameters = new ParameterParserImpl(this, upload, trimming, filters, htmlFieldSuffix); } return parameters; } /** * 取得所有cookie。第一次执行此方法时,将会解析request,从中取得所有cookies。 * * @return <code>CookieParser</code>实例 */ public CookieParser getCookies() { if (cookies == null) { cookies = new CookieParserImpl(this); } return cookies; } /** * 将指定的字符串根据<code>getCaseFolding()</code>的设置,转换成指定大小写形式。 * * @param str 要转换的字符串 * @return 转换后的字符串 */ public String convertCase(String str) { String folding = getCaseFolding(); str = StringUtil.trimToEmpty(str); if (URL_CASE_FOLDING_LOWER.equals(folding)) { str = StringUtil.toLowerCase(str); } else if (URL_CASE_FOLDING_LOWER_WITH_UNDERSCORES.equals(folding)) { str = StringUtil.toLowerCaseWithUnderscores(str); } else if (URL_CASE_FOLDING_UPPER.equals(folding)) { str = StringUtil.toUpperCase(str); } else if (URL_CASE_FOLDING_UPPER_WITH_UNDERSCORES.equals(folding)) { str = StringUtil.toUpperCaseWithUnderscores(str); } return str; } /** 包装request。 */ private class RequestWrapper extends AbstractRequestWrapper { private final ParameterMap parameterMap = new ParameterMap(); public RequestWrapper(HttpServletRequest request) { super(ParserRequestContextImpl.this, request); } @Override public String getParameter(String key) { return getParameters().getString(key); } @Override public Map<String, String[]> getParameterMap() { return parameterMap; } @Override public Enumeration<String> getParameterNames() { return new IteratorEnumeration<String>(getParameters().keySet().iterator()); } @Override public String[] getParameterValues(String key) { return getParameters().getStrings(key); } } private class IteratorEnumeration<E> implements Enumeration<E> { private Iterator<E> iterator; public IteratorEnumeration(Iterator<E> iterator) { this.iterator = iterator; } public boolean hasMoreElements() { return iterator.hasNext(); } public E nextElement() { return iterator.next(); } } /** 一个以ParameterParser为基础的map。 */ private class ParameterMap extends AbstractMap<String, String[]> { private final ParameterEntrySet entrySet = new ParameterEntrySet(); @Override public boolean containsKey(Object key) { try { return getParameters().containsKey((String) key); } catch (ClassCastException e) { return false; } } @Override public String[] get(Object key) { try { return getParameters().getStrings((String) key); } catch (ClassCastException e) { return null; } } @Override public Set<java.util.Map.Entry<String, String[]>> entrySet() { return entrySet; } } private class ParameterEntrySet extends AbstractSet<Map.Entry<String, String[]>> { @Override public Iterator<Map.Entry<String, String[]>> iterator() { final Iterator<String> i = getParameters().keySet().iterator(); return new Iterator<Map.Entry<String, String[]>>() { public boolean hasNext() { return i.hasNext(); } public Entry<String, String[]> next() { return new ParameterEntry(i.next()); } public void remove() { unsupportedOperation(); } }; } @Override public int size() { return getParameters().size(); } } private class ParameterEntry implements Map.Entry<String, String[]> { private final String key; private ParameterEntry(String key) { this.key = key; } public String getKey() { return key; } public String[] getValue() { return getParameters().getStrings(key); } public String[] setValue(String[] value) { unsupportedOperation(); return null; } } }