本文将带您了解关于Spring-Test-MVC/MockServletContext-内容在测试中为空,但可在Tomcat上运行的新内容,同时我们还将为您解释springmvc测试类的相关知识,另外
本文将带您了解关于Spring-Test-MVC / MockServletContext-内容在测试中为空,但可在Tomcat上运行的新内容,同时我们还将为您解释springmvc测试类的相关知识,另外,我们还将为您提供关于ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载、Failed to instantiate [org.springframework.test.context.web.ServletTestExecute、FAQ(7):IOException parsing XML document from ServletContext resource [/calsspath:springmvc.xml];、org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer的实例源码的实用信息。
本文目录一览:- Spring-Test-MVC / MockServletContext-内容在测试中为空,但可在Tomcat上运行(springmvc测试类)
- ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载
- Failed to instantiate [org.springframework.test.context.web.ServletTestExecute
- FAQ(7):IOException parsing XML document from ServletContext resource [/calsspath:springmvc.xml];
- org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer的实例源码
Spring-Test-MVC / MockServletContext-内容在测试中为空,但可在Tomcat上运行(springmvc测试类)
我们正在尝试为我们的Spring-MVC Web应用程序设置Spring-Test-
MVC。我们开始使用freemarker,一切都很好。但是,我们决定反对它,现在正尝试使用JSP进行设置。当测试应用程序部署在Tomcat上时,它就可以正常工作。当我们运行简单的测试时:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(loader = WebContextLoader.class, locations = { "file:src/main/webapp/WEB-INF/servlet-context.xml" })public class SkelletonTest { @Inject private MockMvc mockMvc; @Test public void homeTest() throws Exception { mockMvc.perform(get("/")).andExpect(status().isOk()) .andExpect(content().type("text/html;charset=ISO-8859-1")) .andExpect(content().string(containsString("Hello World!"))); }
它说:content type not set
或如果将其删除,则内容将为空。但是,控制器将被调用,因此映射必须起作用。
因此,这强烈暗示我们的测试未呈现该视图,但是我不知道可能缺少什么设置。
这是我们的servlet-context.xml:
<context:component-scan base-package="package.to.controllers" /><mvc:annotation-driven /><bean id="viewResolver"> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" /> <property name="exposeContextBeansAsAttributes" value="true" /> <property name="prefix" value="/views/" /> <property name="suffix" value=".jsp" /></bean>
WebContextLoader:
public class WebContextLoader extends GenericWebContextLoader { public WebContextLoader() { super("src/main/webapp", false); }}
GenericWebContextLoader是spring-
test-mvc的原始版本。
MockMvc像这样设置为Bean:
@Configurationpublic class TestConfig { @Inject private WebApplicationContext wac; @Bean public MockMvc create(){ return (MockMvcBuilders.webApplicationContextSetup(this.wac).build()); }}
这就是设置。测试框架未使用web.xml,因为它之前已经在工作,所以无关紧要。
我认为servlet上下文中必须有其他设置。我检查了它的负载,但是对于Tomcat部署的应用来说,它很重要,但是我为它设置的前缀和后缀将被测试忽略。
不知道错误跟踪将有多大帮助,但是这里是:
java.lang.AssertionError: Content type not set at org.springframework.test.web.AssertionErrors.fail(AssertionErrors.java:35) at org.springframework.test.web.AssertionErrors.assertTrue(AssertionErrors.java:57) at org.springframework.test.web.server.result.ContentResultMatchers$1.match(ContentResultMatchers.java:59) at org.springframework.test.web.server.MockMvc$1.andExpect(MockMvc.java:84) at our.package.SkelletonTest.homeTest(SkelletonTest.java:30) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:601) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:42) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20) at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:74) at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:83) at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:72) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:231) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:47) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:231) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:60) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:229) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:50) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:222) at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:71) at org.junit.runners.ParentRunner.run(ParentRunner.java:300) at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:174) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
并测试输出:
2012-06-15 10:41:04 TestContextManager [INFO] @TestExecutionListeners is not present for class [class package.to.test.SkelletonTest]: using defaults.2012-06-15 10:41:05 XmlBeanDefinitionReader [INFO] Loading XML bean definitions from URL [file:src/main/webapp/WEB-INF/servlet-context.xml]2012-06-15 10:41:05 ClassPathBeanDefinitionScanner [INFO] JSR-330 ''javax.inject.Named'' annotation found and supported for component scanning2012-06-15 10:41:05 GenericWebApplicationContext [INFO] Refreshing org.springframework.web.context.support.GenericWebApplicationContext@158539f: startup date [Fri Jun 15 10:41:05 CEST 2012]; root of context hierarchy2012-06-15 10:41:05 AutowiredAnnotationBeanPostProcessor [INFO] JSR-330 ''javax.inject.Inject'' annotation found and supported for autowiring2012-06-15 10:41:05 DefaultListableBeanFactory [INFO] Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@c64bc2: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,testConfig,freemarkerController,homeController,tableService,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,viewResolver,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,create]; root of factory hierarchy2012-06-15 10:41:05 RequestMappingHandlerMapping [INFO] Mapped "{[/],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public org.springframework.web.servlet.ModelAndView package.to.controller.HomeController.index()2012-06-15 10:41:05 RequestMappingHandlerMapping [INFO] Mapped "{[/test],methods=[],params=[],headers=[],consumes=[],produces=[],custom=[]}" onto public java.lang.String package.to.controller.HomeController.test(org.springframework.ui.Model)2012-06-15 10:41:06 GenericWebContextLoader$1 [INFO] Initializing Spring FrameworkServlet ''''2012-06-15 10:41:06 TestDispatcherServlet [INFO] FrameworkServlet '''': initialization started2012-06-15 10:41:06 TestDispatcherServlet [INFO] FrameworkServlet '''': initialization completed in 32 ms2012-06-15 10:41:06 GenericWebApplicationContext [INFO] Closing org.springframework.web.context.support.GenericWebApplicationContext@158539f: startup date [Fri Jun 15 10:41:05 CEST 2012]; root of context hierarchy2012-06-15 10:41:06 DefaultListableBeanFactory [INFO] Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@c64bc2: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,testConfig,freemarkerController,homeController,tableService,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping#0,org.springframework.format.support.FormattingConversionServiceFactoryBean#0,org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter#0,org.springframework.web.servlet.handler.MappedInterceptor#0,org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver#0,org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver#0,org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver#0,org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,viewResolver,org.springframework.context.annotation.ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor#0,create]; root of factory hierarchy
因此,感谢您提供任何有助于我找出问题的建议!
顺便说一句:不想再这样了,所以我跳过了pom。我们正在使用Spring 3.1,spring-test-mvc 1.0.0..BUILD-
SNAPSHOT,jsp-ap 2.2,jstl 1.2,…如果您需要了解更多信息,我会尝试将其上传到某个地方…
编辑
如果您需要更多信息,或者为什么无法回答我的问题,请告诉我。真的需要弄清楚,我不知道从哪里开始。因此,也欢迎任何想法或评论。
编辑2
使用了以下输出的打印方法:
MockHttpServletRequest: HTTP Method = GET Request URI = / Parameters = {} Headers = {} Handler: Type = package.to.controller.HomeController Method = public org.springframework.web.servlet.ModelAndView package.to.controller.HomeController.index() Resolved Exception: Type = null ModelAndView: View name = index View = null Attribute = welcome value = Hello World! FlashMap:MockHttpServletResponse: Status = 200 Error message = null Headers = {} Content type = null Body = Forwarded URL = /views/index.jsp Redirected URL = null Cookies = []
哪个更好地显示了问题,但没有解决方案…
编辑3
刚刚发现以下内容:
JSP需要一个servlet容器。因此,看来我无法以这种方式测试我的页面…如果任何人有解决此问题的想法,请告诉我。
答案1
小编典典添加到您的edit3中,本质上是为了JSP渲染,最后一次调用是
RequestDispatcher requestDispatcher = httpRequest.getRequestDispacher(jspPath)requestDispatcher.forward(httpRequest,httpResponse)
并且RequestDispatcher
实现是由容器提供的(因为它取决于需要如何编译jsp,在何处放置已编译的jsp等)。RequestDispatcher的Mock实现只是捕获转发的JSP页面,并且您
只能验证到JSP的路径就是您期望的路径。
ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载
ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载内容的区别
一:ContextLoaderListener 加载内容
二:DispatcherServlt 加载内容
ContextLoaderListener 和 DispatcherServlet 都会在 Web 容器启动的时候加载一下 bean 配置。区别在于:
DispatcherServlet 一般会加载 MVC 相关的 bean 配置管理 (如: ViewResolver, Controller, MultipartResolver, ExceptionHandler, etc.)
ContextLoaderListener 一般会加载整个 Spring 容器相关的 bean 配置管理 (如: Log, Service, Dao, PropertiesLoader, etc.)
DispatcherServlet 默认使用 WebApplicationContext 作为上下文.
值得注意的是,DispatcherServlet 的上下文仅仅是 Spring MVC 的上下文,而 ContextLoaderListener 的上下文则对整个 Spring 都有效。一般 Spring web 项目中同时会使用这两种上下文.
Failed to instantiate [org.springframework.test.context.web.ServletTestExecute
有时候 启动springBoot 会报错,test时有时也是,
类似 Failed to instantiate [org.springframework.test.context.web.ServletTestExecute,
java.lang.NoClassDefFoundError: javax/servlet/ServletContext
这样的错误,
我遇到这个问题的原因,是因为引用的 依赖版本不正确,
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
<scope>test</scope>
</dependency>
原来引用的是 3.XXX 的版本,改为以上版本就可以了
FAQ(7):IOException parsing XML document from ServletContext resource [/calsspath:springmvc.xml];
又是一个粗心大意的恶果!!!

IOException parsing XML document from ServletContext resource [/calsspath:springmvc.xml]; nested exception is java.io.FileNotFoundException:
Could not open ServletContext resource [/calsspath:springmvc.xml]

无法打开ServletContext上下文资源:springmvc.xml
classpath单词写错!
真正有价值的还在后面,原以为修改便大吉大利,,但是依旧报错!而且还是同一个错误!!不科学。
于是我把内置浏览器的缓存清除,然后再次运行,发现原来错误消失。做个猜测:也许是xml配置文件此前已经加载了,因而修改过后要一段时间才能被软件检测修复,所以清理缓存不失为好方法。
org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer的实例源码
@Bean public EmbeddedServletContainerCustomizer cookieProcessorCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { if (container instanceof TomcatEmbeddedServletContainerFactory) { TomcatEmbeddedServletContainerFactory factory = (TomcatEmbeddedServletContainerFactory) container; factory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { context.setCookieProcessor(new LegacyCookieProcessor()); } }); } } }; }
@Test public void redirectContextRootCanBeConfigured() throws Exception { Map<String,String> map = new HashMap<String,String>(); map.put("server.tomcat.redirect-context-root","false"); bindProperties(map); ServerProperties.Tomcat tomcat = this.properties.getTomcat(); assertthat(tomcat.getRedirectContextRoot()).isEqualTo(false); TomcatEmbeddedServletContainerFactory container = new TomcatEmbeddedServletContainerFactory(); this.properties.customize(container); Context context = mock(Context.class); for (TomcatContextCustomizer customizer : container .getTomcatContextCustomizers()) { customizer.customize(context); } verify(context).setMapperContextRootRedirectEnabled(false); }
@Bean public EmbeddedServletContainerCustomizer customizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { TomcatEmbeddedServletContainerFactory tomcat = (TomcatEmbeddedServletContainerFactory) container; TomcatContextCustomizer contextCustomizer = new TomcatContextCustomizer() { @Override public void customize(Context context) { context.setCookieProcessor(new LegacyCookieProcessor()); } }; tomcat.addContextCustomizers(contextCustomizer); } }; }
@Bean public EmbeddedServletContainerFactory servletContainer() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); MockService config = MockService.getInstance(); factory.setPort(config.getPort()); factory.setSessionTimeout(10,TimeUnit.MINUTES); factory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { JarScanner jarScanner = new JarScanner() { @Override public void scan(ServletContext arg0,ClassLoader arg1,JarScannerCallback arg2,Set<String> arg3) { } }; context.setJarScanner(jarScanner); } }); return factory; }
@Bean public EmbeddedServletContainerCustomizer containerCustomizer() { if (highAvailability) { logger.info("Setting up high availability configuration"); return factory -> { logger.info("Customizing Tomcat container"); TomcatEmbeddedServletContainerFactory containerFactory = (TomcatEmbeddedServletContainerFactory) factory; TomcatContextCustomizer tomcatContextCustomizer = context -> { context.setSessionTimeout(30); context.setManager(new MemcachedBackupSessionManager() {{ setMemcachednodes(nodes); setFailoverNodes(failover); setRequestUriIgnorePattern(".*\\.(ico|png|gif|jpg|css|js)$"); }}); }; containerFactory.setTomcatContextCustomizers(Collections.singletonList(tomcatContextCustomizer)); setMimeMappings(factory); }; } else { logger.info("Skipping HA configuration"); return this::setMimeMappings; } }
public static void configure(TomcatEmbeddedServletContainerFactory tomcatFactory) { tomcatFactory.addContextCustomizers((TomcatContextCustomizer) context -> { boolean development = (System.getProperty("airsonic.development") != null); // Increase the size and time before eviction of the Tomcat // cache so that resources aren't uncompressed too often. // See https://github.com/jhipster/generator-jhipster/issues/3995 StandardRoot resources = new StandardRoot(); if (development) { resources.setCachingallowed(false); } else { resources.setCacheMaxSize(100000); resources.setCacheObjectMaxSize(4000); resources.setCacheTtl(24 * 3600 * 1000); // 1 day,in milliseconds } context.setResources(resources); // Put Jasper in production mode so that JSP aren't recompiled // on each request. // See http://stackoverflow.com/questions/29653326/spring-boot-application-slow-because-of-jsp-compilation Container jsp = context.findChild("jsp"); if (jsp instanceof Wrapper) { ((Wrapper) jsp).addInitParameter("development",Boolean.toString(development)); } }); }
private void customizeBackgroundProcessorDelay( TomcatEmbeddedServletContainerFactory factory) { factory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { context.setBackgroundProcessorDelay( Tomcat.this.backgroundProcessorDelay); } }); }
private void customizeRedirectContextRoot( TomcatEmbeddedServletContainerFactory factory,final boolean redirectContextRoot) { factory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { context.setMapperContextRootRedirectEnabled(redirectContextRoot); } }); }
@Override public void doCustomize(TomcatEmbeddedServletContainerFactory tomcatContainer) { tomcatContainer.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { addListener(context,findListenerType()); } }); }
@Bean public TomcatContextCustomizer tomcatContextCustomizer() { return new TomcatContextCustomizer() { @Override public void customize(Context context) { context.addApplicationListener("org.apache.tomcat.websocket.server.WsContextListener"); } }; }
private void customizeBackgroundProcessorDelay( TomcatEmbeddedServletContainerFactory factory) { factory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { context.setBackgroundProcessorDelay( Tomcat.this.backgroundProcessorDelay); } }); }
@Override public void doCustomize(TomcatEmbeddedServletContainerFactory tomcatContainer) { tomcatContainer.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { addListener(context,findListenerType()); } }); }
private void customizeBackgroundProcessorDelay( TomcatEmbeddedServletContainerFactory factory) { factory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { context.setBackgroundProcessorDelay( Tomcat.this.backgroundProcessorDelay); } }); }
@Override public void doCustomize(TomcatEmbeddedServletContainerFactory tomcatContainer) { tomcatContainer.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { addListener(context,findListenerType()); } }); }
@Bean public TomcatEmbeddedServletContainerFactory factory() { TomcatEmbeddedServletContainerFactory tomcatEmbeddedServletContainerFactory = new TomcatEmbeddedServletContainerFactory(); tomcatEmbeddedServletContainerFactory.addContextCustomizers((TomcatContextCustomizer) (Context context) -> { context.addServletContainerInitializer(new JasperInitializer(),Collections.<Class<?>> emptySet()); }); return tomcatEmbeddedServletContainerFactory; }
@Bean public EmbeddedServletContainerCustomizer servletContainerCustomizer() { return new EmbeddedServletContainerCustomizer() { @Override public void customize(ConfigurableEmbeddedServletContainer container) { if (container instanceof TomcatEmbeddedServletContainerFactory) { customizetomcat((TomcatEmbeddedServletContainerFactory)container); } } private void customizetomcat(TomcatEmbeddedServletContainerFactory tomcatFactory) { tomcatFactory.addContextCustomizers(new TomcatContextCustomizer() { @Override public void customize(Context context) { Container jsp = context.findChild("jsp"); if (jsp instanceof Wrapper) { ((Wrapper)jsp).addInitParameter("development","false"); } } }); } }; }
@Bean public TomcatEmbeddedServletContainerFactory tomcatContainerFactory() { TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory(); factory.setTomcatContextCustomizers( Arrays.asList(new TomcatContextCustomizer[] { tomcatContextCustomizer() })); return factory; }
@Bean public TomcatContextCustomizer tomcatContextCustomizer() { return new TomcatContextCustomizer() { @Override public void customize(Context context) { context.addServletContainerInitializer(new WsSci(),null); } }; }
@Bean public TomcatContextCustomizer tomcatContextCustomizer() { return new TomcatContextCustomizer() { @Override public void customize(Context context) { context.addServletContainerInitializer(new WsSci(),null); } }; }
我们今天的关于Spring-Test-MVC / MockServletContext-内容在测试中为空,但可在Tomcat上运行和springmvc测试类的分享就到这里,谢谢您的阅读,如果想了解更多关于ContextLoaderListener 和 Spring MVC 中的 DispatcherServlet 加载、Failed to instantiate [org.springframework.test.context.web.ServletTestExecute、FAQ(7):IOException parsing XML document from ServletContext resource [/calsspath:springmvc.xml];、org.springframework.boot.context.embedded.tomcat.TomcatContextCustomizer的实例源码的相关信息,可以在本站进行搜索。
本文标签: