commit
					f15dcb5fc1
				
				 9 changed files with 466 additions and 0 deletions
			
			
		| @ -0,0 +1,40 @@ | |||||||
|  | target/ | ||||||
|  | !.mvn/wrapper/maven-wrapper.jar | ||||||
|  | !**/src/main/**/target/ | ||||||
|  | !**/src/test/**/target/ | ||||||
|  | 
 | ||||||
|  | ### IntelliJ IDEA ### | ||||||
|  | .idea/modules.xml | ||||||
|  | .idea/jarRepositories.xml | ||||||
|  | .idea/compiler.xml | ||||||
|  | .idea/libraries/ | ||||||
|  | *.iws | ||||||
|  | *.iml | ||||||
|  | *.ipr | ||||||
|  | 
 | ||||||
|  | ### Eclipse ### | ||||||
|  | .apt_generated | ||||||
|  | .classpath | ||||||
|  | .factorypath | ||||||
|  | .project | ||||||
|  | .settings | ||||||
|  | .springBeans | ||||||
|  | .sts4-cache | ||||||
|  | 
 | ||||||
|  | ### NetBeans ### | ||||||
|  | /nbproject/private/ | ||||||
|  | /nbbuild/ | ||||||
|  | /dist/ | ||||||
|  | /nbdist/ | ||||||
|  | /.nb-gradle/ | ||||||
|  | build/ | ||||||
|  | !**/src/main/**/build/ | ||||||
|  | !**/src/test/**/build/ | ||||||
|  | 
 | ||||||
|  | ### VS Code ### | ||||||
|  | .vscode/ | ||||||
|  | 
 | ||||||
|  | ### Mac OS ### | ||||||
|  | .DS_Store | ||||||
|  | logs | ||||||
|  | .idea | ||||||
| @ -0,0 +1,72 @@ | |||||||
|  | <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||||
|  |   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||||||
|  |   <modelVersion>4.0.0</modelVersion> | ||||||
|  | 
 | ||||||
|  |   <groupId>com.zsw</groupId> | ||||||
|  |   <artifactId>netty01</artifactId> | ||||||
|  |   <version>1.0-SNAPSHOT</version> | ||||||
|  |   <packaging>jar</packaging> | ||||||
|  | 
 | ||||||
|  |   <name>netty01</name> | ||||||
|  |   <url>http://maven.apache.org</url> | ||||||
|  | 
 | ||||||
|  |   <properties> | ||||||
|  |     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||||
|  |     <maven.compiler.source>1.8</maven.compiler.source> | ||||||
|  |     <maven.compiler.target>1.8</maven.compiler.target> | ||||||
|  |     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> | ||||||
|  |   </properties> | ||||||
|  | 
 | ||||||
|  |   <dependencies> | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>io.netty</groupId> | ||||||
|  |       <artifactId>netty-all</artifactId> | ||||||
|  |       <version>4.1.63.Final</version> | ||||||
|  |     </dependency> | ||||||
|  | 
 | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>org.springframework.boot</groupId> | ||||||
|  |       <artifactId>spring-boot-starter</artifactId> | ||||||
|  |       <version>2.7.10</version> | ||||||
|  |       <scope>compile</scope> | ||||||
|  |     </dependency> | ||||||
|  | 
 | ||||||
|  |     <!-- https://mvnrepository.com/artifact/com.google.guava/guava --> | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>com.google.guava</groupId> | ||||||
|  |       <artifactId>guava</artifactId> | ||||||
|  |       <version>31.1-jre</version> | ||||||
|  |     </dependency> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>org.projectlombok</groupId> | ||||||
|  |       <artifactId>lombok</artifactId> | ||||||
|  |       <optional>true</optional> | ||||||
|  |       <version>1.18.28</version> | ||||||
|  |     </dependency> | ||||||
|  | 
 | ||||||
|  |     <!-- https://mvnrepository.com/artifact/cn.hutool/hutool-all --> | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>cn.hutool</groupId> | ||||||
|  |       <artifactId>hutool-all</artifactId> | ||||||
|  |       <version>5.8.16</version> | ||||||
|  |     </dependency> | ||||||
|  | 
 | ||||||
|  |     <!-- https://mvnrepository.com/artifact/com.google.code.gson/gson --> | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>com.google.code.gson</groupId> | ||||||
|  |       <artifactId>gson</artifactId> | ||||||
|  |       <version>2.9.0</version> | ||||||
|  |     </dependency> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     <dependency> | ||||||
|  |       <groupId>junit</groupId> | ||||||
|  |       <artifactId>junit</artifactId> | ||||||
|  |       <version>3.8.1</version> | ||||||
|  |       <scope>test</scope> | ||||||
|  |     </dependency> | ||||||
|  |   </dependencies> | ||||||
|  | 
 | ||||||
