1. java命令行的启动

首先是gradle build

其次是:java -Dabc.appid=1234 -classpath "a.jar:b.jar"  com.ctrip.oss.MainClass 1>"d:\test\logs\log.txt" 2>"d:\test\errors\errors.txt"

其中:
-D后面的是运行时的配置参数,可以在代码中通过 System.getProperty('abc.appid')的方式获得

-classpath是编译完成后生成的*.jar文件路径

com.ctrip.oss.MainClass是程序运行开始的主类

1>如果代码中存在sl4j 这个参数后面的路径文件将用来存放log log文件,包括info, warn, error 信息

2>如果代码中存在任何未经捕获的异常,log信息会写到errors.txt文件中

如何配置sl4j的环境。  以下依赖是必须的

compile 'org.slf4j:slf4j-api:1.7.5'
代码中使用logger:
Logger logger = LoggerFactory.getLogger(this.getClass());

2. Logback 的使用,logback用来记录本地log

logback是用来配置Log写在什么地方的,这里将Log写在本地:

首先需要引用logback的dependency:

 compile 'ch.qos.logback:logback-core:1.1.1'
compile 'ch.qos.logback:logback-classic:1.1.1'
compile 'ch.qos.logback:logback-access:1.1.1'

其次在resources目录下配置logback.xml.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_DIR" value="session-service/logs"/>
<property name="LOG_FILE_NAME" value="session-server.log"/>
<!-- Output to File and Rotate if it's necessary -->
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_DIR}/${LOG_FILE_NAME}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>${LOG_DIR}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}.%i</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
<maxHistory>10</maxHistory>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%date [%-5thread] %-5level [%-10logger] %-10msg%n</pattern>
</encoder>
<filter class="com.ctriposs.session.util.LogLevelFilter">
<level>WARN</level>
</filter>
</appender> <root level="INFO">
<appender-ref ref="ROLLING"/>
</root>
</configuration>

最后在代码中加载这个xml 并且配置运行时环境变量

      LoggerContext lc = (LoggerContext)LoggerFactory.getILoggerFactory();

         JoranConfigurator joranConfigurator=new JoranConfigurator();
joranConfigurator.setContext(lc);
lc.reset(); // Get the configuration xml file
String configurationFilePath=appName+"-logback.xml";
InputStream stream = logConfigurator.class.getResourceAsStream(configurationFilePath); // Configure the log context with the stream loaded
try {
joranConfigurator.doConfigure(stream);
} catch (JoranException e) {
e.printStackTrace();
}

配置运行时环境变量

通过以上配置:在此配置之前的log会写在>1 和>2两个命令行参数所指定的log地址,但是当使用了log back之后的logger将使用最新的log地址

注意:

XML中配置的log地址是可以动态配置的,即通过在java命令的配置参数中使用 -DXX的形式

log所在的路径即/opt/test/session-service/logs, 这里/opt/test/session-service为classpath的根,logs文件夹应该提前在工程中与main相同的路径下新建好

2. Configuration的配置和使用。

上面提到了使用在启动命令中使用 -Dxxx 的方式传递配置参数,也可以使用一些开源的属性配置器来做

添加引用:
compile 'com.netflix.archaius:archaius-core:0.6.0' 使用代码:
// 首先设置全局变量,这两个变量
System.setProperty("archaius.deployment.applicationId", "mysession-server");
System.setProperty("archaius.deployment.environment", "lpt");
//获取以上设置
String appId = ConfigurationManager.getDeploymentContext().getApplicationId();
String environmentName = ConfigurationManager.getDeploymentContext().getDeploymentEnvironment();
//加载properties文件
ConfigurationManager.loadCascadedPropertiesFromResources(appId);
String settingName=ConfigurationManager.getConfigInstance().getString("setting1");
String settingName2=ConfigurationManager.getConfigInstance().getString("setting2");

*另外archious还提供了动态配置文件的作用,参照https://github.com/Netflix/archaius

3。由于要加在到classpath中的jar包随着工程的复杂而增加,所以手动的拼写所有的依赖包变得不现实,使用sh脚本语言将大大简化我们的工作

