public interface Filter {
//初始化方法,整个生命周期中只执行一次。
//在init方法成功(失败如抛异常等)执行完前,不能提供过滤服务。
//参数FilterConfig用于获取初始化参数
public void init(FilterConfig filterConfig) throws ServletException;
//执行过滤任务的方法,参数FilterChain表示过滤器链,doFilter方法中只有执行chain.doFilter()后才能调用下一个过滤器的doFilter方法
//才能将请求交经下一个Filter或Servlet执行
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException;
//销毁方法,当移出服务时由web容器调用。整个生命周期中destroy方法只会执行一次
//destroy方法可用于释放持有的资源,如内存、文件句柄等
public void destroy();
}
@Component
public class TimeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("time filter init");
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
System.out.println("time filter start");
long startTime = System.currentTimeMillis();
filterChain.doFilter(servletRequest, servletResponse);
long endTime = System.currentTimeMillis();
System.out.println("time filter consume " + (endTime - startTime) + " ms");
System.out.println("time filter end");
}
@Override
public void destroy() {
System.out.println("time filter init");
}
}
public class StandardContext extends ContainerBase
implements Context, NotificationEmitter {
private HashMap<String, FilterDef> filterDefs = new HashMap<>();
private HashMap<String, ApplicationFilterConfig> filterConfigs = new HashMap<>();
@Override
protected synchronized void startInternal() throws LifecycleException {
// 省略其他代码
if (ok) {
if (!filterStart()) {
log.error(sm.getString("standardContext.filterFail"));
ok = false;
}
}
}
public boolean filterStart() {
boolean ok = true;
synchronized (filterConfigs) {
filterConfigs.clear();
// 遍历filterDefs的map初始化Filter对象
for (Entry<String,FilterDef> entry : filterDefs.entrySet()) {
String name = entry.getKey();
try {
ApplicationFilterConfig filterConfig =
new ApplicationFilterConfig(this, entry.getValue());
filterConfigs.put(name, filterConfig);
} catch (Throwable t) {
ok = false;
}
}
}
return ok;
}
}
public class FilterDef implements Serializable {
private static final long serialVersionUID = 1L;
private static final StringManager sm = StringManager.getManager(Constants.PACKAGE_NAME);
private String description = null;
private String displayName = null;
private transient Filter filter = null;
private String filterClass = null;
private String filterName = null;
private String largeIcon = null;
private final Map<String, String> parameters = new HashMap<>();
private String smallIcon = null;
private String asyncSupported = null;
}
public final class ApplicationFilterConfig implements FilterConfig, Serializable {
private static final long serialVersionUID = 1L;
static final StringManager sm = StringManager.getManager(Constants.Package);
private static final List<String> emptyString = Collections.emptyList();
private final transient Context context;
private transient Filter filter = null;
private final FilterDef filterDef;
private transient InstanceManager instanceManager;
private ObjectName oname;
ApplicationFilterConfig(Context context, FilterDef filterDef)
throws ClassCastException, ClassNotFoundException, IllegalAccessException,
InstantiationException, ServletException, InvocationTargetException, NamingException,
IllegalArgumentException, NoSuchMethodException, SecurityException {
super();
this.context = context;
this.filterDef = filterDef;
if (filterDef.getFilter() == null) {
getFilter();
} else {
this.filter = filterDef.getFilter();
getInstanceManager().newInstance(filter);
initFilter();
}
}
Filter getFilter() throws ClassCastException, ClassNotFoundException, IllegalAccessException,
InstantiationException, ServletException, InvocationTargetException, NamingException,
IllegalArgumentException, NoSuchMethodException, SecurityException {
if (this.filter != null)
return (this.filter);
// 创建 并初始化 Filter 对象
String filterClass = filterDef.getFilterClass();
this.filter = (Filter) getInstanceManager().newInstance(filterClass);
initFilter();
return (this.filter);
}
private void initFilter() throws ServletException {
if (context instanceof StandardContext &&
context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
filter.init(this);
} finally {
String capturedlog = SystemLogHandler.stopCapture();
if (capturedlog != null && capturedlog.length() > 0) {
getServletContext().log(capturedlog);
}
}
} else {
filter.init(this);
}
registerJMX();
}
}
FilterDef 的来源需要如果是 web.xml 定义那么就从 webxml 中获取,如果是springboot 工程,就通过ApplicationContextFacade类型进行获取。
public class ContextConfig implements LifecycleListener {
private void configureContext(WebXml webxml) {
// 省略相关代码
for (FilterDef filter : webxml.getFilters().values()) {
if (filter.getAsyncSupported() == null) {
filter.setAsyncSupported("false");
}
context.addFilterDef(filter);
}
}
}
public class ApplicationContextFacade implements org.apache.catalina.servlet4preview.ServletContext {
@Override
public FilterRegistration.Dynamic addFilter(String filterName,
Filter filter) {
if (SecurityUtil.isPackageProtectionEnabled()) {
return (FilterRegistration.Dynamic) doPrivileged("addFilter",
new Class[]{String.class, Filter.class},
new Object[]{filterName, filter});
} else {
return context.addFilter(filterName, filter);
}
}
}
public class ApplicationContext implements org.apache.catalina.servlet4preview.ServletContext {
private FilterRegistration.Dynamic addFilter(String filterName,
String filterClass, Filter filter) throws IllegalStateException {
FilterDef filterDef = context.findFilterDef(filterName);
// context是StandardContext对象
if (filterDef == null) {
filterDef = new FilterDef();
filterDef.setFilterName(filterName);
context.addFilterDef(filterDef);
} else {
if (filterDef.getFilterName() != null &&
filterDef.getFilterClass() != null) {
return null;
}
}
if (filter == null) {
filterDef.setFilterClass(filterClass);
} else {
filterDef.setFilterClass(filter.getClass().getName());
filterDef.setFilter(filter);
}
return new ApplicationFilterRegistration(filterDef, context);
}
}

