{"id":18773902,"url":"https://github.com/ejunjsh/jsimple","last_synced_at":"2025-12-14T02:30:17.961Z","repository":{"id":109691053,"uuid":"107089495","full_name":"ejunjsh/jSimple","owner":"ejunjsh","description":"a java framework include ioc,orm,mvc","archived":false,"fork":false,"pushed_at":"2019-01-28T03:01:21.000Z","size":2561,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2024-12-29T08:41:56.531Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ejunjsh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-10-16T06:57:42.000Z","updated_at":"2019-01-28T03:01:23.000Z","dependencies_parsed_at":"2023-03-13T14:05:12.854Z","dependency_job_id":null,"html_url":"https://github.com/ejunjsh/jSimple","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ejunjsh%2FjSimple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ejunjsh%2FjSimple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ejunjsh%2FjSimple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ejunjsh%2FjSimple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ejunjsh","download_url":"https://codeload.github.com/ejunjsh/jSimple/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239680985,"owners_count":19679509,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-07T19:36:14.768Z","updated_at":"2025-12-14T02:30:17.922Z","avatar_url":"https://github.com/ejunjsh.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# jSimple\r\n## 简介\r\n### 源码模块结构如下：\r\n```\r\njSimple-parent(jSimple父级模块，配置基础依赖)\r\n L aop--利用cglib实现的aop，支持多拦截器（未排序）\r\n L bean--一个bean容器和一个扫描器\r\n L blog--angularjs开发的blog\r\n L cache--简单缓存实现，包括内存和memcached\r\n L config--整个jsimple配置常量接口\r\n L data--简单数据访问接口，基于dbutils开发，实现简单ORM，还有延迟加载\r\n L exception--统一jsimple异常类\r\n L hessian--hessian使用例子\r\n L ioc--依赖注入，基于bean容器的注入\r\n L mvc--mvc框架，应该说还是好好用的\r\n L utils--基于apache公共java库的一个公共库\r\n```\r\n\r\n## 入门\r\n### 1.安装\r\nclone代码之后，直接maven命令安装\r\n```\r\nmvn clean install\r\n```\r\n### 2.创建一个maven web工程\r\n基本java目录结构如下：\r\n```\r\ncom.sky.jSimple.blog\r\n　　┗ controller/ 控制器\r\n　　┗ entity/   实体\r\n   ┗ dao/   数据访问\r\n   ┗ service/   业务逻辑\r\n   ┗ interceptor/   拦截器\r\n```\r\n### 3. 配置 Maven 依赖\r\n```\r\n\u003cdependency\u003e\r\n   \u003cgroupId\u003ecom.sky.jSimple\u003c/groupId\u003e\r\n   \u003cartifactId\u003ejSimple-mvc\u003c/artifactId\u003e\r\n   \u003cversion\u003e0.0.1-SNAPSHOT\u003c/version\u003e\r\n\u003c/dependency\u003e\r\n```\r\n### 4. 编写配置\r\n\r\n在 `resources` 目录下，创建一个名为 `jSimple.xml` 的文件，内容如下：\r\n```xml\r\n\u003c?xml version=\"1.0\" encoding=\"UTF-8\"?\u003e\r\n\u003cjSimple\u003e\r\n    \u003cmvc static-suffix=\".jpg;.bmp;.jpeg;.png;.gif;.html;.css;.js;.htm;.ttf;.woff;.svg;.swf;.map\"\r\n         static-expire=\"3600\"\r\n            /\u003e\r\n    \u003cbeans scan-package=\"${scan.package}\"\u003e\r\n        \u003cbean id=\"dataSource\"\r\n              class=\"org.apache.commons.dbcp.BasicDataSource\"\u003e\r\n            \u003cproperty name=\"driverClassName\" value=\"com.mysql.jdbc.Driver\"/\u003e\r\n            \u003cproperty name=\"url\"\r\n                      value=\"${jdbc.driver}\"/\u003e\r\n            \u003cproperty name=\"username\" value=\"${jdbc.user}\"/\u003e\r\n            \u003cproperty name=\"password\" value=\"${jdbc.pwd}\"/\u003e\r\n            \u003cproperty name=\"initialSize\" value=\"10\"/\u003e\r\n            \u003cproperty name=\"maxIdle\" value=\"20\"/\u003e\r\n            \u003cproperty name=\"minIdle\" value=\"5\"/\u003e\r\n            \u003cproperty name=\"maxActive\" value=\"50\"/\u003e\r\n        \u003c/bean\u003e\r\n        \u003cbean id=\"sessionFactory\" class=\"com.sky.jSimple.data.SessionFactory\"\u003e\r\n            \u003cproperty name=\"dataSource\" ref=\"dataSource\"/\u003e\r\n        \u003c/bean\u003e\r\n        \u003cbean id=\"jSimpleDataTemplate\" class=\"com.sky.jSimple.data.JSimpleDataTemplate\"\u003e\r\n            \u003cproperty name=\"sessionFactory\" ref=\"sessionFactory\"/\u003e\r\n            \u003cproperty name=\"dbType\" value=\"mysql\"/\u003e\r\n        \u003c/bean\u003e\r\n        \u003c!--默认是memoryCacheManager,去掉注释用的是memcached--\u003e\r\n        \u003c!--\u003cbean id=\"memcachedCacheManager\" class=\"com.sky.jSimple.cache.MemcachedCacheManager\"\u003e--\u003e\r\n        \u003c!--\u003cproperty name=\"servers\"  value=\"192.168.153.132:11111,192.168.153.133:11111\" /\u003e--\u003e\r\n        \u003c!--\u003cproperty name=\"weights\"  value=\"1,1\" /\u003e--\u003e\r\n        \u003c!--\u003c/bean\u003e--\u003e\r\n        \u003c!--\u003cbean id=\"cacheProxy\" class=\"com.sky.jSimple.cache.CacheProxy\"\u003e--\u003e\r\n        \u003c!--\u003cproperty name=\"cacheManager\"  ref=\"memcachedCacheManager\" /\u003e--\u003e\r\n        \u003c!--\u003c/bean\u003e--\u003e\r\n    \u003c/beans\u003e\r\n\u003c/jSimple\u003e\r\n```\r\n这里很像spring的做法，之所以用这个，主要是因为想实现一个类下面的多个bean实体的配置，例如多数据源,当然还有就是灵活配置\r\n\r\n然后在`web.xml` 添加一个serlvet\r\n```xml\r\n \u003cservlet\u003e  \r\n        \u003cservlet-name\u003ejsimplemvc\u003c/servlet-name\u003e  \r\n        \u003cservlet-class\u003ecom.sky.jSimple.mvc.DispatcherServlet\u003c/servlet-class\u003e\r\n        \u003cinit-param\u003e\r\n          \u003cparam-name\u003econfigPath\u003c/param-name\u003e\r\n          \u003cparam-value\u003e/jSimple.xml\u003c/param-value\u003e\r\n        \u003c/init-param\u003e\r\n      \u003cload-on-startup\u003e1\u003c/load-on-startup\u003e\r\n    \u003c/servlet\u003e  \r\n    \u003cservlet-mapping\u003e  \r\n        \u003cservlet-name\u003ejsimplemvc\u003c/servlet-name\u003e  \r\n        \u003curl-pattern\u003e/\u003c/url-pattern\u003e  \r\n    \u003c/servlet-mapping\u003e  \r\n```\r\n### 5. 编写entity\r\n```java\r\n@Entity(\"blog\")\r\npublic class Blog implements Serializable {\r\n\r\n    @Id\r\n    private long id;\r\n    private String title;\r\n    private String content;\r\n    private Date createdDate;\r\n    private Date lastModifiedDate;\r\n    private long uid;\r\n    private long viewCount;\r\n    private String linkName;\r\n    private long categoryId;\r\n    private String tags;\r\n\r\n    private int isRecommend;\r\n\r\n    @GetEntity(condition = \"id=?\", values = \"categoryId\")\r\n    private Category category;\r\n\r\n    @GetEntity(condition = \"id=?\", values = \"uid\")\r\n    private User user;\r\n\r\n    @GetCount(condition = \"blogId=?\", values = \"id\", cls = Comment.class)\r\n    private Long commentCount;\r\n    \r\n    //getter/setter\r\n\r\n}\r\n```\r\n里面`@Entity`注解里面是表名，`@Id`注解是必须的,`@GetEntity`和`@GetCount`是延迟加载的对象注解。\r\n\r\n### 6.dao编写\r\n```java\r\n@Bean\r\npublic class BlogDao {\r\n    @Inject\r\n    private JSimpleDataTemplate jSimpleDataTemplate;\r\n\r\n    public void insert(Blog entity) {\r\n        jSimpleDataTemplate.insert(entity);\r\n    }\r\n\r\n\r\n    public void update(Blog entity) {\r\n        jSimpleDataTemplate.update(entity);\r\n    }\r\n\r\n    public void delete(Long id) {\r\n        jSimpleDataTemplate.delete(id, Blog.class);\r\n    }\r\n\r\n    public Blog getById(Long id) {\r\n        return jSimpleDataTemplate.getById(Blog.class, id);\r\n    }\r\n    \r\n    //getter/setter\r\n}\r\n```\r\n`@Bean`代表此类放进bean容器里面，`@Inject` 注入进去，可以传参数进去代表注入的是那个bean例如`@Inject(\"jSimpleDataTemplate\")`,同时注意的是被注入对象必须有setter\r\n\r\n### 7.service编写\r\n```java\r\n@Bean\r\npublic class BlogService implements IBlogService {\r\n    @Inject\r\n    private BlogDao blogDao;\r\n\r\n    @Transactional\r\n    public void insert(Blog entity) {\r\n        blogDao.insert(entity);\r\n    }\r\n\r\n    @Transactional\r\n    public void update(Blog entity) {\r\n        blogDao.update(entity);\r\n    }\r\n\r\n    public void delete(Long id) {\r\n        blogDao.delete(id, Blog.class);\r\n    }\r\n\r\n    public Blog getById(Long id) {\r\n        return blogDao.getById(Blog.class, id);\r\n    }\r\n   \r\n    //getter/setter\r\n}\r\n```\r\n`@Transactional` 事务处理，里面可以放入多个dao操作。\r\n\r\n### 8.Controller 编写\r\n```java\r\n@Bean\r\npublic class BlogController extends ControllerBase {\r\n   @Inject\r\n   private IBlogService blogService;\r\n   \r\n   @HttpPost(\"/api/blog\")\r\n   public ActionResult addBlog(Blog blog)  {\r\n   \r\n           blog.setCreatedDate(new Date());\r\n           blog.setLastModifiedDate(new Date());\r\n           blog.setUid(1);\r\n           blog.setViewCount(0);\r\n           blogService.insert(blog);\r\n   \r\n           return json(blog);\r\n   }\r\n   \r\n   //setter/getter\r\n}\r\n```\r\ncontroller中最重要的是用`@HttpPost` 标记的方法，方法参数是由前端post过来参数，支持封装到一个对象，map等。\u003cbr /\u003e\r\n例如：url /api/blog/{id}/edit?page=1 \u003cbr /\u003e\r\n相应的参数是(int page,int id)或者是(Map map)或者是包含page和id两个属性的实体。 \u003cbr /\u003e\r\n目前有`@HttpPost` `@HttpGet` `@HttpPut` `@HttpDelete` 四种标记。 \u003cbr /\u003e\r\n\r\n返回的`ActionResult` 支持多种，json，html，jsp，file，freemarker，velocity等，同时易于扩展。\r\n例如，我要返回一个验证码，那我要怎么实现一个`ActionResult`,代码如下：\r\n```java\r\npublic class ValidateCodeResult extends ActionResult {\r\n    @Override\r\n    public void ExecuteResult() {\r\n        response.setContentType(\"image/jpeg\");//设置相应类型,告诉浏览器输出的内容为图片\r\n        response.setHeader(\"Pragma\", \"No-cache\");//设置响应头信息，告诉浏览器不要缓存此内容\r\n        response.setHeader(\"Cache-Control\", \"no-cache\");\r\n        response.setDateHeader(\"Expire\", 0);\r\n        //验证码类，用来生成验证码的类库\r\n        RandomValidateCode randomValidateCode = new RandomValidateCode();\r\n        try {\r\n            randomValidateCode.getRandcode(request, response);//输出图片方法\r\n        } catch (Exception e) {\r\n            throw new JSimpleException(e);\r\n        }\r\n    }\r\n\r\n}\r\n```\r\n在controller调用\r\n```java\r\n@HttpGet(\"/validateCode\")\r\npublic ActionResult getValidateCode()\r\n{\r\n   return new ValidateCodeResult();\r\n}\r\n```\r\nSo easy!\r\n\r\n### 9.异常处理\r\n每个controller里面都有一个onException的方法，默认是返回打印错误信息的页面，直接覆盖onException可以实现自定义的异常\r\n例如一个ajax请求，我不需要返回一个错误信息的页面而是一个json，那么代码可以这样写：\r\n```java\r\n public class AjaxController extends ControllerBase {\r\n \r\n     public void onException(Throwable e, HttpServletRequest request, HttpServletResponse response) {\r\n         try {\r\n             Map map=new HashMap();\r\n             map.put(\"error\",e);\r\n             json(map).ExcuteResult();\r\n         } catch (JSimpleException e1) {\r\n             // TODO Auto-generated catch block\r\n             e1.printStackTrace();\r\n         }\r\n     }\r\n     \r\n }\r\n```\r\n\r\n### 10.拦截器编写\r\n假如我要实现一个非登陆跳转的拦截器，代码如下：\r\n```java\r\n@Order(98)\r\npublic class NeedLoginInterceptor extends Interceptor {\r\n\r\n    public Class\u003c? extends Annotation\u003e getAnnotation() {\r\n        return Login.class;\r\n    }\r\n\r\n    @Override\r\n    public ActionResult before(Class\u003c?\u003e cls, Method method, Object[] params) {\r\n        if (BlogContext.getUser() == null) {\r\n            return new RedirectResult(\"/user/login?path=\" + request.getAttribute(\"encodeUrl\"));\r\n        }\r\n        return null;\r\n    }\r\n\r\n    @Override\r\n    public void after(Class\u003c?\u003e cls, Method method, Object[] params, ActionResult result) {\r\n    }\r\n\r\n}\r\n```\r\n`@Order`注解表示，这个拦截器执行顺序，越大表示执行最前面。`getAnnotation()`表示标记了什么注解方法会被拦截。\u003cbr /\u003e\r\n`before()` 和 `after()` 代表方法之前和之后执行，必须要注意的是`before()`返回非空表示直接返回，不往下执行了。\r\n\r\n### 总结\r\n这个框架还存在很多问题，我只能说，就当学习一下呗。上面的实例代码来自一个基于这个框架写的blog，jsimple-blog，多谢捧场哦。\r\n\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fejunjsh%2Fjsimple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fejunjsh%2Fjsimple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fejunjsh%2Fjsimple/lists"}