sourcelocation='/opt/test/MainProject-1.0/'
loglocation='/opt/test/MainProject-1.0/logs'
java -classpath $(echo /opt/test/MainProject-1.0/lib/* | tr ' ' ':') com.ctrip.test.mainClass 1>$loglocation/log.txt 2>$loglocation/error.txt

4. Handler 的添加。

在项目开发过程中往往要将内部的一些部分作为API对外公开,在.NET中是通过配置handler进行的。Java中可以通过一些服务器组件来实现,比如jetty,前半部分是Jetty的后半部分是序列化器的

compile 'org.eclipse.jetty:jetty-server:8.1.0.RC5'
compile 'org.eclipse.jetty:jetty-servlet:8.1.0.RC5'
compile 'org.eclipse.jetty:jetty-servlets:8.1.0.RC4' compile 'com.fasterxml.jackson.core:jackson-core:2.3.3'
compile 'com.fasterxml.jackson.core:jackson-databind:2.3.3'
compile 'com.fasterxml.jackson.core:jackson-annotations:2.3.3' 新写一个Server类作为注册Handler的容器
public class ServerBoard {
private int _port;
private Server server;
private volatile boolean running=false;
public ServerBoard(int p)
{
_port=p;
server=new Server(_port); ServletContextHandler servletContextHandler = new ServletContextHandler();
servletContextHandler.setContextPath("/");
servletContextHandler.addServlet(ServeletA.class,"/api/env");
server.setHandler(servletContextHandler);
} public void Start(){
try {
if(!running) {
server.start();
running=true;
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void Stop(){
try {
if(running) {
server.stop();
running=false;
}
} catch (Exception e) {
e.printStackTrace();
}
}
}

Handdler容器

至于Servlet则很简单的

public class ServeletA extends HttpServlet {

    private ObjectMapper objectMapper = new ObjectMapper();

    @Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { Map<String, String> map = new TreeMap<String, String>(System.getenv());
String systemEnvironmentStr = objectMapper.writeValueAsString(map); resp.addHeader("Access-Control-Allow-Origin", "*");
resp.addHeader("Access-Control-Allow-Headers", "Content-Type, Accept");
resp.setContentType("application/json"); PrintWriter printWriter = resp.getWriter();
try {
printWriter.write(systemEnvironmentStr);
resp.setStatus(org.eclipse.jetty.server.Response.SC_OK);
}
finally {
if(printWriter!=null) {
printWriter.close();
}
}
}
}

5。Thrift的使用:

Thrift是facebook开源的一个项目https://github.com/apache/thrift

Thrift is a lightweight, language-independent software stack with an associated code generation mechanism for RPC. Thrift provides clean abstractions for data transport, data serialization, and application level processing. The code generation system takes a simple definition language as its input and generates code across programming languages that uses the abstracted stack to build interoperable RPC clients and servers.

Thrift is specifically designed to support non-atomic version changes across client and server code.

关于Thrift的使用这里有一篇参考文档 :http://www.importnew.com/23211.html

http://blog.csdn.net/m13321169565/article/details/7835957

http://www.javabloger.com/article/thrift-java-code-example.html

第一步 引入Dependency-

 compile 'org.apache.thrift:libthrift:0.9.1'

第二步:下载Windows的Thrift.exe用于根根据IDL生成不同语言的支持代码(YOUR CODE)

下载地址http://labs.renren.com/apache-mirror//incubator/thrift/0.5.0-incubating/thrift-0.5.0.exe

第三部:根据业务逻辑书写IDL文件

/*Include the another thrift file, like using*/
include "common.thrift"
namespace csharp a.b.c // The namespace used for csharp generated class file
namespace java a.b.d // java // Struct type
struct StructType{
1: string stringProperty,
2: i32 intProperty,
3: i64 intProperty,
4: double doubleProperty,
5: list<string> orderedListProperty,
6: set<string> unorderedListProperty,
7: map<string,string> k-vProperty,
8: common.typeInCommonThrift referenceProperty
}
// Enumeration type
enum EnumType{
1: A,
2: B,
3: C
}
// Service interface, methods should not have implementations
service ServiceOperation{
/**Service method comments**/
structType MethodName(1:paramType param1, 2:paramType parma2), // Other methods
}

Thirft IDL文件模板

第四部:运行命令 以生成java的IDL-
thrift-0.9.1.exe -gen java a.thrift

将生成的java代码直接拖到你的工程里对应的package下面。

第五步:使用上面生成的代码:

代码主要部分在上面的IDL中的Service声明部分,上面的Service部分生成的Java或者C# 的样式大概是这样的

// 类名ServiceOperation - IDL中由Service声明的类
public class ServiceOperation {
public interface Iface {
// 方法名和IDL中的Service 块中的方法名相同
public GetBookResponseType GetBooks(GetBookRequestType getReqeust) throws org.apache.thrift.TException; public SetBookResponseType SetBook(SetBookRequestType setBookRequest) throws org.apache.thrift.TException;
} // Client是用在客户端的类
public static class Client extends org.apache.thrift.TServiceClient implements Iface {
}
// Processor用在服务端的类
public static class Processor<I extends Iface> extends org.apache.thrift.TBaseProcessor<I> implements org.apache.thrift.TProcessor
{
} }

主要的类

第六部:在Server端定义Thrift Server所需要的component 主要是Protocol 和Transport代码如下

public class ThriftServer {
private BookRepository bookRepository;
private int port;
private TServer server;
private ServiceOperation.Processor processor;
private ThreadPoolExecutor executor;
private TNonblockingServerTransport transport; public ThriftServer(int _port) throws TTransportException { port=_port; bookRepository = new BookRepositoryImpl();
processor = new ServiceOperation.Processor<BookRepository>(bookRepository); transport = new TNonblockingServerSocket(port, 2000); executor = new ThreadPoolExecutor(100, 200, 1000, TimeUnit.MILLISECONDS, new SynchronousQueue<Runnable>()) {
@Override
public void execute(Runnable command) {
super.execute(command);
}
}; THsHaServer.Args args = new THsHaServer.Args(transport);
args.maxReadBufferBytes = 1024 * 1024 * 8;
server = new THsHaServer(args.executorService(executor).processor(processor));
} public void start(){
server.serve();
}
}
public interface BookRepository extends ServiceOperation.Iface{
}
 
public class BookRepositoryImpl implements BookRepository {
@Override
public GetBookResponseType GetBooks(GetBookRequestType getReqeust) throws TException {
return null;
} @Override
public SetBookResponseType SetBook(SetBookRequestType setBookRequest) throws TException {
SetBookResponseType setBookResponseType=new SetBookResponseType();
setBookResponseType.status= BookOperationStatus.NotFound;
return setBookResponseType;
}
}
 

这样就会在Server端开启一个端口监听来自客户端的请求

最后一部:在客户端比如是C# 的Console程序。 定义Client的组件

    static void Main(string[] args)
{
TSocket socket = new TSocket("10.2.5.63", , * ); TFramedTransport transport = new TFramedTransport(socket); transport.Open(); TBinaryProtocol protocol = new TBinaryProtocol(transport); Ctrip.Test.Client.Service.ServiceOperation.Client client = new Service.ServiceOperation.Client(protocol);
SetBookResponseType response = client.SetBook(new Service.SetBookRequestType()
{
Books = new CTripOSS.Thrift.Collections.THashSet<Service.Book>() {
new Book(){ BookId=, BookTitle="Test Book", BookPrice=, BookState=BookStatusEnumerate.IN}
}
}); Console.WriteLine(response.Status);
}

Client Code

一个Java项目的学习的更多相关文章

  1. java学习笔记(一):开始第一个java项目

    这里使用IntelliJ IDEA 来新建第一个java项目 在新建项目向导,你可以选择你的项目支持的技术,你正在做一个普通的Java项目,只需单击下一步. 下一步,新建一个test的项目. 新建一个 ...

  2. java项目(学习和研究)

    java项目就是研究,不断的对项目进行迭代,把产品做的越来越好,就是research. 自己想着做一个java项目把,可以类似牛客网,想好自己的预期产品,在设计的过程中可以不断改进和扩展,在做这个项目 ...

  3. 作为Java新手,如何才能快速的看透一个Java项目?

    前言 技术学习是一个总结.纠错.触类旁通的过程,而不是单纯重复练习的过程,如果你问一个做过5年以上Java的老码农,他们很多人都会有很强的"搬砖感",这种"搬砖感&quo ...

  4. 初学者如何吃透一个Java项目

    不少初学者朋友在学习Java过程中,会对着视频敲Java项目,其中遇到的BUG还能解决,但就是每次敲完一个项目,就感觉很空虚,项目里面的知识点感觉懂了但又好像没懂 这些朋友应该怎样才能掌握一个项目所用 ...

  5. 在Eclipse中,如何把一个java项目变成web项目

    经常在eclipse中导入web项目时,出现转不了项目类型的问题,导入后就是一个java项目.解决步骤:1.进入项目目录,可看到.project文件,打开.2.找到<natures>... ...

  6. 一个toolkit或者一个开源项目如何学习它并使用它

    一个toolkit或者一个开源项目如何学习它并使用它 一般一个流行的toolkit和开源项目,一般都会被广泛地被应用: 那么,我们如何学习它,如何应用它在自己的业务场景中呢? 答案就是:学习源码并借鉴 ...

  7. 【系列教程1】Gradle入门系列二:第一个Java项目

    这篇教程的主要内容是讲解如何用Gradle编译和打包一个简单的Java项目. 该Java项目只有一个需求:我们的构建脚本必须创建一个可执行的Jar文件,换句话说,我们必须能够使用命令java -jar ...

  8. java 项目相关 学习记录

    一位资深程序员大牛给予Java初学者的学习路线建议  [任何时期都可以好好看看] https://www.imooc.com/article/8993 https://www.jianshu.com/ ...

  9. [IntelliJ IDEA入门] 新建一个Java项目

    新建一个Project 是否有JDK配置 选择JavaEE 点击Next 项目路径和文件 .idea (directory based) 创建项目的时候自动创建一个 .idea 的项目配置目录来保存项 ...

随机推荐

  1. opencv + numpy for python

    OpenCV的全称是:Open Source Computer Vision Library.OpenCV是一个基于(开源)发行的跨平台计算机视觉库,可以运行在Linux.Windows和Mac OS ...

  2. Android的AndroidManifest.xml文件的详解

    一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文件.它位于整个项目的根目录,描述了package中暴露的组件(activiti ...

  3. C和指针c6-1

    #include<stdio.h> #include<stdlib.h> char *find_char(char const *source_str, char const ...

  4. 使用 asp.net Web API 2的坑

    使用工具: Googl  浏览器+PostMan 插件 写了个  控制器 添加了个Action,结果呢?GET 方式请求没问题. POST一直,在服务器端获取不了参数...找了官方的文档 .各种雨里雾 ...

  5. WPF制作的一个小功能,智能提示(IntelliSense)

    原文http://www.cnblogs.com/scheshan/archive/2012/06/30/2570867.html 最近WPF项目中遇到一个需求,需要给一个RichTextBox添加智 ...

  6. 【转】理解 Android Build 系统----不错

    $ mmm -help用法:make [选项] [目标] ...选项: -b, -m 忽略兼容性. -B, --always-make Unconditionally make all targets ...

  7. 8个华丽的HTML5相册动画欣赏

    HTML5的图片动画非常丰富,我们也在网站上分享过很多关于HTML5的图片动画.相册在网络中也十分常见,本文我们要分享一些比较华丽的jQuery/HTML5相册动画,希望大家喜欢. 1.HTML5 3 ...

  8. UVA 1599 Ideal Path(bfs1+bfs2,双向bfs)

    给一个n个点m条边(<=n<=,<=m<=)的无向图,每条边上都涂有一种颜色.求从结点1到结点n的一条路径,使得经过的边数尽量少,在此前提下,经过边的颜色序列的字典序最小.一对 ...

  9. iOS 无效的版本,提交成功,不出现版本号

    最近更新到 iOS 10,提交审核 会卡在 转菊花 ...需要更新到Xcode 8 去提交. 然后提交成功后,版本管理 新版本,构建版本 迟迟不出来.恭喜你,你的版本是无效的.请看看 你的 公司app ...

  10. ffmpeg API录制rtsp视频流

    原文出自http://blog.csdn.net/zxwangyun/article/details/8190638#reply   作者 Sloan 这里在录制时,并没有进行转码,只是相当于把rts ...