final class StandardWrapperValve
extends ValveBase {
@Override
public final void invoke(Request request, Response response)
throws IOException, ServletException {
// 省略相关代码
ApplicationFilterChain filterChain =
ApplicationFilterFactory.createFilterChain(request, wrapper, servlet);
try {
if ((servlet != null) && (filterChain != null)) {
if (context.getSwallowOutput()) {
try {
SystemLogHandler.startCapture();
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
filterChain.doFilter(request.getRequest(),
response.getResponse());
}
} finally {
}
} else {
if (request.isAsyncDispatching()) {
request.getAsyncContextInternal().doInternalDispatch();
} else {
filterChain.doFilter
(request.getRequest(), response.getResponse());
}
}
}
} catch (Throwable e) {
}
// Release the filter chain (if any) for this request
if (filterChain != null) {
filterChain.release();
}
}
}
public final class ApplicationFilterChain implements FilterChain {
public static final int INCREMENT = 10;
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private int pos = 0;
private int n = 0;
private Servlet servlet = null;
private boolean servletSupportsAsync = false;
private static final StringManager sm = StringManager.getManager(Constants.Package);
void addFilter(ApplicationFilterConfig filterConfig) {
for(ApplicationFilterConfig filter:filters)
if(filter==filterConfig)
return;
if (n == filters.length) {
ApplicationFilterConfig[] newFilters =
new ApplicationFilterConfig[n + INCREMENT];
System.arraycopy(filters, 0, newFilters, 0, n);
filters = newFilters;
}
filters[n++] = filterConfig;
}
}
public final class ApplicationFilterFactory {
public static ApplicationFilterChain createFilterChain(ServletRequest request,
Wrapper wrapper, Servlet servlet) {
ApplicationFilterChain filterChain = null;
if (request instanceof Request) {
Request req = (Request) request;
if (Globals.IS_SECURITY_ENABLED) {
filterChain = new ApplicationFilterChain();
} else {
filterChain = (ApplicationFilterChain) req.getFilterChain();
if (filterChain == null) {
filterChain = new ApplicationFilterChain();
req.setFilterChain(filterChain);
}
}
} else {
filterChain = new ApplicationFilterChain();
}
filterChain.setServlet(servlet);
filterChain.setServletSupportsAsync(wrapper.isAsyncSupported());
// 通过StandardContext#findFilterMaps获取所有的Filter对象
StandardContext context = (StandardContext) wrapper.getParent();
FilterMap filterMaps[] = context.findFilterMaps();
if ((filterMaps == null) || (filterMaps.length == 0))
return (filterChain);
DispatcherType dispatcher =
(DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
String requestPath = null;
Object attribute = request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
if (attribute != null){
requestPath = attribute.toString();
}
String servletName = wrapper.getName();
// 匹配路径 Add the relevant path-mapped filters to this filter chain
for (int i = 0; i < filterMaps.length; i++) {
if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
continue;
}
if (!matchFiltersURL(filterMaps[i], requestPath))
continue;
// 通过StandardContext#findFilterConfig获取Filter对象
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
context.findFilterConfig(filterMaps[i].getFilterName());
if (filterConfig == null) {
continue;
}
filterChain.addFilter(filterConfig);
}
// 匹配servlet的名字 Add filters that match on servlet name second
for (int i = 0; i < filterMaps.length; i++) {
if (!matchDispatcher(filterMaps[i] ,dispatcher)) {
continue;
}
if (!matchFiltersServlet(filterMaps[i], servletName))
continue;
ApplicationFilterConfig filterConfig = (ApplicationFilterConfig)
context.findFilterConfig(filterMaps[i].getFilterName());
if (filterConfig == null) {
// FIXME - log configuration problem
continue;
}
filterChain.addFilter(filterConfig);
}
// Return the completed filter chain
return filterChain;
}
}
public final class ApplicationFilterChain implements FilterChain {
public static final int INCREMENT = 10;
private ApplicationFilterConfig[] filters = new ApplicationFilterConfig[0];
private int pos = 0;
private int n = 0;
private Servlet servlet = null;
private boolean servletSupportsAsync = false;
private static final StringManager sm = StringManager.getManager(Constants.Package);
@Override
public void doFilter(ServletRequest request, ServletResponse response)
throws IOException, ServletException {
if( Globals.IS_SECURITY_ENABLED ) {
// 省略相关代码
} else {
internalDoFilter(request,response);
}
}
private void internalDoFilter(ServletRequest request,
ServletResponse response)
throws IOException, ServletException {
if (pos < n) {
ApplicationFilterConfig filterConfig = filters[pos++];
try {
Filter filter = filterConfig.getFilter();
if( Globals.IS_SECURITY_ENABLED ) {
// 省略相关代码
} else {
filter.doFilter(request, response, this);
}
} catch (IOException | ServletException | RuntimeException e) {
} catch (Throwable e) {
}
return;
}
try {
if ((request instanceof HttpServletRequest) &&
(response instanceof HttpServletResponse) &&
Globals.IS_SECURITY_ENABLED ) {
// 省略相关代码
} else {
servlet.service(request, response);
}
} catch (IOException | ServletException | RuntimeException e) {
} catch (Throwable e) {
} finally {
}
}
}
/**
* 来看下这个类的官方解释:
* Web应用程序的过滤器映射的表示形式,如部署描述符中<filter-mapping>元素中的所示
* 每个过滤器映射都必须包含过滤器名称以及URL模式或servlet名称
* 例如以下配置:
* <filter-mapping>
* <filter-name>MyFilter</filter-name>
* <url-pattern>/my</url-pattern>
* </filter-mapping>
*
* 说白了,这个FilterMap就是封装了配置信息中<filter-mapping>标签中的元素
* 其中还包含了两个重点属性:过滤器名、过滤器对应过滤的url
*/
public class FilterMap extends XmlEncodingBase implements Serializable {
private boolean matchAllUrlPatterns = false;
private boolean matchAllServletNames = false;
// serverlet的名字,对应多个
private String[] servletNames = new String[0];
// 过滤器名,对应的是<filter-name>中的内容
private String filterName = null;
// 过滤url,对应的是<url-pattern>中的内容(可配置多个<filter-mapping>匹配不同的url,因此是数组形式)
private String[] urlPatterns = new String[0];
}
public class ContextConfig implements LifecycleListener {
private void configureContext(WebXml webxml) {
// 省略相关代码
for (FilterMap filterMap : webxml.getFilterMappings()) {
context.addFilterMap(filterMap);
}
}
}
public class ApplicationFilterRegistration
implements FilterRegistration.Dynamic {
private static final StringManager sm =
StringManager.getManager(Constants.Package);
private final FilterDef filterDef;
private final Context context;
public ApplicationFilterRegistration(FilterDef filterDef,
Context context) {
this.filterDef = filterDef;
this.context = context;
}
@Override
public void addMappingForServletNames(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... servletNames) {
FilterMap filterMap = new FilterMap();
filterMap.setFilterName(filterDef.getFilterName());
if (dispatcherTypes != null) {
for (DispatcherType dispatcherType : dispatcherTypes) {
filterMap.setDispatcher(dispatcherType.name());
}
}
if (servletNames != null) {
for (String servletName : servletNames) {
filterMap.addServletName(servletName);
}
if (isMatchAfter) {
context.addFilterMap(filterMap);
} else {
context.addFilterMapBefore(filterMap);
}
}
}
@Override
public void addMappingForUrlPatterns(
EnumSet<DispatcherType> dispatcherTypes, boolean isMatchAfter,
String... urlPatterns) {
FilterMap filterMap = new FilterMap();
filterMap.setFilterName(filterDef.getFilterName());
if (dispatcherTypes != null) {
for (DispatcherType dispatcherType : dispatcherTypes) {
filterMap.setDispatcher(dispatcherType.name());
}
}
if (urlPatterns != null) {
for (String urlPattern : urlPatterns) {
filterMap.addURLPattern(urlPattern);
}
if (isMatchAfter) {
context.addFilterMap(filterMap);
} else {
context.addFilterMapBefore(filterMap);
}
}
}
}

