一个Java项目的学习
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项目的学习的更多相关文章
- java学习笔记(一):开始第一个java项目
这里使用IntelliJ IDEA 来新建第一个java项目 在新建项目向导,你可以选择你的项目支持的技术,你正在做一个普通的Java项目,只需单击下一步. 下一步,新建一个test的项目. 新建一个 ...
- java项目(学习和研究)
java项目就是研究,不断的对项目进行迭代,把产品做的越来越好,就是research. 自己想着做一个java项目把,可以类似牛客网,想好自己的预期产品,在设计的过程中可以不断改进和扩展,在做这个项目 ...
- 作为Java新手,如何才能快速的看透一个Java项目?
前言 技术学习是一个总结.纠错.触类旁通的过程,而不是单纯重复练习的过程,如果你问一个做过5年以上Java的老码农,他们很多人都会有很强的"搬砖感",这种"搬砖感&quo ...
- 初学者如何吃透一个Java项目
不少初学者朋友在学习Java过程中,会对着视频敲Java项目,其中遇到的BUG还能解决,但就是每次敲完一个项目,就感觉很空虚,项目里面的知识点感觉懂了但又好像没懂 这些朋友应该怎样才能掌握一个项目所用 ...
- 在Eclipse中,如何把一个java项目变成web项目
经常在eclipse中导入web项目时,出现转不了项目类型的问题,导入后就是一个java项目.解决步骤:1.进入项目目录,可看到.project文件,打开.2.找到<natures>... ...
- 一个toolkit或者一个开源项目如何学习它并使用它
一个toolkit或者一个开源项目如何学习它并使用它 一般一个流行的toolkit和开源项目,一般都会被广泛地被应用: 那么,我们如何学习它,如何应用它在自己的业务场景中呢? 答案就是:学习源码并借鉴 ...
- 【系列教程1】Gradle入门系列二:第一个Java项目
这篇教程的主要内容是讲解如何用Gradle编译和打包一个简单的Java项目. 该Java项目只有一个需求:我们的构建脚本必须创建一个可执行的Jar文件,换句话说,我们必须能够使用命令java -jar ...
- java 项目相关 学习记录
一位资深程序员大牛给予Java初学者的学习路线建议 [任何时期都可以好好看看] https://www.imooc.com/article/8993 https://www.jianshu.com/ ...
- [IntelliJ IDEA入门] 新建一个Java项目
新建一个Project 是否有JDK配置 选择JavaEE 点击Next 项目路径和文件 .idea (directory based) 创建项目的时候自动创建一个 .idea 的项目配置目录来保存项 ...
随机推荐
- 远程访问TeamTalk的Mysql数据库被拒解决方法
1.A Database Error Occurred 问题如图: 蓝狐给的解答是: 这是访问mysql出错了.解决办法参考:http://www.bkjia.com/jingyan/512248.h ...
- 串口WIF简单调试
/*********************************************************************** Title:Wifi串口调试 Hardware: Wi ...
- wordpress教程之函数site_url()、home_url()、bloginfo(‘url’)的区别
在wordpress插件和主题开发中经常需要获取各种URL路径,wordpress提供了以下集中方法获得URL路径: plugins_url() — 插件目录的 URL (例如:http://www. ...
- 【Xamarin挖墙脚系列:常用的Mac 命令】
通俗点说Mac 跟Linux的爹都是Unix,他们都加入了标准的Shell命令工具,bash 所以俩系统中的命令基本通用 Linux下的操作手册,本人自己整理了一份.呵呵~~~~ 还可以使用客户端远程 ...
- jdk8预览
原文:http://www.techempower.com/blog/2013/03/26/everything-about-java-8/ 1.接口增强 (1)接口可以定义static方法 java ...
- 括号匹配问题(C++、堆栈)
原文地址:http://www.cppblog.com/GUO/archive/2010/09/12/126483.html /* 括号匹配问题,比较经典,利用堆栈来实现(摘自internet) 1. ...
- poj 1015 Jury Compromise_dp
题意:n个陪审团,每个陪审团有x,y值,选出m个陪审团,要求 (sum(xi)-sum(yi))最少,当 (sum(xi)-sum(yi))最少有多个,取sum(xi)+sum(yi)最大那个 ,并顺 ...
- 喜欢的女生快被别人抢走了,我敢怎么抢? - V2EX
喜欢的女生快被别人抢走了,我敢怎么抢? - V2EX 三大定律镇楼: 第一定律:永远不要以为女生对你有好感.第二定律:告白等于见光死.第三定律:秀恩爱分得快.
- C# Socket学习笔记二
小记:昨天咱们已经了解了Socket的通信原理,可是点对点的一次通信并不是我们想要的,那么今天那我们就继续学习异步通信,简单来说就是服务器端和客户端可以进行多次 互发信息的通信而不用担心通道会关闭.在 ...
- 【考虑周全+数学变形】【11月赛】Is it a fantastic matrix?
Is it a fantastic matrix? Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/ ...