ServiceFramework is a web-application framework that includes some powerfull Persistence Components like ActiveORM and MongoMongo written by java language according to the Model-View-Controller(MVC) pattern.
clone and build:
git clone [email protected]:allwefantasy/ServiceFramework.git
mvn install -Pscala-2.11 -Pjetty-8 -Pweb-include-jetty-8
If you wanna switch scala version,use follow command:
./dev/change-version-to-2.10.sh
however,we realy recommend you clone source and using 'maven deploy -DskipTests' command to upload jar to your private maven repository.
make sure config/application.yml,config/logging.yml are present in your project root.
-
ActiveORM in ServiceFramework like ActiveRecord in Rails,Awesome.
List<Tag> tags = Tag.where(map("name","java")).fetch;
-
Controller is total redesigned and some usefull functions are provied.
-
Most Object are managed by IOC.
@inject Service service;
-
Easy to Test without Servlet container
@Test public void search() throws Exception { RestResponse response = get("/doc/blog/search", map( "tagNames", "_10,_9" )); Assert.assertTrue(response.status() == 200); Page page = (Page) response.originContent(); Assert.assertTrue(page.getResult().size() > 0); }
-
just a little configuration and Thrift & RESTFul are all supported
###############http config################## http: port: 7700 disable: false thrift: disable: false services: net_csdn_controller_thrift_impl_CLoadServiceImpl: port: 7701 min_threads: 100 max_threads: 1000 servers: load: ["127.0.0.1:7701"]
-
Template Engine using Velocity. Instance Variables and Helper Class method will be automatically imported in page
@At(path = "/hello", types = GET) public void hello() { render(200, map( "name", "ServiceFramework" ), ViewType.html); }
-
Dubbo is suppored now. You can do everything dubbo can in Serviceframework. RestProtocol as a new feature is also been added to make invoking HTTP API like RPC.
@At(path = "/say/hello", types = {RestRequest.Method.GET}) public void sayHello() { render(200, "hello" + param("kitty")); } you can just type 'http://127.0.0.1/say/hello?kitty=wow' in Chrome , 'hellokitty' will be retured. However,maby you wanna invoke this HTTP API in your program. Just declare a interface like this: public interface TagController { @At(path = "/say/hello", types = {RestRequest.Method.GET, RestRequest.Method.POST}) public HttpTransportService.SResponse sayHello(RestRequest.Method method, Map<String, String> params); @At(path = "/say/hello", types = {RestRequest.Method.GET}) public HttpTransportService.SResponse sayHello3(@Param("kitty") String kitty); now,you can code like this: tagController.sayHello(RestRequest.Method.GET, WowCollections.map("kitty", "你好,太脑残")).getContent() or tagController.sayHello3("哇塞,天才呀").getContent()
-
Without Dubbo,you can also invoke HTTP API like RPC.
-
Suppose we have a Searcher, the rest API is something like '/v2/
//_search'。Create a new Interface in your project(Scala Example):trait SearcherClient { @At(path = Array("/v2/~/~/_search"), types = Array(GET, POST)) @BasicInfo( desc = "索引服务", state = State.alpha, testParams = "", testResult = "", author = "WilliamZhu", email = "[email protected]" ) def search(params: Map[String, String], content: String, method: net.csdn.modules.http.RestRequest.Method): java.util.List[HttpTransportService.SResponse] }
-
Now you can create SearchClient instance like this (Please make sure you only create once.)(Scala Example):
val _searchClient = AggregateRestClient.buildClient[SearcherClient](hostAndPorts, new SearchEngineStrategy(), httpRequest) //SearchEngineStrategy is the Strategy how you invoke multi backend.
-
Now ,invoking like this(Scala Example):
val res = _searchClient.search( url._2.toMap ++ Map("index" -> index, "type" -> ctype), query, RestRequest.Method.POST).searchResult
-
Step 1 > clone
git clone https://github.com/allwefantasy/ServiceFramework
Step 2 > import to your IDE
Step 3 > modify config/application.yaml according to your DB Connection infomation. Notice that if you only use mysql you should disable mongodb.
datasources:
mysql:
host: 127.0.0.1
port: 3306
database: wow
username: root
password: root
disable: false
mongodb:
host: 127.0.0.1
port: 27017
database: wow
disable: false
redis:
host: 127.0.0.1
port: 6379
disable: true
Step4 > import sql/wow.sql into MySQL
Step5 > create com.example.model.Tag class.
public class Tag extends Model
{
}
Step6 > create com.example.controller.http.TagController
public class TagController extends ApplicationController
{
@At(path = "/hello", types = RestRequest.Method.GET)
public void hello() {
Tag tag = Tag.create(map("name","java"));
tag.save();
render(200, map(
"tag", tag
), ViewType.html);
}
}
Step7 > create template/tag/hello.vm
Hello $tag.name! Hello world!
Step8 > create startup class
public class ExampleApplication {
public static void main(String[] args) {
ServiceFramwork.scanService.setLoader(ExampleApplication.class);
Application.main(args);
}
}
Step9 > run ExampleApplication in your IDE
Step10 > visit http://127.0.0.1:9002/hello . Check your database, table tag will have one item.
Step11 > Prepare for Test Unit . modify runner.DynamicSuite and add follow in first line of initEnv method.
ServiceFramwork.scanService.setLoader(ExampleApplication.class);
Step12 > create test class test.com.example.TagControllerTest
public class TagControllerTest extends BaseControllerTest {
@Test
public void testHello() throws Exception {
Tag.deleteAll();
RestResponse response = get("/hello", map());
Assert.assertTrue(response.status() == 200);
String result = response.content();
Assert.assertEquals("Hello java! Hello world!", result);
}
}
Step13 > run DynamicSuiteRunner
Step14 > However,DynamicSuteRunner is not required。 You can also add following lines to you test class and then you can use your IDE to test the class directly.
static {
initEnv(ExampleApplication.class);
}
initEnv method promise that your container will be started propertly and right ClassLoader be used.
Step-by-Step-tutorial-for-ServiceFramework(continue...)