我有一个字符串input="maybe(thisis|thatwas)some((nice|ugly)(day|night)|(strange(weather|time)))"Ruby中解析该字符串的最佳方法是什么?我的意思是脚本应该能够像这样构建句子:maybethisissomeuglynightmaybethatwassomenicenightmaybethiswassomestrangetime等等,你明白了......我应该一个字符一个字符地读取字符串并构建一个带有堆栈的状态机来存储括号值以供以后计算,还是有更好的方法?也许为此目的准备了一个开箱即用的库?
我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i
我正在使用ruby1.9解析以下带有MacRoman字符的csv文件#encoding:ISO-8859-1#csv_parse.csvName,main-dialogue"Marceu","Giveittohimóhe,hiswife."我做了以下解析。require'csv'input_string=File.read("../csv_parse.rb").force_encoding("ISO-8859-1").encode("UTF-8")#=>"Name,main-dialogue\r\n\"Marceu\",\"Giveittohim\x97he,hiswife.\"\
简而言之错误:NOTE:Gem::SourceIndex#add_specisdeprecated,useSpecification.add_spec.Itwillberemovedonorafter2011-11-01.Gem::SourceIndex#add_speccalledfrom/opt/local/lib/ruby/site_ruby/1.8/rubygems/source_index.rb:91./opt/local/lib/ruby/gems/1.8/gems/rails-2.3.8/lib/rails/gem_dependency.rb:275:in`==':und
深度学习部署:Windows安装pycocotools报错解决方法1.pycocotools库的简介2.pycocotools安装的坑3.解决办法更多Ai资讯:公主号AiCharm本系列是作者在跑一些深度学习实例时,遇到的各种各样的问题及解决办法,希望能够帮助到大家。ERROR:Commanderroredoutwithexitstatus1:'D:\Anaconda3\python.exe'-u-c'importsys,setuptools,tokenize;sys.argv[0]='"'"'C:\\Users\\46653\\AppData\\Local\\Temp\\pip-instal
我正在使用ruby2.1.0我有一个json文件。例如:test.json{"item":[{"apple":1},{"banana":2}]}用YAML.load加载这个文件安全吗?YAML.load(File.read('test.json'))我正在尝试加载一个json或yaml格式的文件。 最佳答案 YAML可以加载JSONYAML.load('{"something":"test","other":4}')=>{"something"=>"test","other"=>4}JSON将无法加载YAML。JSON.load("
我想用Nokogiri解析HTML页面。页面的一部分有一个表,它没有使用任何特定的ID。是否可以提取如下内容:Today,3,455,34Today,1,1300,3664Today,10,100000,3444,Yesterday,3454,5656,3Yesterday,3545,1000,10Yesterday,3411,36223,15来自这个HTML:TodayYesterdayQntySizeLengthLengthSizeQnty345534345456563113003664354510001010100000344434113622315
我使用的第一个解析器生成器是Parse::RecDescent,它的指南/教程很棒,但它最有用的功能是它的调试工具,特别是tracing功能(通过将$RD_TRACE设置为1来激活)。我正在寻找可以帮助您调试其规则的解析器生成器。问题是,它必须用python或ruby编写,并且具有详细模式/跟踪模式或非常有用的调试技术。有人知道这样的解析器生成器吗?编辑:当我说调试时,我并不是指调试python或ruby。我指的是调试解析器生成器,查看它在每一步都在做什么,查看它正在读取的每个字符,它试图匹配的规则。希望你明白这一点。赏金编辑:要赢得赏金,请展示一个解析器生成器框架,并说明它的
我有这样的HTML代码:Label1Value1Label2Value2...我的代码不起作用。doc.css("first").eachdo|item|label=item.css("dt")value=item.css("dd")end显示所有首先标记,然后标记标签,我需要“标签:值” 最佳答案 首先,您的HTML应该有和中的元素:Label1Value1Label2Value2...但这不会改变您解析它的方式。你想找到s并遍历它们,然后在每个你可以使用next_element得到;像这样:doc=Nokogiri::HTML(
我想禁用HTTP参数的自动XML解析。但我发现命令仅适用于Rails2.x,它们都不适用于3.0:config.action_controller.param_parsers.deleteMime::XML(application.rb)ActionController::Base.param_parsers.deleteMime::XMLRails3.0中的等价物是什么? 最佳答案 根据CVE-2013-0156的最新安全公告你可以将它用于Rails3.0。3.1和3.2ActionDispatch::ParamsParser::