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. wdcp/wdlinux 在 UBUNTU/linux 中安装失败原因之创建用户

    根本原因在于安装时创建的用户www 使用了和ubuntu已创建的用户,冲突了自然创建不了用户. 你可以修改lanmp.sh脚本中创建www用户时的代码,将1000改为其他数字. 也可以修改当前用户的U ...

  2. gcc编译通过,运行却显示“段错误”的解决方法

    ​第一次在Liunx上(liunx mint 17)使用gcc编译c文件,竟然提示“找不到stdio.h",经过google后发现执行 sudo apt-get install build- ...

  3. 对于C++中const & T operator= 的一点思考

    一个正常的assignment操作符的声明是这样的. const elmentType & elmentType::operator=(const elmentType &rhs) 这 ...

  4. linux开启mysql远程登录

    Mysql默认root用户只能本地访问,不能远程连接管理mysql数据库,Linux如何开启mysql远程连接?设置步骤如下:1.GRANT命令创建远程连接mysql授权用户itloggermysql ...

  5. BZOJ 2876 骑行川藏

    http://www.lydsy.com/JudgeOnline/problem.php?id=2876 拉格朗日乘数法:f'+入g'=0,f为函数的导数,g为限制条件的导数. 思路:E=Σki*si ...

  6. SCSI磁盘标准的架构与文档

    来自scsi标准的官方网站http://t10.org/,具体的文档可以去浏览官方网站. (*) This chart reflects the currently approved SCSI pro ...

  7. js中获取键盘事件

    <script type="text/javascript" language=JavaScript charset="UTF-8"> docume ...

  8. Canvas API -- JavaScript 标准参考教程(alpha)

    Canvas API -- JavaScript 标准参考教程(alpha) Canvas API

  9. hdu - 4651 - Partition

    题意:把一个整数N(1 <= N <= 100000)拆分不超过N的正整数相加,有多少种拆法. 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid ...

  10. Mac 下纯lua(三)

    文件处理 直接使用io调用 io.close();文件流关闭 io.flush():如果文件流以bufferd缓存模式处理,输入不会立即存入文件,需要调用本函数 io.input(file):输入 i ...