|  | </project> | ||||||
| @ -0,0 +1,24 @@ | |||||||
|  | package com.zsw; | ||||||
|  | 
 | ||||||
|  | import com.zsw.starter.Client; | ||||||
|  | import com.zsw.starter.Server; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Hello world! | ||||||
|  |  * | ||||||
|  |  */ | ||||||
|  | @Slf4j | ||||||
|  | public class App  | ||||||
|  | { | ||||||
|  |     public static void main( String[] args ) | ||||||
|  |     { | ||||||
|  |         log.info("hello,world. {}",1); | ||||||
|  |         System.out.println( "Hello World!" ); | ||||||
|  |         Server server = new Server(); | ||||||
|  |         server.run(); | ||||||
|  | 
 | ||||||
|  |         Client client = new Client(); | ||||||
|  |         client.run(); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,64 @@ | |||||||
|  | package com.zsw.starter; | ||||||
|  | 
 | ||||||
|  | import cn.hutool.core.thread.ThreadUtil; | ||||||
|  | import com.zsw.starter.handler.ClientHandler; | ||||||
|  | import io.netty.bootstrap.Bootstrap; | ||||||
|  | import io.netty.channel.ChannelFuture; | ||||||
|  | import io.netty.channel.ChannelInitializer; | ||||||
|  | import io.netty.channel.ChannelOption; | ||||||
|  | import io.netty.channel.nio.NioEventLoopGroup; | ||||||
|  | import io.netty.channel.socket.SocketChannel; | ||||||
|  | import io.netty.channel.socket.nio.NioSocketChannel; | ||||||
|  | import io.netty.handler.codec.json.JsonObjectDecoder; | ||||||
|  | import io.netty.handler.codec.string.StringEncoder; | ||||||
|  | import io.netty.handler.timeout.IdleStateHandler; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | 
 | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | 
 | ||||||
|  | @Slf4j | ||||||
|  | public class Client { | ||||||
|  | 
 | ||||||
|  |     private void start(int i) throws InterruptedException { | ||||||
|  |         NioEventLoopGroup group = new NioEventLoopGroup(); | ||||||
|  |         Bootstrap bootstrap = new Bootstrap(); | ||||||
|  |         bootstrap.group(group) | ||||||
|  |                 .channel(NioSocketChannel.class) | ||||||
|  |                 .option(ChannelOption.TCP_NODELAY, true) | ||||||
|  |                 .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, 3000) | ||||||
|  |                 .handler(new ChannelInitializer<SocketChannel>() { | ||||||
|  |                     protected void initChannel(SocketChannel ch) { | ||||||
|  |                         // 注册名称
 | ||||||
|  |                         ch.pipeline().addLast("idleStateHandler", new IdleStateHandler(60, 60, 60, TimeUnit.SECONDS)); | ||||||
|  |                         ch.pipeline().addLast(new JsonObjectDecoder()); | ||||||
|  |                         ch.pipeline().addLast(new StringEncoder()); | ||||||
|  |                         ch.pipeline().addLast(new ClientHandler(i)); | ||||||
|  |                     } | ||||||
|  |                 }); | ||||||
|  |         ChannelFuture channelFuture = bootstrap.connect("127.0.0.1", 8899); | ||||||
|  |         channelFuture.sync(); | ||||||
|  |         channelFuture.channel().closeFuture().sync(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void run(){ | ||||||
|  |         for (int i = 0; i < 10; i++) { | ||||||
|  |             // try {
 | ||||||
|  |             //     Thread.sleep(200);
 | ||||||
|  |             // } catch (InterruptedException e) {
 | ||||||
|  |             //     throw new RuntimeException(e);
 | ||||||
|  |             // }
 | ||||||
|  |             int finalI = i; | ||||||
|  |             ThreadUtil.execAsync(()->{ | ||||||
|  |                 log.info("client:{} ready", finalI); | ||||||
|  |                 try { | ||||||
|  |                     this.start(finalI); | ||||||
|  |                 } catch (InterruptedException e) { | ||||||
|  |                     throw new RuntimeException(e); | ||||||
|  |                 } | ||||||
|  |             }); | ||||||
|  | 
 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,54 @@ | |||||||
|  | package com.zsw.starter; | ||||||
|  | 
 | ||||||
|  | import com.zsw.starter.handler.ServerHandler; | ||||||
|  | import io.netty.bootstrap.ServerBootstrap; | ||||||
|  | import io.netty.channel.ChannelFuture; | ||||||
|  | import io.netty.channel.ChannelInitializer; | ||||||
|  | import io.netty.channel.ChannelOption; | ||||||
|  | import io.netty.channel.ChannelPipeline; | ||||||
|  | import io.netty.channel.nio.NioEventLoopGroup; | ||||||
|  | import io.netty.channel.socket.SocketChannel; | ||||||
|  | import io.netty.channel.socket.nio.NioChannelOption; | ||||||
|  | import io.netty.channel.socket.nio.NioServerSocketChannel; | ||||||
|  | import io.netty.handler.codec.json.JsonObjectDecoder; | ||||||
|  | import io.netty.handler.codec.string.StringEncoder; | ||||||
|  | import io.netty.handler.timeout.IdleStateHandler; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | 
 | ||||||
|  | import java.util.concurrent.TimeUnit; | ||||||
|  | 
 | ||||||
|  | @Slf4j | ||||||
|  | public class Server { | ||||||
|  | 
 | ||||||
|  |     private void start() throws InterruptedException { | ||||||
|  |         NioEventLoopGroup bossGroup = new NioEventLoopGroup(1); | ||||||
|  |         //new 一个工作线程组
 | ||||||
|  |         NioEventLoopGroup workGroup = new NioEventLoopGroup(200); | ||||||
|  |         ServerBootstrap bootstrap = new ServerBootstrap() | ||||||
|  |                 .group(bossGroup, workGroup) | ||||||
|  |                 .channel(NioServerSocketChannel.class) | ||||||
|  |                 .childHandler(new ChannelInitializer<SocketChannel>() { | ||||||
|  |                     @Override | ||||||
|  |                     protected void initChannel(SocketChannel socketChannel) throws Exception { | ||||||
|  |                         ChannelPipeline pipline = socketChannel.pipeline(); | ||||||
|  |                         pipline.addLast("heart",new IdleStateHandler(5,5,10, TimeUnit.SECONDS)); | ||||||
|  |                         // pipline.addFirst(new JsonObjectDecoder());
 | ||||||
|  |                         pipline.addLast(new StringEncoder()); | ||||||
|  |                         pipline.addLast(new ServerHandler()); | ||||||
|  |                     } | ||||||
|  |                 }) | ||||||
|  |                 .localAddress(8899) | ||||||
|  |                 .option(ChannelOption.SO_BACKLOG, 1024) | ||||||
|  |                 .childOption(NioChannelOption.SO_KEEPALIVE, true); | ||||||
|  |         ChannelFuture future = bootstrap.bind().sync(); | ||||||
|  |         log.info("打印服务启动,端口:{} ",8899); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     public void run(){ | ||||||
|  |         try { | ||||||
|  |             this.start(); | ||||||
|  |         } catch (InterruptedException e) { | ||||||
|  |             throw new RuntimeException(e); | ||||||
|  |         } | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,33 @@ | |||||||
|  | package com.zsw.starter.handler; | ||||||
|  | 
 | ||||||
|  | import io.netty.buffer.ByteBuf; | ||||||
|  | import io.netty.channel.ChannelHandlerContext; | ||||||
|  | import io.netty.channel.SimpleChannelInboundHandler; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | 
 | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Slf4j | ||||||
|  | public class ClientHandler extends SimpleChannelInboundHandler<ByteBuf> { | ||||||
|  |     int i ; | ||||||
|  |     public ClientHandler(int i) { | ||||||
|  |         this.i = i; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { | ||||||
|  |         String channelId = channelHandlerContext.channel().id().toString(); | ||||||
|  |         byte[] bytes = new byte[byteBuf.readableBytes()]; | ||||||
|  |         byteBuf.getBytes(byteBuf.readerIndex(), bytes); | ||||||
|  |         String info = new String(bytes, StandardCharsets.UTF_8); | ||||||
|  |         log.info("info:{}",info); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     @Override | ||||||
|  |     public void channelActive(ChannelHandlerContext ctx) throws Exception { | ||||||
|  |         super.channelActive(ctx); | ||||||
|  |         log.info("客户端连接:{}",ctx.channel().id()); | ||||||
|  |         ctx.writeAndFlush("ctx-"+i); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @ -0,0 +1,62 @@ | |||||||
|  | package com.zsw.starter.handler; | ||||||
|  | 
 | ||||||
|  | import cn.hutool.core.util.StrUtil; | ||||||
|  | import io.netty.buffer.ByteBuf; | ||||||
|  | import io.netty.channel.ChannelHandlerContext; | ||||||
|  | import io.netty.channel.ChannelId; | ||||||
|  | import io.netty.channel.SimpleChannelInboundHandler; | ||||||
|  | import lombok.Synchronized; | ||||||
|  | import lombok.extern.slf4j.Slf4j; | ||||||
|  | 
 | ||||||
|  | import java.io.OutputStream; | ||||||
|  | import java.io.OutputStreamWriter; | ||||||
|  | import java.net.Socket; | ||||||
|  | import java.nio.charset.StandardCharsets; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @Slf4j | ||||||
|  | public class ServerHandler extends SimpleChannelInboundHandler<ByteBuf> { | ||||||
|  |     protected void channelRead0(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf) throws Exception { | ||||||
|  | 
 | ||||||
|  |         String channelId = channelHandlerContext.channel().id().toString(); | ||||||
|  |         byte[] bytes = new byte[byteBuf.readableBytes()]; | ||||||
|  |         byteBuf.getBytes(byteBuf.readerIndex(), bytes); | ||||||
|  |         String info = new String(bytes, StandardCharsets.UTF_8); | ||||||
|  |         log.info("channelHandlerContext:{}",channelHandlerContext.channel().id()); | ||||||
|  |         test(channelHandlerContext.channel().id()); | ||||||
|  | 
 | ||||||
|  |         // Thread.sleep(5000L);
 | ||||||
|  |         Socket socket = new Socket("192.168.10.188", 9100); | ||||||
|  |         OutputStream socketOut = socket.getOutputStream(); | ||||||
|  |         OutputStreamWriter writer = new OutputStreamWriter(socketOut, "GBK"); | ||||||
|  |         socketOut.write(27); | ||||||
|  |         socketOut.write(27); | ||||||
|  |         String str = StrUtil.format("ctx:{},text:{}\n",channelHandlerContext.channel().id(),info); | ||||||
|  |         writer.write(str); | ||||||
|  |         writer.flush(); | ||||||
|  | 
 | ||||||
|  |         writer.write(27); | ||||||
|  |         writer.write(100); | ||||||
|  |         writer.write(4); | ||||||
|  |         writer.write(10); | ||||||
|  |         writer.flush(); | ||||||
|  | 
 | ||||||
|  |         writer.write(0x1D); | ||||||
|  |         writer.write("V"); | ||||||
|  |         writer.write(48); | ||||||
|  |         writer.write(0); | ||||||
|  |         writer.flush(); | ||||||
|  | 
 | ||||||
|  |         log.info("停止5秒后完成"); | ||||||
|  |         socket.close(); | ||||||
|  |         writer.close(); | ||||||
|  |         socketOut.close(); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     private synchronized  void test(ChannelId id){ | ||||||
|  |         log.info("测试同步开始...{}",id); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -0,0 +1,79 @@ | |||||||
|  | <?xml version="1.0" encoding="UTF-8"?> | ||||||
|  | <configuration debug="false" scan="false"> | ||||||
|  |     <property name="log.path" value="logs"/> | ||||||
|  | 
 | ||||||
|  | <!--    <!– 彩色日志格式 –>--> | ||||||
|  | <!--    <property name="CONSOLE_LOG_PATTERN"--> | ||||||
|  | <!--              value="%clr([${spring.application.name}:${server.port}:%X{tenant}:%X{userid}]) %clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(---){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/>--> | ||||||
|  | 
 | ||||||
|  | <!--    <!– 普通日志格式 –>--> | ||||||
|  | <!--    <property name="CONSOLE_LOG_PATTERN_NO_COLOR"--> | ||||||
|  | <!--              value="[${spring.application.name}:${server.port}:%X{tenant}:%X{userid}] %d{yyyy-MM-dd HH:mm:ss.SSS}[%5p] ${PID} [%X{trace}] [%t:%r] [%logger{50}.%M:%L] %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" />--> | ||||||
|  | 
 | ||||||
|  |     <property name="CONSOLE_LOG_PATTERN" | ||||||
|  |               value=" %clr(%d{yyyy-MM-dd HH:mm:ss:SSS}) %clr(){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}"/> | ||||||
|  | 
 | ||||||
|  |     <!-- 普通日志格式 --> | ||||||
|  |     <property name="CONSOLE_LOG_PATTERN_NO_COLOR" | ||||||
|  |               value=" %d{yyyy-MM-dd HH:mm:ss}[%5p]  [%X{trace}] [%t:%r] [%logger{50}.%M:%L] %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}" /> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  |     <!-- 彩色日志依赖的渲染类 --> | ||||||
|  |     <conversionRule conversionWord="clr" | ||||||
|  |                     converterClass="org.springframework.boot.logging.logback.ColorConverter"/> | ||||||
|  |     <conversionRule conversionWord="wex" | ||||||
|  |                     converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/> | ||||||
|  |     <conversionRule conversionWord="wEx" | ||||||
|  |                     converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/> | ||||||
|  | <!--    <conversionRule conversionWord="traceId" converterClass="com.zsw.pos.common.converter.ZswLogPrefixConverter"/>--> | ||||||
|  | 
 | ||||||
|  |     <!-- Console log output --> | ||||||
|  |     <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>${CONSOLE_LOG_PATTERN}</pattern> | ||||||
|  |         </encoder> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <!-- Log file info output --> | ||||||
|  |     <appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||||||
|  |         <file>${log.path}/info.log</file> | ||||||
|  |         <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||||||
|  |             <fileNamePattern>${log.path}/%d{yyyy-MM, aux}/info.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> | ||||||
|  |             <maxFileSize>50MB</maxFileSize> | ||||||
|  |             <maxHistory>30</maxHistory> | ||||||
|  |         </rollingPolicy> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>${CONSOLE_LOG_PATTERN_NO_COLOR}</pattern> | ||||||
|  |             <charset>UTF-8</charset> | ||||||
|  |         </encoder> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <!-- Log file error output --> | ||||||
|  |     <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender"> | ||||||
|  |         <file>${log.path}/error.log</file> | ||||||
|  |         <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy"> | ||||||
|  |             <fileNamePattern>${log.path}/%d{yyyy-MM}/error.%d{yyyy-MM-dd}.%i.log.gz</fileNamePattern> | ||||||
|  |             <maxFileSize>50MB</maxFileSize> | ||||||
|  |             <maxHistory>30</maxHistory> | ||||||
|  |         </rollingPolicy> | ||||||
|  |         <encoder> | ||||||
|  |             <pattern>${CONSOLE_LOG_PATTERN_NO_COLOR}</pattern> | ||||||
|  |             <charset>UTF-8</charset> | ||||||
|  |         </encoder> | ||||||
|  |         <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> | ||||||
|  |             <level>ERROR</level> | ||||||
|  |         </filter> | ||||||
|  |     </appender> | ||||||
|  | 
 | ||||||
|  |     <!-- Level: FATAL 0  ERROR 3  WARN 4  INFO 6  DEBUG 7 --> | ||||||
|  |     <root level="INFO"> | ||||||
|  |         <appender-ref ref="console"/> | ||||||
|  |         <appender-ref ref="error"/> | ||||||
|  |         <appender-ref ref="info"/> | ||||||
|  |     </root> | ||||||
|  | 
 | ||||||
|  |     <!-- 服务日志 --> | ||||||
|  |     <logger name="root" level="info" /> | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | </configuration> | ||||||
| @ -0,0 +1,38 @@ | |||||||
|  | package com.zsw; | ||||||
|  | 
 | ||||||
|  | import junit.framework.Test; | ||||||
|  | import junit.framework.TestCase; | ||||||
|  | import junit.framework.TestSuite; | ||||||
|  | 
 | ||||||
|  | /** | ||||||
|  |  * Unit test for simple App. | ||||||
|  |  */ | ||||||
|  | public class AppTest  | ||||||
|  |     extends TestCase | ||||||
|  | { | ||||||
|  |     /** | ||||||
|  |      * Create the test case | ||||||
|  |      * | ||||||
|  |      * @param testName name of the test case | ||||||
|  |      */ | ||||||
|  |     public AppTest( String testName ) | ||||||
|  |     { | ||||||
|  |         super( testName ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * @return the suite of tests being tested | ||||||
|  |      */ | ||||||
|  |     public static Test suite() | ||||||
|  |     { | ||||||
|  |         return new TestSuite( AppTest.class ); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     /** | ||||||
|  |      * Rigourous Test :-) | ||||||
|  |      */ | ||||||
|  |     public void testApp() | ||||||
|  |     { | ||||||
|  |         assertTrue( true ); | ||||||
|  |     } | ||||||
|  | } | ||||||
					Loading…
					
					
				
		Reference in new issue