diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..0b2ff139 --- /dev/null +++ b/.gitignore @@ -0,0 +1,11 @@ +!/.gitignore +/target/ +/catalina.base_IS_UNDEFINED/ +/.classpath +/.project +/.settings/ +/reports +/.pmd +/.springBeans +/.idea/ +/ssmbootstrap_table.iml \ No newline at end of file diff --git a/README.md b/README.md index 3ac4ba73..b8ef2a6c 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,70 @@ -#ssmbootstrap_table demo -## 技术栈 -* spring+springmvc+mybatis -* poi3 -* 自定义标签开发 -* bootstrap3 -* bootstrap-table1.9 -* druid -* weui -* log4jdbc - -##How to run -项目采用maven构建,运行前请先执行src/main/java下的sql脚本到你的mysql数据库中,然后修改src/main/resource下的jdbc.properties配置文件中的数据库配置信息,进入项目目录,执行mvn tomcat7:run来运行 - -#![](src/main/webapp/image/sys1.png) -#![](src/main/webapp/image/sys2.png) \ No newline at end of file +# ssmbootstrap_table demo + +## 技术栈/technology stack +* spring+springmvc+mybatis +* poi3 +* 自定义标签开发 +* bootstrap3/bootstrap-fileinput/jquery.fileupload +* bootstrap-table1.9 +* druid +* fastjson +* weui +* log4jdbc/log4jdbc-remix/log4jdbc-log4j2(show sql) +* hibernate-validator +* [spring-jsonp-support](https://github.com/bhagyas/spring-jsonp-support) +* SUI mobile +* lombok +* ehcache +* metrics +* springfox +* spring-websocket +* zxing +* jwebunit +* mockito +* itextpdf + +> ## github:[https://github.com/netbuffer/ssmbootstrap_table](https://github.com/netbuffer/ssmbootstrap_table) +> ## git@osc:[https://gitee.com/netbuffer/ssmbootstrap_table](https://gitee.com/netbuffer/ssmbootstrap_table) + +## Stargazers over time +[![Stargazers over time](https://starchart.cc/netbuffer/ssmbootstrap_table.svg)](https://starchart.cc/netbuffer/ssmbootstrap_table) + +## How to run +The project constructed by `maven`, please execute under the `help directory` `SQL script` to your `MySQL` database operation, and then modify the database configuration information `jdbc.properties` under the path `src/main/resource` configuration file in the project directory, enter, execute `mvn tomcat7:run` to run + +## 运行 +项目采用`maven`构建,运行前请先执行`help目录`下的`sql`脚本到你的`mysql`数据库中,然后修改`src/main/resource`下的`jdbc.properties`配置文件中的数据库配置信息,进入项目目录,执行`mvn tomcat7:run`来运行 + +git->clone;eclipse->File->Import->Existing Maven projects,导入到eclipse后,等maven依赖下载完,右键项目,run as->maven build->tomcat7:run + +# ![demo](src/main/webapp/image/demo.gif) + +# ![数据列表页面](src/main/webapp/image/sys2.png) + +metrics | @Timed +---|--- +![metrics-servlet](src/main/webapp/image/metrics.png) | ![metrics-servlet](src/main/webapp/image/@Timed.png) + + +# ![springfox](src/main/webapp/image/swagger.png) +--- +> +> * develop开发分支 +> * cxf test `apache cxf` +> * JdbcTemplate(test spring `jdbctemplate`/test `shiro`) +> * springtask(test spring `task`/`quartz`) +> * velocity(test `velocity` template) +> * swagger (test `swagger` api doc) + +# other projects +> `ssmbt(ssmbootstrap_table maven module )` github:[https://github.com/netbuffer/ssmbt](https://github.com/netbuffer/ssmbt)`/`git@osc:[https://gitee.com/netbuffer/ssmbt](https://gitee.com/netbuffer/ssmbt) + +> `sssbootstrap_table(spring+springmvc+spring data jpa)` github:[https://github.com/netbuffer/sssbootstrap_table](https://github.com/netbuffer/sssbootstrap_table)`/`git@osc:[https://gitee.com/netbuffer/sssbootstrap_table](https://gitee.com/netbuffer/sssbootstrap_table) + +> `sshbootstrap_table(spring+struts2+hibernate)` github:[https://github.com/netbuffer/sshbootstrap-table](https://github.com/netbuffer/sshbootstrap-table)`/`git@osc:[https://gitee.com/netbuffer/sshbootstrap-table](https://gitee.com/netbuffer/sshbootstrap-table) + +> `spring-boot-bootstrap_table(springboot)` github:[https://github.com/netbuffer/spring-boot-bootstrap_table](https://github.com/netbuffer/spring-boot-bootstrap_table)`/`git@osc:[https://gitee.com/netbuffer/spring-boot-bootstrap_table](https://gitee.com/netbuffer/spring-boot-bootstrap_table) + +> `jfinal-bootstrap-table(jfinal)`github:[https://github.com/netbuffer/jfinal-bootstrap-table](https://github.com/netbuffer/jfinal-bootstrap-table)`/`git@osc:[http://gitee.com/netbuffer/jfinal-bootstrap-table](http://gitee.com/netbuffer/jfinal-bootstrap-table) + +> `medoo_bootstrap_table(php5)`github:[https://github.com/netbuffer/medoo_bootstrap_table](https://github.com/netbuffer/medoo_bootstrap_table)`/`git@osc:[http://gitee.com/netbuffer/medoo_bootstrap_table](http://gitee.com/netbuffer/medoo_bootstrap_table) \ No newline at end of file diff --git a/help/README.md b/help/README.md new file mode 100644 index 00000000..52327c8e --- /dev/null +++ b/help/README.md @@ -0,0 +1,11 @@ +### 备注 +* `FileUploadController`-文件上传测试,包括`jquery.fileupload`的使用 +* `JsonpController`-测试jsonp使用,spring-jsonp库的使用,原理就是通过`HttpServletResponseWrapper`修改响应 +* `ApiController`-@RestController注解测试,编写http接口使用很方便,开发restful接口好用 +* `GlobalExceptionController`-全局异常捕获处理 +* `TestController`-一些乱七八糟的测试... +* `MySpringTextWsHandler`spring-websocket测试 +* `UserController`测试数据获取、json/pdf/excel视图 +--- + +> 使用idea编译工程需要在maven pom.xml中配置打包xml/properties资源,默认idea不打包,eclipse会打包 \ No newline at end of file diff --git a/help/db.sql b/help/db.sql new file mode 100644 index 00000000..f04ff4b0 --- /dev/null +++ b/help/db.sql @@ -0,0 +1,96 @@ +CREATE TABLE `user` ( + `id` bigint(11) NOT NULL AUTO_INCREMENT, + `name` varchar(50) NOT NULL COMMENT '姓名', + `sex` varchar(2) NOT NULL COMMENT '性别', + `age` int(3) NOT NULL COMMENT '年龄', + `phone` varchar(11) NOT NULL DEFAULT '0' COMMENT '手机', + `deliveryaddress` varchar(200) DEFAULT NULL COMMENT '收货地址', + `adddate` int(11) NOT NULL COMMENT '添加时间', + PRIMARY KEY (`id`) +) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `address`; +CREATE TABLE `address` ( + `user_id` bigint(20) DEFAULT NULL, + `province` varchar(255) DEFAULT NULL, + `city` varchar(255) DEFAULT NULL +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +DROP TABLE IF EXISTS `menu`; +CREATE TABLE `menu` ( + `id` bigint(20) NOT NULL DEFAULT '0', + `name` varchar(255) DEFAULT NULL COMMENT '菜单名', + `parent_id` bigint(20) DEFAULT NULL COMMENT '父id', + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of menu +-- ---------------------------- +INSERT INTO `menu` VALUES ('1', 'menu', '0'); +INSERT INTO `menu` VALUES ('2', 'submenu', '1'); + +DROP TABLE IF EXISTS `card`; +CREATE TABLE `card` ( + `user_id` bigint(20) NOT NULL DEFAULT '0', + `card_no` varchar(255) DEFAULT NULL, + PRIMARY KEY (`user_id`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +-- ---------------------------- +-- Records of card +-- ---------------------------- +INSERT INTO `card` VALUES ('1', 'this is cardno'); + +-- ---------------------------- +-- Function structure for `fristPinyin` +-- ---------------------------- +DROP FUNCTION IF EXISTS `fristPinyin`; +DELIMITER ;; +CREATE DEFINER=`root`@`%` FUNCTION `fristPinyin`(P_NAME VARCHAR(255)) RETURNS varchar(255) CHARSET utf8 +BEGIN + DECLARE V_RETURN VARCHAR(255); + SET V_RETURN = ELT(INTERVAL(CONV(HEX(left(CONVERT(P_NAME USING gbk),1)),16,10), + 0xB0A1,0xB0C5,0xB2C1,0xB4EE,0xB6EA,0xB7A2,0xB8C1,0xB9FE,0xBBF7, + 0xBFA6,0xC0AC,0xC2E8,0xC4C3,0xC5B6,0xC5BE,0xC6DA,0xC8BB, + 0xC8F6,0xCBFA,0xCDDA,0xCEF4,0xD1B9,0xD4D1), + 'A','B','C','D','E','F','G','H','J','K','L','M','N','O','P','Q','R','S','T','W','X','Y','Z'); + RETURN V_RETURN; +END +;; +DELIMITER ; + +CREATE TABLE if not exists `statistics` ( + `usertotal` bigint(20) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + +--触发器测试 +DROP TRIGGER IF EXISTS tri_countUserTotal; +CREATE TRIGGER tri_countUserTotal AFTER +INSERT ON USER +FOR EACH ROW BEGIN DECLARE c int; +SET c = + (SELECT count(*) + FROM USER); +UPDATE STATISTICS +SET usertotal = c; END; +update statistics set usertotal=0; + +CREATE DEFINER=`root`@`%` PROCEDURE `insert_touser`(in start int(10),in max_num int(10)) +begin +declare i int default 0; + -- set autocommit =0 把autocommit设置成0 不自动提交,循环完统一提交 + set autocommit = 0; + repeat + set i = i + 1; + insert into user(name,phone,adddate) values ((start+i),'test',UNIX_TIMESTAMP(NOW())); + until i = max_num + end repeat; + commit; + end + -- 添加1w个用户 +call insert_touser(1,10000); +-- 锁表 +lock tables user read; +lock tables user write; +unlock tables; \ No newline at end of file diff --git a/help/logback.sql b/help/logback.sql new file mode 100644 index 00000000..b1c47ea2 --- /dev/null +++ b/help/logback.sql @@ -0,0 +1,34 @@ +CREATE TABLE logging_event + ( + timestmp BIGINT NOT NULL, + formatted_message TEXT NOT NULL, + logger_name VARCHAR(254) NOT NULL, + level_string VARCHAR(254) NOT NULL, + thread_name VARCHAR(254), + reference_flag SMALLINT, + arg0 VARCHAR(254), + arg1 VARCHAR(254), + arg2 VARCHAR(254), + arg3 VARCHAR(254), + caller_filename VARCHAR(254) NOT NULL, + caller_class VARCHAR(254) NOT NULL, + caller_method VARCHAR(254) NOT NULL, + caller_line CHAR(4) NOT NULL, + event_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY + ); +CREATE TABLE logging_event_property + ( + event_id BIGINT NOT NULL, + mapped_key VARCHAR(254) NOT NULL, + mapped_value TEXT, + PRIMARY KEY(event_id, mapped_key), + FOREIGN KEY (event_id) REFERENCES logging_event(event_id) + ); +CREATE TABLE logging_event_exception + ( + event_id BIGINT NOT NULL, + i SMALLINT NOT NULL, + trace_line VARCHAR(254) NOT NULL, + PRIMARY KEY(event_id, i), + FOREIGN KEY (event_id) REFERENCES logging_event(event_id) + ); \ No newline at end of file diff --git a/help/mysql-util.sql b/help/mysql-util.sql new file mode 100644 index 00000000..f7c64bae --- /dev/null +++ b/help/mysql-util.sql @@ -0,0 +1,32 @@ +-- 查询select次数 +show GLOBAL status like 'com_select'; +-- 查询insert次数 +show GLOBAL status like 'com_insert'; +-- 查询update次数 +show GLOBAL status like 'com_update'; +-- 查询delete次数 +show GLOBAL status like 'com_delete'; +-- 查询活跃连接 +show status like 'connections'; +-- 查询慢查询次数 +show global status like 'slow_queries'; +-- 查询慢查询设置 +show variables like 'long_query_time'; +-- 锁表/解锁使用http://www.111cn.net/database/mysql/55482.htm +-- 锁定数据表,避免在备份过程中,表被更新,这个时候insert update delete等操作会阻塞,直到UNLOCK TABLES;其它线程可以读不可写 +LOCK TABLES user READ; +-- 当前线程拥有读写权限,其它线程不能进行读写 +LOCK TABLES user WRITE; +-- 解锁表,释放当前线程加的锁 +UNLOCK TABLES; + +-- mysql行级锁 +-- 启两个控制台窗口,执行,update都会成功 +SELECT * FROM user WHERE id=2 FOR UPDATE; +update user set sex='男' where id=2; +--for update要放在一个事务中,这时候其它线程写操作会阻塞掉,普通select可以执行,执行select.. WHERE id=2 FOR UPDATE会被阻塞掉 +begin + SELECT * FROM user WHERE id=2 FOR UPDATE; + update user set sex='女' where id=2; +commit; +end \ No newline at end of file diff --git a/pom.xml b/pom.xml index d5538db0..90725635 100644 --- a/pom.xml +++ b/pom.xml @@ -1,12 +1,13 @@ 4.0.0 - cn.com.ttblog.ssmbootstrap-table + cn.netbuffer.ssmbootstrap-table ssmbootstrap_table war 0.0.1-SNAPSHOT ssmbootstrap_table Maven Webapp http://netbuffer.github.io + netbuffer @@ -15,14 +16,31 @@ http://netbuffer.github.io + + + https://github.com/netbuffer/ssmbootstrap_table/ + scm:git:git://github.com/netbuffer/ssmbootstrap_table.git + scm:git:ssh://git@github.com:netbuffer/ssmbootstrap_table.git + + + + Github + https://github.com/netbuffer/ssmbootstrap_table/issues + + - 4.0.2.RELEASE + 4.3.21.RELEASE 3.3.0 1.7.7 1.1.3 + 1.10.19 + 5.5.9 + 1.9.2 + UTF-8 + com.thoughtworks.xstream xstream @@ -96,6 +114,7 @@ spring-test ${spring.version} + org.mybatis mybatis @@ -106,20 +125,34 @@ mybatis-spring 1.2.2 + + org.mybatis + mybatis-ehcache + 1.0.0 + + + + + org.aspectj + aspectjrt + 1.8.6 + + + org.aspectj + aspectjweaver + 1.8.6 + mysql mysql-connector-java 5.1.38 - commons-dbcp - commons-dbcp - 1.2.2 - - - jstl - jstl - 1.2 + com.alibaba + druid + 1.0.21 javax.servlet.jsp @@ -132,10 +165,16 @@ logback-classic ${logback.version} + + + org.slf4j + jcl-over-slf4j + 1.7.12 + com.alibaba fastjson - 1.1.41 + 1.2.83 org.slf4j @@ -163,9 +202,9 @@ 1.9.2 - commons-lang - commons-lang - 2.6 + org.apache.commons + commons-lang3 + 3.4 commons-codec @@ -182,15 +221,296 @@ poi 3.13 + + javax.validation + validation-api + 1.1.0.Final + + + org.hibernate + hibernate-validator + 5.2.4.Final + + + + com.belerweb + pinyin4j + 2.5.1 + + + joda-time + joda-time + 2.9.2 + + + + com.fasterxml.jackson.core + jackson-databind + 2.9.7 + + + org.projectlombok + lombok + 1.16.8 + + + + + com.github.js-cookie + java-cookie + 0.0.2 + + + + de.danielbechler + java-object-diff + 0.93.1 + + + + + org.lazyluke + log4jdbc-remix + 0.2.7 + + + + org.bgee.log4jdbc-log4j2 + log4jdbc-log4j2-jdbc4.1 + 1.16 + + + net.sf.ehcache + ehcache + 2.10.4 + + + net.sf.ehcache + ehcache-web + 2.0.4 + + + + com.ryantenney.metrics + metrics-spring + 3.1.3 + + + io.dropwizard.metrics + metrics-jvm + 3.1.2 + + + com.codahale.metrics + metrics-servlets + 3.0.2 + + + com.codahale.metrics + metrics-healthchecks + 3.0.2 + + + javax.transaction + jta + 1.1 + + + org.json + json + 20160212 + + + io.springfox + springfox-swagger2 + 2.5.0 + + + + io.springfox + springfox-swagger-ui + 2.5.0 + + + javax.websocket + javax.websocket-api + 1.1 + provided + + + org.springframework + spring-websocket + ${spring.version} + + + org.springframework + spring-messaging + ${spring.version} + + + + com.thetransactioncompany + cors-filter + 2.5 + + + com.google.zxing + core + 3.2.1 + + + com.google.zxing + javase + 3.2.1 + + + + org.apache.tomcat.embed + tomcat-embed-websocket + 7.0.52 + test + + + net.coobird + thumbnailator + 0.4.8 + + + + com.itextpdf + itextpdf + ${itextpdf.version} + + + com.itextpdf + itext-asian + 5.2.0 + + + org.mockito + mockito-all + ${mockito.version} + + + net.sourceforge.jwebunit + jwebunit-core + 3.3 + + + + javax.servlet + servlet-api + + + + + eu.bitwalker + UserAgentUtils + 1.20 + + + org.jsoup + jsoup + ${jsoup.version} + + + + + offical + Maven Official Repository + http://repo1.maven.org/maven2 + + false + + + + aliyun + aliyun + http://maven.aliyun.com/nexus/content/groups/public/ + + true + + + + spring-milestones + Spring Milestones + http://repo.spring.io/milestone + + false + + + + tomcat-snapshots + https://repository.apache.org/content/repositories/snapshots + + true + + + false + + + + java-net + https://maven.java.net/content/repositories/releases + + + + + + src/main/resources + + **/*.properties + **/*.xml + + true + + + src/main/java + + **/*.properties + **/*.xml + + true + + ssmbootstrap_table + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + 1.7 + 1.7 + + org.apache.tomcat.maven tomcat7-maven-plugin 2.2 + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + + org.apache.maven.plugins + maven-changelog-plugin + 2.3 + + + + org.apache.maven.plugins + maven-site-plugin + 3.5.1 + - + \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/IndexController.java b/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/IndexController.java deleted file mode 100644 index 7383be52..00000000 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/IndexController.java +++ /dev/null @@ -1,128 +0,0 @@ -package cn.com.ttblog.ssmbootstrap_table.controller; - -import java.io.File; -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.ArrayList; -import java.util.Date; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Resource; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; - -import org.apache.commons.io.FileUtils; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpStatus; -import org.springframework.http.MediaType; -import org.springframework.http.ResponseEntity; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.ResponseBody; - -import com.alibaba.fastjson.JSONArray; - -import cn.com.ttblog.ssmbootstrap_table.model.User; -import cn.com.ttblog.ssmbootstrap_table.service.IUserService; -import cn.com.ttblog.ssmbootstrap_table.util.BeanMapUtil; -import cn.com.ttblog.ssmbootstrap_table.util.POIExcelUtil; - -@Controller -@RequestMapping("/") -public class IndexController { - - @Resource - private IUserService userService; - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @RequestMapping("/login") - public String login(HttpSession session, HttpServletRequest request, - HttpServletResponse response, String username, String password) { - logger.info("进入username:{},pwd:{}", username, password); - if (username.equals(ConfigConstant.VAL_USERNAME) - && password.equals(ConfigConstant.VAL_PWD)) { - session.setAttribute(ConfigConstant.ISLOGIN, true); - session.setAttribute(ConfigConstant.USERNAME, username); - Cookie c = new Cookie(ConfigConstant.USERNAME, username); - c.setMaxAge(86400); - response.addCookie(c); - return "redirect:/manage.html"; - } else { - return "redirect:/index.html"; - } - } - - @RequestMapping("/newdata") - public String newdata(HttpSession session,Model model) { - logger.info("执行前:{}",model); - int newcount = userService.getNewData(); - String username = session.getAttribute(ConfigConstant.USERNAME) - .toString(); - model.addAttribute("newcount", newcount); - model.addAttribute("username", username); - logger.info("执行后:{}",model); - return "newdata"; - } - - @RequestMapping("/datacount") - public @ResponseBody Map datacount(HttpSession session,Model model) { - List> counts = userService.getDataSum(); - - JSONArray categorys=new JSONArray(); - JSONArray nums=new JSONArray(); - for(Map m:counts){ - categorys.add(m.get("adddate").toString()); - nums.add(m.get("num").toString()); - } - Map data=new HashMap(); - data.put("c", categorys); - data.put("d", nums); - return data; - } - - @RequestMapping("/export") - public ResponseEntity export(HttpSession session, HttpServletRequest request, - HttpServletResponse response) { - SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); - List users = userService.getUserList("desc", 10, 0); - String projectPath = request.getServletContext().getRealPath("export")+File.separator; - int userCount = users.size(); - List> mps = new ArrayList>( - users.size()); - for (int i = 0; i < userCount; i++) { - Map m = BeanMapUtil.transBean2Map(users.get(i)); - mps.add(m); - } - logger.info("users:{}", mps); - List titles = new ArrayList(mps.get(0).size() - 1); - titles.add("adddate"); - titles.add("age"); - titles.add("deliveryaddress"); - titles.add("id"); - titles.add("name"); - titles.add("phone"); - titles.add("sex"); - String file = projectPath + format.format(new Date()) + "." - + ConfigConstant.EXCELSTR; - logger.info("文件路径:{}",file); - POIExcelUtil.export(titles, mps, file); - HttpHeaders headers = new HttpHeaders(); - headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); - headers.setContentDispositionFormData("attachment",file.replace(projectPath, "")); - try { - return new ResponseEntity(FileUtils.readFileToByteArray(new File(file)), - headers, HttpStatus.CREATED); - } catch (IOException e) { - e.printStackTrace(); - } - return null; - } -} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/RegisterController.java b/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/RegisterController.java deleted file mode 100644 index 7670bf4d..00000000 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/RegisterController.java +++ /dev/null @@ -1,39 +0,0 @@ -package cn.com.ttblog.ssmbootstrap_table.controller; - -import javax.annotation.Resource; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.web.bind.annotation.RequestMapping; - -import cn.com.ttblog.ssmbootstrap_table.model.User; -import cn.com.ttblog.ssmbootstrap_table.service.IUserService; - -@Controller -@RequestMapping("/register") -public class RegisterController { - - @Resource - private IUserService userService; - - private Logger logger = LoggerFactory.getLogger(this.getClass()); - - @RequestMapping(value={"/index","/"}) - public String index() { - return "redirect:/register.html"; - } - - @RequestMapping("/save") - public String save(User user) { - user.setAdddate((int)(System.currentTimeMillis()/1000)); - try { - userService.addUser(user); - } catch (Exception e) { - e.printStackTrace(); - return "redirect:/register-error.html"; - } - return "redirect:/register-success.html"; - } - -} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/UserController.java b/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/UserController.java deleted file mode 100644 index 6182a4ab..00000000 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/UserController.java +++ /dev/null @@ -1,94 +0,0 @@ -package cn.com.ttblog.ssmbootstrap_table.controller; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import javax.annotation.Resource; -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.stereotype.Controller; -import org.springframework.ui.Model; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RequestMethod; -import org.springframework.web.bind.annotation.ResponseBody; -import org.springframework.web.servlet.ModelAndView; - -import cn.com.ttblog.ssmbootstrap_table.model.User; -import cn.com.ttblog.ssmbootstrap_table.service.IUserService; - -@Controller -@RequestMapping("/user") -public class UserController { - - @Resource - private IUserService userService; - - private Logger logger=LoggerFactory.getLogger(this.getClass()); - - @RequestMapping("/showUser/{id}") - public String toIndex(@PathVariable("id") int id,HttpServletRequest request, Model model) { - logger.info("进入:{},参数:{}",request.getRequestURI(),model.toString()); - int userId = id; - User user = userService.getUserById(userId); - model.addAttribute("user", user); - return "su"; - } - - @RequestMapping("/testmodel") - public ModelAndView model() { - ModelAndView mav=new ModelAndView(); - User u=new User(); - u.setName("tianyu"); - u.setAge(11); - u.setDeliveryaddress("收货地址"); - mav.addObject("model", u); - return mav; - } - - /** - * http://localhost:8080/ssmbootstrap_table/user/userlist?order=asc&limit=10&offset=0 - * @param order - * @param limit - * @param offset - * @param model - * @return - */ - @RequestMapping("/userlist") - public String userlist(String order,int limit,int offset, Model model) { - logger.info("参数:{},{},{}",order,limit,offset); - List users = userService.getUserList(order,limit,offset); - long total=userService.getUserListCount(); - Map params=new HashMap(); - model.addAttribute("total",total); - model.addAttribute("rows", users); - logger.info("结果:{}",params); - return "userlist"; - } - - @RequestMapping("/showUserXML") - public ModelAndView showUserXML(HttpServletRequest request, Model model) { - ModelAndView mav = new ModelAndView("xStreamMarshallingView"); - int userId = Integer.parseInt("1"); - User user = userService.getUserById(userId); - return mav; - } - - @RequestMapping(method = RequestMethod.GET, value = "/u/{id}", headers = "Accept=application/json") - public @ResponseBody User getEmp(@PathVariable String id) { - User e = userService.getUserById(1); - return e; - } - - @RequestMapping(method = RequestMethod.GET, value = "/us", headers = "Accept=application/json") - public @ResponseBody List ListinggetAllEmp() { - List us = new ArrayList(); - us.add(userService.getUserById(1)); - us.add(userService.getUserById(2)); - return us; - } -} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/LoginFilter.java b/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/LoginFilter.java deleted file mode 100644 index 72badd79..00000000 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/LoginFilter.java +++ /dev/null @@ -1,103 +0,0 @@ -package cn.com.ttblog.ssmbootstrap_table.filter; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -import org.apache.commons.lang.builder.ToStringBuilder; - -import cn.com.ttblog.ssmbootstrap_table.Constant.ConfigConstant; - - -public class LoginFilter implements Filter { - - private FilterConfig filterConfig; - - @Override - public void init(FilterConfig filterConfig) throws ServletException { - this.filterConfig = filterConfig; - } - - @Override - public void doFilter(ServletRequest servletRequest, - ServletResponse servletResponse, FilterChain filterChain) - throws IOException, ServletException { - HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; - HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; - - String noFilterTagString = filterConfig - .getInitParameter("noFilterTags"); - boolean enable=Boolean.parseBoolean(filterConfig.getInitParameter("enable")); - //不起用的情况下直接通过 - if(!enable){ - filterChain.doFilter(httpServletRequest, - httpServletResponse); - return ; - } - String[] noFilterTags = noFilterTagString.split(";"); - - String uri = httpServletRequest.getRequestURI(); - System.out.println("过滤路径:"+uri); - // 配置文件中允许放行的关键字 - if (noFilterTags != null) { - for (String noFilterTag : noFilterTags) { - if (noFilterTag == null || "".equals(noFilterTag.trim())) { - continue; - } - if (uri.indexOf(noFilterTag.trim()) != -1) { - System.out.println("uri:"+uri); - filterChain.doFilter(httpServletRequest, - httpServletResponse); - return; - } - } - } - - Cookie[] cookies=httpServletRequest.getCookies(); - System.out.println("path:"+uri); - Object islogin=httpServletRequest.getSession().getAttribute(ConfigConstant.ISLOGIN); - if ( islogin!= null&&Boolean.parseBoolean(islogin.toString())) { - System.out.println("p1"); - if(uri.endsWith(ConfigConstant.PROJECTNAME+"/")){ - httpServletResponse.sendRedirect(httpServletRequest - .getContextPath() + "/manage.html"); - }else{ - filterChain.doFilter(httpServletRequest, httpServletResponse); - } - } else if(cookies!=null){ - System.out.println("p2"); - for(Cookie cookie:cookies){ - if(cookie.getName().equals(ConfigConstant.USERNAME)){ - System.out.println("cookie:"+ToStringBuilder.reflectionToString(cookie)); - httpServletRequest.getSession().setAttribute(ConfigConstant.ISLOGIN, true); - httpServletRequest.getSession().setAttribute(ConfigConstant.USERNAME, cookie.getValue()); - if(uri.endsWith(ConfigConstant.PROJECTNAME+"/")){ - httpServletResponse.sendRedirect(httpServletRequest - .getContextPath() + "/manage.html"); - }else{ - filterChain.doFilter(httpServletRequest, httpServletResponse); - } - return ; - } - } - httpServletResponse.sendRedirect(httpServletRequest - .getContextPath() + "/index.html"); - }else{ - System.out.println("^^^"); - } - - } - - @Override - public void destroy() { - - } -} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/service/IUserService.java b/src/main/java/cn/com/ttblog/ssmbootstrap_table/service/IUserService.java deleted file mode 100644 index 9a633aa1..00000000 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/service/IUserService.java +++ /dev/null @@ -1,15 +0,0 @@ -package cn.com.ttblog.ssmbootstrap_table.service; - -import java.util.List; -import java.util.Map; - -import cn.com.ttblog.ssmbootstrap_table.model.User; - -public interface IUserService { - public User getUserById(long userId); - public void addUser(User user); - public List getUserList(String order, int limit, int offset); - public long getUserListCount(); - public int getNewData(); - public List> getDataSum(); -} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/serviceimpl/UserServiceImpl.java b/src/main/java/cn/com/ttblog/ssmbootstrap_table/serviceimpl/UserServiceImpl.java deleted file mode 100644 index 2c34e423..00000000 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/serviceimpl/UserServiceImpl.java +++ /dev/null @@ -1,66 +0,0 @@ -package cn.com.ttblog.ssmbootstrap_table.serviceimpl; - -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.Random; - -import javax.annotation.Resource; - -import org.mybatis.spring.SqlSessionTemplate; -import org.springframework.stereotype.Service; -import org.springframework.transaction.annotation.Transactional; - -import cn.com.ttblog.ssmbootstrap_table.dao.IUserDao; -import cn.com.ttblog.ssmbootstrap_table.model.User; -import cn.com.ttblog.ssmbootstrap_table.service.IUserService; - -@Service("userService") -public class UserServiceImpl implements IUserService { - /** - * @resource 是按照name注入,@autowired是按照type注入 - */ - @Resource - private IUserDao userDao; - @Resource - private SqlSessionTemplate sqlSession; - @Override - public User getUserById(long userId) { - return this.userDao.selectByPrimaryKey(userId); - } - - @Transactional - @Override - public void addUser(User user) { - Random r=new Random(); - sqlSession.insert(IUserDao.class.getName()+".insert",user); - //事务测试 -// if(r.nextInt(6)==0){ -// int i=1/0; -// } - } - - @Override - public List getUserList(String order, int limit, int offset) { - Map params=new HashMap(); - params.put("order", order); - params.put("limit", limit); - params.put("offset", offset); - return sqlSession.selectList(IUserDao.class.getName()+".selectList",params); - } - - @Override - public long getUserListCount() { - return userDao.getUserListCount(); - } - - @Override - public int getNewData() { - return userDao.getNewData(); - } - - @Override - public List> getDataSum() { - return userDao.getDataSum(); - } -} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/annotation/Token.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/annotation/Token.java new file mode 100644 index 00000000..16837a16 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/annotation/Token.java @@ -0,0 +1,25 @@ +package cn.netbuffer.ssmbootstrap_table.annotation; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +/** + * 表单重复提交问题 + * http://www.oschina.net/question/1539369_2154772?fromerr=aQTSxo9I + */ +@Target(ElementType.METHOD) +@Retention(RetentionPolicy.RUNTIME) +public @interface Token { + boolean save() default false; + boolean remove() default false; + /** + * 默认值token + * @return + */ + String tokenname() default "token"; + /** + * 校验不通过后跳转url + */ + String failuri() default "error"; +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/aop/ControllerAspect.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/aop/ControllerAspect.java new file mode 100644 index 00000000..ac31829d --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/aop/ControllerAspect.java @@ -0,0 +1,68 @@ +package cn.netbuffer.ssmbootstrap_table.aop; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@Aspect +public class ControllerAspect { + + private static final Logger LOG = LoggerFactory + .getLogger(ControllerAspect.class); + + @Pointcut("execution(* cn.netbuffer.ssmbootstrap_table.controller..*.*(..))") + public void pointCut() { + } + + @After("pointCut()") + public void after(JoinPoint joinPoint) { + } + + @Before("pointCut()") + public void before(JoinPoint joinPoint) { + // Object[] args = joinPoint.getArgs(); + LOG.warn("控制器切面参数 param:{}", + ToStringBuilder.reflectionToString(joinPoint)); + Object[] arr = joinPoint.getArgs(); + if (arr.length > 0) { + LOG.warn("method param:{}", + ToStringBuilder.reflectionToString(joinPoint.getArgs()[0])); + } + } + + @AfterReturning(pointcut = "pointCut()", returning = "returnVal") + public void afterReturning(JoinPoint joinPoint, Object returnVal) { + } + + @Around("pointCut()") + public Object around(ProceedingJoinPoint pjp) throws Throwable { + Object obj = null; + long startTime = System.nanoTime(); + long endTime; + try { + obj = pjp.proceed(); + endTime = System.nanoTime(); + } catch (Throwable ex) { + throw ex; + } + LOG.warn(pjp.getSignature() + "-time consume is " + + (endTime - startTime) / 1000 / 1000 / 1000 * 0.1 + "s"); + return obj; + } + + @AfterThrowing(pointcut = "pointCut()", throwing = "error") + public void afterThrowing(JoinPoint jp, Throwable error) { + LOG.error("控制器发生错误:" + error); + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/aop/SimpleAspect.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/aop/SimpleAspect.java new file mode 100644 index 00000000..5d2868be --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/aop/SimpleAspect.java @@ -0,0 +1,69 @@ +package cn.netbuffer.ssmbootstrap_table.aop; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.aspectj.lang.JoinPoint; +import org.aspectj.lang.ProceedingJoinPoint; +import org.aspectj.lang.annotation.After; +import org.aspectj.lang.annotation.AfterReturning; +import org.aspectj.lang.annotation.AfterThrowing; +import org.aspectj.lang.annotation.Around; +import org.aspectj.lang.annotation.Aspect; +import org.aspectj.lang.annotation.Before; +import org.aspectj.lang.annotation.Pointcut; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Component; + +@Component +@Aspect +public class SimpleAspect { + private Logger log = LoggerFactory.getLogger(getClass()); + //http://jinnianshilongnian.iteye.com/blog/1415606 切入点语法 + @Pointcut("execution(* cn.netbuffer.ssmbootstrap_table.service.*Service*.*(..))") + public void pointCut() { + } + + @After("pointCut()") + public void after(JoinPoint joinPoint) { + log.warn("after aspect executed"); + } + + @Before("pointCut()") + public void before(JoinPoint joinPoint) { + // 如果需要这里可以取出参数进行处理 + // Object[] args = joinPoint.getArgs(); + log.warn("before aspect executing param:{}",ToStringBuilder.reflectionToString(joinPoint)); + Object[] arr=joinPoint.getArgs(); + if(arr.length>0){ + log.warn("method param:{}",ToStringBuilder.reflectionToString(joinPoint.getArgs()[0])); + } + } + + @AfterReturning(pointcut = "pointCut()", returning = "returnVal") + public void afterReturning(JoinPoint joinPoint, Object returnVal) { + log.warn("afterReturning executed, return result is " + returnVal); + } + + @Around("pointCut()") + public Object around(ProceedingJoinPoint pjp) throws Throwable { + log.warn("around start.."); + Object obj = null; + long startTime=System.nanoTime(); + long endTime; + try { + obj = pjp.proceed(); + endTime=System.nanoTime(); + } catch (Throwable ex) { + log.warn("error in around"); + throw ex; + } + log.warn("around end"); + log.warn(pjp.getSignature()+"-time consume is " + (endTime-startTime)/1000/1000/1000*0.1+"s"); + return obj; + } + + @AfterThrowing(pointcut = "pointCut()", throwing = "error") + public void afterThrowing(JoinPoint jp, Throwable error) { + log.error("error:" + error); + } +} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/Constant/ConfigConstant.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/constant/ConfigConstant.java similarity index 83% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/Constant/ConfigConstant.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/constant/ConfigConstant.java index be3eacc2..e08a373a 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/Constant/ConfigConstant.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/constant/ConfigConstant.java @@ -1,12 +1,12 @@ -package cn.com.ttblog.ssmbootstrap_table.Constant; - -public class ConfigConstant { - /** - * user表字符串 - */ - public static final String USERTABLE="user"; - public static final String ISLOGIN = "islogin"; - public static final String USERNAME = "username"; - public static final String EXCELSTR = "xls"; - public static final String PROJECTNAME = "ssmbootstrap_table"; -} +package cn.netbuffer.ssmbootstrap_table.constant; + +public class ConfigConstant { + /** + * user表字符串 + */ + public static final String USERTABLE="user"; + public static final String ISLOGIN = "islogin"; + public static final String USERNAME = "username"; + public static final String EXCELSTR = "xls"; + public static final String PROJECTNAME = "ssmbootstrap_table"; +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/ApiController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/ApiController.java new file mode 100644 index 00000000..01acb166 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/ApiController.java @@ -0,0 +1,31 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RestController; +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; + +/** + * Restful Controller, 直接输出内容,不调用template引擎 + * @package cn.netbuffer.ssmbootstrap_table.controller + * @author netbuffer + */ +@RestController +@RequestMapping("/restapi") +public class ApiController { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + @Autowired + private IUserService userService; + + @RequestMapping(value = { "", "/{id}", "/index/{id}" },method=RequestMethod.GET) + public User index(@PathVariable("id") int id) { + logger.debug("restapi get user:",id); + return userService.getUserById(id); + } + +} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/ConfigConstant.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/ConfigConstant.java similarity index 86% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/ConfigConstant.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/controller/ConfigConstant.java index 71c20c9f..dfefab06 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/controller/ConfigConstant.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/ConfigConstant.java @@ -1,14 +1,14 @@ -package cn.com.ttblog.ssmbootstrap_table.controller; - -public class ConfigConstant { - /** - * user表字符串 - */ - public static final String USERTABLE="user"; - public static final String ISLOGIN = "islogin"; - public static final String USERNAME = "username"; - public static final String EXCELSTR = "xls"; - public static final String PROJECTNAME = "jfinal-bootstrap-table"; - public static final String VAL_USERNAME = "admin"; - public static final String VAL_PWD = "admin"; -} +package cn.netbuffer.ssmbootstrap_table.controller; + +public class ConfigConstant { + /** + * user表字符串 + */ + public static final String USERTABLE="user"; + public static final String ISLOGIN = "islogin"; + public static final String USERNAME = "username"; + public static final String EXCELSTR = "xls"; + public static final String PROJECTNAME = "jfinal-bootstrap-table"; + public static final String VAL_USERNAME = "admin"; + public static final String VAL_PWD = "admin"; +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/CookieController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/CookieController.java new file mode 100644 index 00000000..9bf27e4f --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/CookieController.java @@ -0,0 +1,150 @@ +package cn.netbuffer.ssmbootstrap_table.controller; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import com.github.jscookie.javacookie.Cookies; + +@RestController +@RequestMapping("/cookie") +public class CookieController { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @RequestMapping("/cookies") + public Cookies cookies(HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + Cookies cookies=Cookies.initFromServlet(request, response); + logger.debug("cookies:{}",cookies.get()); + return cookies; + } + /** + * 添加httponly cookie + * @param name + * @param session + * @param request + * @param response + * @return + */ + @RequestMapping("/addh/{name}") + public boolean addh(@PathVariable("name") String name,HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + Cookie c=new Cookie(name, name); +// c.setComment("purpose"); + c.setHttpOnly(true); + c.setMaxAge(3600); +// c.setDomain("localhost"); +// c.setPath("/ssmbootstrap_table"); + response.addCookie(c); + logger.debug("addh cookie:{}",ToStringBuilder.reflectionToString(c)); + return true; + } + + + @RequestMapping("/add/{name}") + public boolean add(@PathVariable("name") String name,HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + Cookie c=new Cookie(name, name); + c.setComment("purpose"); + c.setMaxAge(3600); + response.addCookie(c); + logger.debug("add cookie:{}",ToStringBuilder.reflectionToString(c)); + return true; + } + + /** + * 删除http only cookie,必须保证和添加的cookie参数是一致的才能删除成功 + * @param name + * @param session + * @param request + * @param response + * @return + */ + @RequestMapping("/delh/{name}") + public boolean delh(@PathVariable("name") String name,HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + Cookie[] cookies=request.getCookies(); + Cookie s=null; + for(Cookie c:cookies){ + if(c.getName().equals(name)){ + s=c; + break; + } + } + logger.debug("delh cookie:{},cookie:{}",name,ToStringBuilder.reflectionToString(s)); + if(s!=null){ + //清除cookie + Cookie c=new Cookie(s.getName(), s.getValue()); +// c.setComment("purpose"); + c.setHttpOnly(true); + c.setMaxAge(0); +// c.setDomain("localhost"); +// c.setPath("/ssmbootstrap_table"); +// s.setValue(""); +// s.setMaxAge(0); +// s.setHttpOnly(true); + response.addCookie(c); + } + return true; + } + + @RequestMapping("/del/{name}") + public boolean del(@PathVariable("name") String name,HttpSession session, HttpServletRequest request, + HttpServletResponse response) { + Cookie[] cookies=request.getCookies(); + Cookie s=null; + for(Cookie c:cookies){ + if(c.getName().equals(name)){ + s=c; + break; + } + } + logger.debug("del cookie:{},cookie:{}",name,ToStringBuilder.reflectionToString(s)); + if(s!=null){ + //清除cookie + s.setValue(""); + s.setMaxAge(0); + response.addCookie(s); + } + return true; + } + + /** + * 测试清除tomcat中JSESSIONID + * @param request + * @param response + * @return + */ + @RequestMapping("/delsession") + public boolean delJsessionid(HttpServletRequest request, + HttpServletResponse response) { + Cookie[] cookies=request.getCookies(); + Cookie s=null; + for(Cookie c:cookies){ + if(c.getName().equals("JSESSIONID")){ + s=c; + break; + } + } + logger.debug("JSESSIONID:{}",ToStringBuilder.reflectionToString(s)); + if(s!=null){ + //清除cookie + s.setValue(""); + s.setMaxAge(0); + s.setDomain("localhost"); + s.setPath("/ssmbootstrap_table/"); + s.setHttpOnly(true); + response.addCookie(s); + } + return true; + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/EhcacheController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/EhcacheController.java new file mode 100644 index 00000000..34efd16c --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/EhcacheController.java @@ -0,0 +1,76 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import java.util.Arrays; + +import net.sf.ehcache.Element; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Controller; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import net.sf.ehcache.Cache; +import net.sf.ehcache.CacheManager; +import org.springframework.web.bind.annotation.ResponseBody; + +/** + * 浏览ehcache状态 + */ +@Controller +@RequestMapping("/ehcache") +public class EhcacheController { + private Logger logger = LoggerFactory.getLogger(this.getClass()); +// @Autowired +// private ApplicationContext applicationContext; + @Autowired + private CacheManager cacheManager; + + @RequestMapping(value = {"/index/{cache}" }) + public String index(@PathVariable("cache") String cache, ModelMap m) { + logger.debug("cache:{}", cache); + if(cacheManager!=null){ + m.put("caches",Arrays.deepToString(cacheManager.getCacheNames())); + m.put("getDiskStorePath", cacheManager.getDiskStorePath()); + m.put("getName", cacheManager.getName()); + m.put("getOriginalConfigurationText", cacheManager.getOriginalConfigurationText()); + m.put("getStatus", cacheManager.getStatus()); + Cache c=cacheManager.getCache(cache); + if(c!=null){ + m.put("getStatistics",c.getStatistics()); + logger.debug("ehcache-{} getStatistics:{}",cache,c.getStatistics()); + } + } + logger.debug("ehcache model:{}",m); + return "ehcache"; + } + + /** + * put到指定cache下 + * @param cacheName + * @param key + * @param val + * @return + */ + @RequestMapping(value = {"/putcache/{cache}/{key}/{val}" }) + @ResponseBody + public Element put(@PathVariable("cache") String cacheName,@PathVariable("key") String key,@PathVariable("val") String val) { + Cache cache=cacheManager.getCache(cacheName); + Element element=new Element(key,val); + cache.put(element); + return element; + } + + /** + * 获取指定cache下的指定key内容 + * @param cacheName + * @param key + * @return + */ + @RequestMapping(value = {"/getcache/{cache}/{key}" }) + @ResponseBody + public Element get(@PathVariable("cache") String cacheName,@PathVariable("key") String key) { + Cache cache=cacheManager.getCache(cacheName); + return cache.get(key); + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/FileUploadController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/FileUploadController.java new file mode 100644 index 00000000..a17bb9bb --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/FileUploadController.java @@ -0,0 +1,111 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import cn.netbuffer.ssmbootstrap_table.model.FileMsgBean; +import cn.netbuffer.ssmbootstrap_table.util.AjaxUtils; +import net.coobird.thumbnailator.Thumbnails; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.WebRequest; +import org.springframework.web.multipart.MultipartFile; +import org.springframework.web.multipart.MultipartHttpServletRequest; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.File; +import java.io.IOException; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +@Controller +@RequestMapping("/fileupload") +public class FileUploadController { + + private static final Logger log=LoggerFactory.getLogger(FileUploadController.class); + + @ModelAttribute + public void ajaxAttribute(WebRequest request, Model model) { + model.addAttribute("ajaxRequest", AjaxUtils.isAjaxRequest(request)); + } + + @RequestMapping(method=RequestMethod.GET) + public String fileUploadForm() { + return "/user/photos"; + } + + @RequestMapping(value="/upload",method=RequestMethod.POST) + public void processUpload(@RequestParam(value = "file") MultipartFile file, Model model) throws IOException { + log.info("文件上传信息:{}",ToStringBuilder.reflectionToString(file)); + log.info("文件上传,存储路径:{}",System.getProperty("webapp.root")+file.getOriginalFilename()); + file.transferTo(new File(System.getProperty("webapp.root")+file.getOriginalFilename())); + model.addAttribute("message", "File '" + file.getOriginalFilename() + "' uploaded successfully"); + } + + @RequestMapping(value="/ajaxupload",method=RequestMethod.POST) + @ResponseBody + public FileMsgBean ajaxUpload(@RequestParam MultipartFile file, HttpServletRequest request) throws IOException { + log.info("ajax文件上传信息:{}",ToStringBuilder.reflectionToString(file)); + String dir=System.getProperty("webapp.root")+File.separator+"image"+File.separator; + String originName=file.getOriginalFilename(); + String ext=originName.split("\\.")[1]; + log.info("file.getName():{},file.getOriginalFilename():{},originName.split(\".\"):{}",file.getName(),file.getOriginalFilename(),Arrays.deepToString(originName.split("\\."))); + String usedName=Base64.encodeBase64String(originName.getBytes())+"."+ext; + String saveImagePath=dir+usedName; + String host=request.getHeader("host"); + String contextPath=request.getContextPath(); + String accessRelativeUrl=request.getScheme()+"://"+host+contextPath+"/image/"; + String imageUrl=accessRelativeUrl+usedName; + log.info("host:{},contextPath:{},saveImagePath:{}",host,contextPath,saveImagePath); + //缩率图 + File saveFile=new File(saveImagePath); + log.info("ajax文件上传:{},存储路径:{},url:{}--name:{}",file,saveImagePath,imageUrl,file.getName()); + file.transferTo(saveFile); + String thumbFileName=Base64.encodeBase64String((originName+"scale030").getBytes())+"."+ext; + Thumbnails.of(saveFile).scale(0.30f).toFile(dir+thumbFileName); + String thumbnailUrl=accessRelativeUrl+thumbFileName; + FileMsgBean bean=new FileMsgBean(); + bean.setName(file.getOriginalFilename()); + bean.setSize(file.getSize()); + bean.setUrl(imageUrl); + bean.setThumbnailUrl(thumbnailUrl); + bean.setDeleteUrl("no delete url"); + return bean; + } + + @RequestMapping(value="/multiupload", method = RequestMethod.POST) + public @ResponseBody List upload(MultipartHttpServletRequest request,@RequestParam(value = "multifile",required = false) MultipartFile[] files, HttpServletResponse response) { + log.debug("ajax多文件上传,files:{}",files); + String dir=System.getProperty("webapp.root")+File.separator+"image"+File.separator; +// int sleep=RandomUtils.nextInt(2, 6); +// log.debug("upload-sleep:{}s",sleep); +// try { +// TimeUnit.SECONDS.sleep(sleep); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } + String host=request.getHeader("host"); + String contextPath=request.getContextPath(); + String url=request.getScheme()+"://"+host+contextPath+"/image/"; + List beans=new ArrayList(2); + for(MultipartFile f:files){ + try { + f.transferTo(new File(dir+f.getOriginalFilename())); + } catch (IOException e) { + e.printStackTrace(); + } + FileMsgBean bean=new FileMsgBean(); + bean.setName(f.getName()); + bean.setSize(f.getSize()); + bean.setUrl(url+f.getOriginalFilename()); + bean.setThumbnailUrl(url+f.getOriginalFilename()); + bean.setDeleteUrl("no delete url"); + beans.add(bean); + } + return beans; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/GlobalExceptionController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/GlobalExceptionController.java new file mode 100644 index 00000000..21719a90 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/GlobalExceptionController.java @@ -0,0 +1,40 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.bind.annotation.ControllerAdvice; +import org.springframework.web.bind.annotation.ExceptionHandler; +import org.springframework.web.servlet.ModelAndView; + +import cn.netbuffer.ssmbootstrap_table.exception.CustomGenericException; + +/** + * @ExceptionHandler只能在一个controller上添加,标记所有controller需要使用@ControllerAdvice来全局处理异常 + * @author netbuffer + */ +@ControllerAdvice +public class GlobalExceptionController { + Logger log=LoggerFactory.getLogger(getClass()); + @ExceptionHandler(CustomGenericException.class) + public ModelAndView handleCustomException(CustomGenericException ex) { + log.error("发生错误1:{}",ToStringBuilder.reflectionToString(ex)); + ModelAndView model = new ModelAndView("error"); + model.addObject("errCode", ex.getErrCode()); + model.addObject("errMsg", ex.getErrMsg()); + return model; + + } + + @ExceptionHandler(Exception.class) + public ModelAndView handleAllException(Exception ex){ + log.error("发生错误2:{}\r\nstacktrace:{}",ToStringBuilder.reflectionToString(ex),ex.getStackTrace()); + ModelAndView model = new ModelAndView("error"); + model.addObject("errMsg",ex.getMessage()); + model.addObject("stackTrace",ExceptionUtils.getStackTrace(ex)); + model.addObject("ex",ex); + return model; + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/IndexController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/IndexController.java new file mode 100644 index 00000000..af4abf9f --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/IndexController.java @@ -0,0 +1,268 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import java.io.File; +import java.io.IOException; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.annotation.Resource; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.io.FileUtils; +import org.apache.commons.lang3.StringUtils; +import org.joda.time.DateTime; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.ApplicationContext; +import org.springframework.core.io.FileSystemResource; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.servlet.ModelAndView; + +import com.alibaba.fastjson.JSONArray; + +//import com.codahale.metrics.annotation.Timed; +import cn.netbuffer.ssmbootstrap_table.event.LoginEvent; +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; +import cn.netbuffer.ssmbootstrap_table.util.BeanMapUtil; +import cn.netbuffer.ssmbootstrap_table.util.POIExcelUtil; + +/** + * index + */ +@Controller(value="mainindex") +@RequestMapping("/") +public class IndexController { + public IndexController(){ + + } + @Resource + private IUserService userService; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @Autowired + private ApplicationContext applicationContext; + + @RequestMapping("/login") + public String login(HttpSession session, HttpServletRequest request, + HttpServletResponse response, String username, String password,@RequestParam(value="requri",required=false) String requri) { +// RequestContextUtils.getWebApplicationContext(request) + logger.info("进入username:{},pwd:{},requri:{}", username, password,requri); + if (username.equals(ConfigConstant.VAL_USERNAME) + && password.equals(ConfigConstant.VAL_PWD)) { + session.setAttribute(ConfigConstant.ISLOGIN, true); + session.setAttribute(ConfigConstant.USERNAME, username); + Cookie c = new Cookie(ConfigConstant.USERNAME, username); + c.setMaxAge(86400); + response.addCookie(c); + Map param=new HashMap<>(); + param.put("loginname", username); + param.put("logintime", new DateTime().toString("yyyy-MM-dd HH:mm:ss")); + param.put("loginip", request.getRemoteAddr()); + //publishEvent会依次调用所有的监听器,同步调用,所有监听器执行完毕继续向下执行 + logger.info("发布事件,parent context:{},application:{}",applicationContext.getParent(),applicationContext); + /** + * 在Controller控制器这一层发布事件不要直接用applicationContext.publishEvent(),因为事件会同时添加在root application context中导致重复执行一次 + */ + applicationContext.getParent().publishEvent(new LoginEvent(this,param)); + if(requri!=null&&requri.length()>0){ + String uri=new String(Base64.decodeBase64(requri)); + String touri=uri.substring(request.getContextPath().length()+1); + logger.debug("request.getContextPath():{} decode-requri:{} touri:{}",request.getContextPath(),uri,touri); +// /ssmbootstrap_table +// /ssmbootstrap_table/test/form?null + if(StringUtils.isNotBlank(touri)&&!touri.equals("/")){ + return "redirect:/"+touri; + } + } + return "redirect:/manage.html"; + } else { + return "redirect:/index.html?requri="+requri; + } + } + + @RequestMapping("/demo") + public String demolist() { + logger.debug("demo"); + return "redirect:/demolist.html"; + } + + @RequestMapping("/exit") + public String exit(HttpSession session,HttpServletRequest request, + HttpServletResponse response) { + logger.debug("用户{}退出系统",session.getAttribute(ConfigConstant.USERNAME)); + //删除cookie + Cookie cookie = new Cookie(ConfigConstant.USERNAME, null); + cookie.setMaxAge(0); + session.invalidate(); + logger.debug("exit c2:{}",cookie); + response.addCookie(cookie); + return "redirect:/index.html"; + } + + @RequestMapping("/newdata") + public String newdata(HttpSession session, Model model) { + DecimalFormat df = new DecimalFormat("0.00"); + // Display the total amount of memory in the Java virtual machine. + long totalMem = Runtime.getRuntime().totalMemory() / 1024 / 1024; + System.out.println(df.format(totalMem) + " MB"); + // Display the maximum amount of memory that the Java virtual machine + // will attempt to use. + long maxMem = Runtime.getRuntime().maxMemory() / 1024 / 1024; + System.out.println(df.format(maxMem) + " MB"); + // Display the amount of free memory in the Java Virtual Machine. + long freeMem = Runtime.getRuntime().freeMemory() / 1024 / 1024; + System.out.println(df.format(freeMem) + " MB"); + logger.info("执行前:{}", model); + int newcount = userService.getNewData(); + String username = session.getAttribute(ConfigConstant.USERNAME).toString(); + model.addAttribute("newcount", newcount); + model.addAttribute("username", username); + logger.info("执行后:{}", model); + return "newdata"; + } + + @RequestMapping("teststr") + public @ResponseBody String teststr() { + return "this is str"; + } + +// @Timed + @RequestMapping("/datacount") + public @ResponseBody Map datacount() { + logger.debug("获取datacount"); + List> counts = userService.getDataSum(); + JSONArray categorys = new JSONArray(); + JSONArray nums = new JSONArray(); + for (Map m : counts) { + categorys.add(m.get("adddate")==null?"":m.get("adddate").toString()); + nums.add(m.get("num").toString()); + } + logger.debug("categorys:{},nums:{}", categorys, nums); + Map data = new HashMap(); + data.put("c", categorys); + data.put("d", nums); + return data; + } + + @RequestMapping("/export") + public ResponseEntity export(HttpSession session, + HttpServletRequest request, HttpServletResponse response, + @RequestHeader(value = "USER-AGENT") String userAgent) throws UnsupportedEncodingException { + SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss"); + List users = userService.getUserList("desc", 10, 0); + String projectPath = request.getServletContext().getRealPath("export") + + File.separator; + File dir=new File(projectPath); + if(!dir.exists()){ + if(dir.mkdir()){ + logger.debug("创建目录:{}",dir.getAbsolutePath()); + }else{ + logger.debug("创建目录:{}失败!,请检查权限!",dir.getAbsolutePath()); + throw new RuntimeException("没有创建:"+dir.getAbsolutePath()+"目录的权限!"); + } + } + int userCount = users.size(); + List> mps = new ArrayList>( + users.size()); + for (int i = 0; i < userCount; i++) { + Map m = BeanMapUtil.transBean2Map(users.get(i)); + mps.add(m); + } + logger.info("users:{}", mps); + List titles = new ArrayList(mps.get(0).size() - 1); + titles.add("adddate"); + titles.add("age"); + titles.add("deliveryaddress"); + titles.add("id"); + titles.add("name"); + titles.add("phone"); + titles.add("sex"); + List columns = new ArrayList(mps.get(0).size() - 1); + columns.add("添加时间"); + columns.add("年龄"); + columns.add("收货地址"); + columns.add("ID"); + columns.add("名字"); + columns.add("手机"); + columns.add("性别"); + String file = projectPath + format.format(new Date()) + "." + + ConfigConstant.EXCELSTR; + logger.info("文件路径:{}", file); + POIExcelUtil.export(titles,columns, mps, file); + HttpHeaders headers = new HttpHeaders(); + headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); + String filename="中文"; + if(userAgent.toLowerCase().indexOf("firefox") >= 0){ + try { + filename = new String((filename+file.replace(projectPath, "")).getBytes("UTF-8"),"iso-8859-1"); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + }else { + try { + filename = URLEncoder.encode(filename+file.replace(projectPath, ""),"UTF-8"); + } catch (UnsupportedEncodingException e1) { + e1.printStackTrace(); + } + } + logger.debug("下载文件名字:{}",filename); + headers.setContentDispositionFormData("attachment",filename); + try { +// http://stackoverflow.com/questions/11203111/downloading-a-spring-mvc-generated-file-not-working-in-ie ie下载问题 + return new ResponseEntity( + FileUtils.readFileToByteArray(new File(file)), headers, + HttpStatus.OK); +// HttpStatus.CREATED + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + @RequestMapping(value = "/files/{file_name}", method = RequestMethod.GET) +// @ResponseBody + public FileSystemResource getFile(@PathVariable("file_name") String fileName,HttpServletRequest request) { + return new FileSystemResource(new File(request.getServletContext().getRealPath("export")+ File.separator+fileName+".xls")); + } + + @RequestMapping("/testerror") + public String testthrowException() { + throw new RuntimeException("test error"); + } + + @ExceptionHandler + public ModelAndView handleAllException(Exception ex) { + ModelAndView mav = new ModelAndView("500"); + mav.addObject("errMsg", ex.getMessage()); + return mav; + } + + /** + * 数据转换处理 + */ + // @InitBinder + // public void bind(WebDataBinder binder){ + // //设置不转换name,自行处理 + // binder.setDisallowedFields("name"); + // } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/JsonpController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/JsonpController.java new file mode 100644 index 00000000..dc4f4078 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/JsonpController.java @@ -0,0 +1,288 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Maps; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.web.bind.annotation.*; +import org.springframework.web.context.request.async.DeferredResult; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; +import java.io.IOException; +import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; + +/** + * jsonp测试 + */ +@Controller +@RequestMapping("/jsonp") +@SessionAttributes("name") +public class JsonpController { + + @Resource + private IUserService userService; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * 被@ModelAttribute注释的方法会在此controller每个方法执行前被执行 + */ + @ModelAttribute + public void testModelAttr(HttpSession session, Model model) { + JSONObject j = new JSONObject(); + if (session.getAttribute(ConfigConstant.ISLOGIN) != null) { + if (Boolean.parseBoolean(session.getAttribute( + ConfigConstant.ISLOGIN).toString())) { + j.put("msg", "^true"); + logger.debug("^true"); + } else { + j.put("msg", "^false"); + logger.debug("^false"); + } + } else { + logger.debug("^null"); + j.put("msg", "^null"); + } + model.addAttribute("j", j); + } + + //http://mvc.linesh.tw/publish/21-3/4-asynchronous-request-processing.html + /** + * 通过Spring MVC所管理的线程来产生返回值。与此同时,Servlet容器的主线程则可以退出并释放其资源了,同时也允许容器去处理其他的请求。 + * 通过一个TaskExecutor,Spring + * MVC可以在另外的线程中调用Callable。当Callable返回时,请求再携带Callable返回的值 + * ,再次被分配到Servlet容器中恢复处理流程 + * spring mvc中配置默认的超时时间 + * @param str + * @return + */ + @RequestMapping(value = "/asyncc", method = RequestMethod.GET) + @ResponseBody + public Callable asyncc(final String str) { + logger.debug("async test"); + return new Callable() { + public String call() throws Exception { + logger.debug("async thread"); + TimeUnit.SECONDS.sleep(10); + return "hello:" + str; + } + }; + } + + @RequestMapping(value = "/asyncd", method = RequestMethod.GET) + @ResponseBody + public DeferredResult asyncd(final String str,@RequestParam(value = "sleep",required = false,defaultValue = "3")final Integer sleep) { + final DeferredResult dr = new DeferredResult(); + new Thread(new Runnable() { + @Override + public void run() { + logger.info("asyncd task start"); + try { + TimeUnit.SECONDS.sleep(sleep); + } catch (InterruptedException e) { + e.printStackTrace(); + } + logger.info("asyncd task end"); + dr.setResult("hello:"+str); + } + },"deffered-execute-thread").start(); + return dr; + } + + /** + * 手动构建jsonp支持 前端使用jquery调用demo $.getJSON( + * "http://localhost:8080/ssmbootstrap_table/jsonp/test/1?callback=?" + * ,function(data){ $("body").append(data.name); console.log(data); }); + * + * + * $.ajax({ type: "GET", + * url:"http://localhost:8080/ssmbootstrap_table/jsonp/test/1", dataType: + * "jsonp", jsonp: "callback", success: function(data) { console.log(data); + * }, error: function(jqXHR){ console.log(jqXHR); }, }); + * + * + * @param id + * @param callback + * @param request + * @param response + * @return + */ + @RequestMapping("/test/{id}") + public @ResponseBody String test(@PathVariable Long id, + @RequestParam String callback, HttpServletRequest request, + HttpServletResponse response, Model model) { + logger.debug("model:{}", model); + response.setContentType("application/javascript"); + response.setCharacterEncoding("utf-8"); + logger.info("request:{}", ToStringBuilder.reflectionToString(request)); + logger.info("id:{}", id); + String result = callback + "(" + + JSON.toJSONString(userService.getUserById(id)) + ")"; + logger.debug("返回结果:{}", result); + return result; + } + + @RequestMapping("/t/{id}") + public void t(@PathVariable Long id, @RequestParam String callback, + HttpServletRequest request, HttpServletResponse response, + Model model) { + response.setContentType("application/javascript"); + response.setCharacterEncoding("utf-8"); + logger.info("request:{}", ToStringBuilder.reflectionToString(request)); + logger.info("id:{}", id); + String result = callback + "(" + + JSON.toJSONString(userService.getUserById(id)) + ")"; + logger.debug("返回结果:{}", result); + try { + response.getWriter().write(result); + } catch (IOException e) { + e.printStackTrace(); + logger.debug("发生错误:{}", e); + } + } + + /** + * 使用spring-jsonp-support库 jsonp调用 $.ajax({ + * url:"http://localhost:8080/ssmbootstrap_table/tj/3.json", + * dataType:"jsonp", jsonp: "callback", success: function(data) { + * console.log(data); }, error: function(jqXHR){ console.log(jqXHR); } }); + */ + @RequestMapping("/tj/{id}") + public User t(@PathVariable Long id, HttpServletRequest request, + HttpServletResponse response, Model model) { + return userService.getUserById(id); + } + + @RequestMapping("/str") + public @ResponseBody String str() { + return "你好"; + } + + /** + * http://localhost:8080/ssmbootstrap_table/jsonp/testarr?v[]=1&v[]=2&v[]=3 + * var arr=["a","b","c"]; 前端jquery发送数组,需要traditional置为 true + * $.ajax({ + * url:"http://localhost:8080/ssmbootstrap_table/jsonp/testarr", + * data:{"v":arr}, + * type:"post", + * traditional: true, + * success:function(data){ + * console.log(data); + * }, + * error:function(xhr){ + * console.log(xhr); + * } + * }); + * + * @param values + * @return + */ + @RequestMapping("/testarr") + public @ResponseBody String[] testarr( + @RequestParam(value = "v") String[] values, Model model) { + logger.debug("接收到的数组参数:{}", Arrays.deepToString(values)); + return values; + } + + /** + var d={"id":1,name:"test"}; + $.ajax({ + url:"http://localhost:8080/ssmbootstrap_table/jsonp/receivejson", + data:{"json":JSON.stringify(d)}, + type:"post", + ContentType: "application/json;charset=UTF-8", + success:function(data){ + console.log(data); + }, + error:function(xhr){ + console.log(xhr); + } + }); + get to http://localhost:8080/ssmbootstrap_table/jsonp/receivejson?json={%22id%22:1,name:%22test%22} + * + * @param values + * @return + */ + @RequestMapping("/receivejson") + public @ResponseBody Object receivejson(@RequestParam(value="json") String json) { + logger.debug("receive json str:{}",json); + JSONObject j=(JSONObject) JSONObject.parse(json); + logger.debug("receive json to jsonobject:{}",j); + return j; + } + + /** + $.ajax({ + url:"http://localhost:8080/ssmbootstrap_table/jsonp/receivejsonobj", + type:"post", + contentType:'application/json;charset=UTF-8', + data: "{id:1,name:\"test\"}", + success:function(data){ + console.log(data); + }, + error:function(xhr){ + console.log(xhr); + } + }); + * + * @param values + * @return + */ + @RequestMapping("/receivejsonobj") + public @ResponseBody User receivejsonobj(@RequestBody User user) { + logger.debug("receive json obj:{}",user); + return user; + } + + //接收JSONObject + @RequestMapping("/receiveJSONObject") + public @ResponseBody + Map receivejsonobj(@RequestBody JSONObject user,HttpServletRequest request) { + logger.debug("receiveJSONObject:{}",user); + return user; + + } + + //接收Map + @RequestMapping("/receiveMap") + public @ResponseBody + Map receivejsonobj(@RequestBody Map user,HttpServletRequest request) { + logger.debug("receiveMap:{}",user); + return user; + + } + + /** + * 获取session中name的值 + * + * @param model + * @return + */ + @RequestMapping("/getSessionAttr") + public @ResponseBody String getSessionAttr( + @ModelAttribute("name") String name, HttpSession session) { + logger.debug("name:{}", name); + return session.getAttribute("name").toString(); + } + + @ExceptionHandler + @ResponseBody + public Map handleAllException(Exception ex) { + Map result= Maps.newHashMap(); + result.put("success",false); + result.put("msg",ex.getMessage()); + return result; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/RegisterController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/RegisterController.java new file mode 100644 index 00000000..594ef123 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/RegisterController.java @@ -0,0 +1,104 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import java.util.List; + +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import javax.validation.Valid; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.validation.BindingResult; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; + +import cn.netbuffer.ssmbootstrap_table.exception.CustomGenericException; +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.model.UserListModel; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; + +@Controller +@RequestMapping("/register") +public class RegisterController { + + @Resource + private IUserService userService; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * springmvc数据校验 需要为实体加@Validated标记 + * @param binder + */ +// @InitBinder +// public void initBinder(DataBinder binder) { +// binder.setValidator(new UserValidator()); +// } + + @RequestMapping(value = { "", "/", "/index" }) + public String index() { + return "redirect:/registerinfo.html"; + } + + @RequestMapping("/save") + public String save(@Valid User user,BindingResult result,Model model) { + if(result.hasErrors()){ + logger.info("校验user出错:"+ToStringBuilder.reflectionToString(result)); + model.addAttribute("result", result); + return "500"; + } + user.setAdddate((int) (System.currentTimeMillis() / 1000)); + try { + userService.addUser(user); + } catch (Exception e) { + e.printStackTrace(); + return "redirect:/register-error.html"; + } + return "redirect:/register-success.html"; + } + + @RequestMapping("/saves") + public String save(UserListModel users) { + logger.debug("user lists-size:{}",users.getUsers().size()); + for(User u:users.getUsers()){ + logger.debug("userinfo:{}",u); + userService.addUser(u); + } + return "redirect:/register-success.html"; + } + + @RequestMapping("/savesjson") + public String savesjson(@RequestBody List users) { + logger.debug("user lists-size:{}",users.size()); + for(User u:users){ + logger.debug("userinfo:{}",u); + userService.addUser(u); + } + return "redirect:/register-success.html"; + } + + @RequestMapping("/testerror1") + public String testError(){ + throw new CustomGenericException(500,"错误测试"); + } + + @RequestMapping("/testerror2") + public String testError2(){ + int i=1/0; + return "index"; + } + @RequestMapping("/testredirect") + public String testRedirect(Model model){ + model.addAttribute("param", "test"); + return "redirect:/register-success.html?id={param}"; + } + + @RequestMapping("/req") + public void req(HttpServletRequest request){ + logger.info("Protocol:{}\r\n" + + "servername:{},\r\ngetScheme:{}",request.getProtocol(),request.getServerName(),request.getScheme()); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/RouteController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/RouteController.java new file mode 100644 index 00000000..76b1b5bb --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/RouteController.java @@ -0,0 +1,29 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@RequestMapping("/route") +public class RouteController { + + private static final Logger LOG = LoggerFactory.getLogger(RouteController.class); + + //指定参数路径映射 + @RequestMapping(params="m=m") + public @ResponseBody String m(HttpServletRequest request){ + LOG.debug("m=m"); + return "hello m"; + } + + @RequestMapping(params="m=m2") + public @ResponseBody String m2(HttpServletRequest request){ + LOG.debug("m=m2"); + return "hello m2"; + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/TestController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/TestController.java new file mode 100644 index 00000000..65dc411e --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/TestController.java @@ -0,0 +1,508 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import java.awt.Color; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.locks.Lock; +import java.util.concurrent.locks.ReentrantLock; +import javax.annotation.Resource; +import javax.imageio.ImageIO; +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.validation.Valid; +import org.apache.commons.lang3.exception.ExceptionUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.context.ApplicationContext; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.http.HttpStatus; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.ModelAttribute; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.bind.annotation.ResponseStatus; +import org.springframework.web.bind.annotation.SessionAttributes; +import org.springframework.web.multipart.commons.CommonsMultipartFile; +import org.springframework.web.servlet.i18n.CookieLocaleResolver; +import org.springframework.web.servlet.mvc.support.RedirectAttributes; +import com.alibaba.fastjson.JSONObject; +import com.google.zxing.BarcodeFormat; +import com.google.zxing.Binarizer; +import com.google.zxing.BinaryBitmap; +import com.google.zxing.DecodeHintType; +import com.google.zxing.EncodeHintType; +import com.google.zxing.LuminanceSource; +import com.google.zxing.MultiFormatReader; +import com.google.zxing.MultiFormatWriter; +import com.google.zxing.NotFoundException; +import com.google.zxing.Result; +import com.google.zxing.WriterException; +import com.google.zxing.client.j2se.BufferedImageLuminanceSource; +import com.google.zxing.client.j2se.MatrixToImageConfig; +import com.google.zxing.client.j2se.MatrixToImageWriter; +import com.google.zxing.common.BitMatrix; +import com.google.zxing.common.HybridBinarizer; +import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel; +import cn.netbuffer.ssmbootstrap_table.annotation.Token; +import cn.netbuffer.ssmbootstrap_table.model.Address; +import cn.netbuffer.ssmbootstrap_table.model.ExtendUser; +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.util.AjaxUtils; +import eu.bitwalker.useragentutils.UserAgent; + +@Controller +@RequestMapping("/test") +@SessionAttributes("name") +public class TestController { + private static final Logger LOG=LoggerFactory.getLogger(TestController.class); + private Logger loggerAccess = LoggerFactory.getLogger("access"); +// private Logger logger = LoggerFactory.getLogger(this.getClass()); + private Logger logger = loggerAccess; + + @Autowired + private ApplicationContext applicationContext; + + @Resource + private Properties configProperties; + @Value("#{configProperties['url2']}") + private String url; + @Value("#{configProperties['mysql.connectTime']}") + private Integer connectTime; + @Autowired + private CookieLocaleResolver cookieResolver; + //锁 + private Lock lock=new ReentrantLock(); + //注入静态属性值 + private static String JDBCURL; + //注入方法 + @Value("#{configProperties['jdbc.url']}") + public void setJdbcUrl(String url) { + JDBCURL = url; + } + + //@RequestMapping不写value会默认映射类上的访问路径"/test" + @RequestMapping(method=RequestMethod.GET) + public @ResponseBody String getTest() { + LOG.debug("GET to /test"); + return "GET to /test"; + } + + @RequestMapping(method=RequestMethod.POST) + public @ResponseBody String postTest() { + LOG.debug("POST to /test"); + return "POST to /test"; + } + + @RequestMapping(value = {"/getJdbcUrl" }) + public @ResponseBody String getJdbcUrl() { + logger.debug("静态属性值:{}",JDBCURL); + return JDBCURL; + } + + @RequestMapping(value = {"/getbean/{name}" }) + public @ResponseBody Object getbean(@PathVariable("name") String name) { + return applicationContext.getBean(name); + } + + @RequestMapping(value = {"/{id}", "/index/{id}" }) + public String index(@PathVariable("id") int id, ModelMap m) { + logger.debug("template id:{}", id); + m.addAttribute("uri", id); + m.addAttribute("showTime", System.currentTimeMillis() / 1000); + m.addAttribute("test",id); + return "test"; + } + + @RequestMapping(value = { "/getconfig" }) + public Object getConfig() { + return JSONObject.toJSON(configProperties); + } + + @RequestMapping(value = { "/geturl" }) + public @ResponseBody String getUrl() { + logger.debug("url:{}", url); + return url; + } + + @RequestMapping(value = { "/getConnectTime" }) + public @ResponseBody Integer getConnectTime() { + logger.debug("connectTime:{}", connectTime); + return connectTime; + } + + /** + * 直接写响应,会使用FastJsonHttpMessageConverter作json转换 访问路径会直接以json输出 + * + * @return + */ + @RequestMapping(value = { "/getobj" }) + public @ResponseBody Map getobj() { + Map res = new HashMap(); + res.put("key1", "v1"); + res.put("key2", "v2"); + return res; + } + + @RequestMapping(value = { "/setSessionAttr" }) + public @ResponseBody String setSessionAttr(ModelMap m) { + logger.debug("setSessionAttr"); + // 会被放到session中 + m.put("name", "this is name's value"); + return "success"; + } + + /** + * 返回本地化信息 + * + * @param locale + * @return + * @author genie + * @date 2016年6月13日 下午1:54:11 + */ + @RequestMapping(value = { "/locale" }) + public @ResponseBody String locale(Locale locale) { + logger.debug("locale:{}", locale); + return locale.toString(); + } + + @RequestMapping("/lang") + @ResponseBody + public String lang(@RequestParam(defaultValue="zh",required=false,value="lang")String langType, HttpServletRequest request, HttpServletResponse response) { + if (langType.equals("zh")) { + Locale locale = new Locale("zh", "CN"); + // request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, + // locale); + cookieResolver.setLocale(request, response, locale); + } else if (langType.equals("en")) { + Locale locale = new Locale("en", "US"); + // request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, + // locale); + cookieResolver.setLocale(request, response, locale); + } else + cookieResolver.setLocale(request, response, LocaleContextHolder.getLocale()); + // request.getSession().setAttribute(SessionLocaleResolver.LOCALE_SESSION_ATTRIBUTE_NAME, + // LocaleContextHolder.getLocale()); + return langType; + } + + @Token(save=true,tokenname="testformtoken") + @RequestMapping(value="/form",method=RequestMethod.GET) + public String getform(){ + logger.debug("test get form "); + return "user/add"; + } + + @Token(remove=true,tokenname="testformtoken",failuri="/user/error.jsp") + @RequestMapping(value="/form",method=RequestMethod.POST) + public String postform(@Valid User u){ +// ,BindingResult result + logger.debug("test post form:{}",u); +// if(result.hasErrors()){ +// logger.info("校验user出错:"+ToStringBuilder.reflectionToString(result)); +// throw new RuntimeException("请填写正确的用户信息"); +// } +// return "redirect:/register-success.html"; + //forward请求导致表单重复提交问题 + return "user/success"; + } + + /** + * 直接返回json数据 ,produces={"application/json"} + */ + @RequestMapping(value={"/uri"},method=RequestMethod.GET,headers={"Accept=application/json"}) + public JSONObject uri(HttpServletRequest request){ + JSONObject j=new JSONObject(); + j.put("request.getRequestURI", request.getRequestURI()); + j.put("request.getRequestURI().split(\"/\")", Arrays.deepToString(request.getRequestURI().split("/"))); + j.put("request.getRequestURL", request.getRequestURL()); + j.put("request.getServletContext().getContextPath", request.getServletContext().getContextPath()); + j.put("request.getServletContext().getRealPath(\"/\")", request.getServletContext().getRealPath("/")); + return j; + } + + /** + * 重定向拼接参数跳转 + * @return + */ + @RequestMapping(value={"/redirect"}) + public String redirect(ModelMap m){ + //spring自动做了参数拼接 + logger.debug("redirect"); + m.put("param", "this is parameter"); + return "redirect:/test/1"; + } + + @RequestMapping(value={"/redirect2"}) + public String redirect2(RedirectAttributes attributes){ + logger.debug("redirect2"); + attributes.addAttribute("param", "this is parameter"); + return "redirect:/test/1"; + } + + @RequestMapping(value={"/error"}) + public String error(ModelMap m){ + logger.debug("test error"); +// int i=1/0; + try{ + throw new RuntimeException("test"); + }catch(Exception ex){ + m.put("ex",ExceptionUtils.getStackTrace(ex)); + } + + return "error"; + } + + @ResponseStatus(reason="test",value=HttpStatus.NO_CONTENT) + @RequestMapping(value={"/status"}) + public String status(){ + logger.debug("status"); + return "error"; + } + + @RequestMapping(value={"/ajax"}) + public String ajax(HttpServletRequest request){ + logger.debug("request.getHeader(\"X-Requested-With\"):{}",request.getHeader("X-Requested-With")); + logger.debug("is ajax:{}",AjaxUtils.isAjaxRequest(request)); + return "index"; + } + + @RequestMapping(value={"/access"}) + public String access(){ + loggerAccess.info("access"); + return "index"; + } + + @RequestMapping(value={"/syn"}) + public synchronized String testSynchronized(ModelMap model){ + logger.warn("{}-执行synchronized操作!", Thread.currentThread().getName()); + try { + TimeUnit.SECONDS.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("服务器错误"); + } + if(model.get("syn")==null){ + model.put("syn", Thread.currentThread().getName()); + } + logger.warn("{}-执行synchronized操作完成", Thread.currentThread().getName()); + return "test"; + } + + @RequestMapping(value={"/syn2"}) + public String testSynchronized2(ModelMap model){ + lock.lock(); + logger.warn("{}-执行synchronized2操作!", Thread.currentThread().getName()); + try { + TimeUnit.SECONDS.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + throw new RuntimeException("服务器错误2"); + } + if(model.get("syn")==null){ + model.put("syn", Thread.currentThread().getName()); + } + logger.warn("{}-执行synchronized操作完成2", Thread.currentThread().getName()); + lock.unlock(); + return "test"; + } + + @RequestMapping(value={"/ue"}) + public String ue(ModelMap model){ + logger.debug("open ueditor"); + return "ueditor/index"; + } + + @RequestMapping(value={"/{no}/uri"}) + public String uri(ModelMap model){ + return "redirect:/{no}/index";//springmvc会对模板变量中的值解析处理 +// return "{no}/index"; + } + + @RequestMapping(value={"/websocket"}) + public String websocket(ModelMap model){ + return "websocket"; + } + + /** + * 创建二维码 + * @param response + * @param param + * @throws IOException + * @throws WriterException + */ + @RequestMapping(value={"/qr"},method=RequestMethod.GET) + public void qr(HttpServletResponse response,@RequestParam(value="param",defaultValue="test",required=false) String param, + @RequestParam(value="width",defaultValue="200") int width,@RequestParam(value="height",defaultValue="200") int height, + @RequestParam(value="format",defaultValue="jpg") String format,@RequestParam(value="r",defaultValue="0") int r, + @RequestParam(value="g",defaultValue="0") int g,@RequestParam(value="b",defaultValue="0") int b) + throws IOException, WriterException{ + logger.debug("使用zxing生成二维码,内容:{}",param); +// int width = 200; // 图像宽度 +// int height = 200; // 图像高度 +// String format = "png";// 图像类型 + Map hints = new HashMap(); +// http://www.tuicool.com/articles/vQFZNfq + hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); //编码 + hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.M); //容错率 + hints.put(EncodeHintType.MARGIN, 0); //二维码边框宽度,这里文档说设置0-4,发现当宽高都大于100的时候,才会有无边框效果 + hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); + BitMatrix bitMatrix = new MultiFormatWriter().encode(param, + BarcodeFormat.QR_CODE, width, height, hints);// 生成矩阵 + ByteArrayOutputStream jpegOutputStream = new ByteArrayOutputStream(); + response.setHeader("Cache-Control", "no-store"); + response.setHeader("Pragma", "no-cache"); + response.setDateHeader("Expires", 0L); + response.setContentType("image/jpeg"); + //颜色 + MatrixToImageConfig config = new MatrixToImageConfig(new Color(r,g,b).getRGB(),0xFFFFFFFF); + ImageIO.write(MatrixToImageWriter.toBufferedImage(bitMatrix,config), "jpeg", jpegOutputStream); + byte[] captchaChallengeAsJpeg = jpegOutputStream.toByteArray(); + ServletOutputStream respOs = response.getOutputStream(); + respOs.write(captchaChallengeAsJpeg); + respOs.flush(); + respOs.close(); + } + + @RequestMapping(value={"/decodeqr"},method=RequestMethod.GET) + public String decodeqr(){ + logger.debug("二维码解析"); + return "decodeqr"; + } + + @RequestMapping(value={"/decodeqr"},method=RequestMethod.POST) + @ResponseBody + public String decodeqr(HttpServletRequest request, + @RequestParam(value="qrimg",required=true)CommonsMultipartFile file, + @RequestParam(value="name",required=false)String name + )throws NotFoundException, IOException{ + logger.debug("二维码解析,附加数据:{}",name); + if(file.isEmpty()){ + throw new RuntimeException("请上传文件"); + } + BufferedImage image = ImageIO.read(file.getInputStream()); + LuminanceSource source = new BufferedImageLuminanceSource(image); + Binarizer binarizer = new HybridBinarizer(source); + BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer); + Map hints = new HashMap(); + hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); + //对图像进行解码 + Result result = null; + String resultTxt="incorrect qrimage"; + try { + result=new MultiFormatReader().decode(binaryBitmap, hints); + } catch (Exception e) { + e.printStackTrace(); + } + if(result!=null){ + resultTxt=result.getText(); + } + logger.debug("zxing解析二维码结果:{}",resultTxt); + return resultTxt; + } + + @RequestMapping(value={"/server"},method=RequestMethod.GET) + @ResponseBody + public String server(HttpServletRequest request){ + return request.getServerName(); + } + + @RequestMapping(value={"/bean"},method=RequestMethod.GET) + @ResponseBody + public Map bean(User u,Address a){ + //访问http://localhost:8080/ssmbootstrap_table/test/bean?name=mingzi&province=aaa&userId=1&sex=n,会自动组装对应的bean字段值 + Map result=new HashMap<>(2); + result.put("u", u); + result.put("a", a); + logger.debug("test receive bean1:{}",result); + return result; + } + + @RequestMapping(value={"/beans"},method=RequestMethod.GET) + @ResponseBody + public Map beansame(User u,ExtendUser eu){ + //http://localhost:8080/ssmbootstrap_table/test/beans?name=mingzisex=n ,会自动组装到所有的bean中 + Map result=new HashMap<>(2); + result.put("u", u); + result.put("eu", eu); + logger.debug("test receive bean2:{}",result); + return result; + } + + @RequestMapping(value={"/getids"},method=RequestMethod.GET) + @ResponseBody + public String getids(String ids){ + logger.debug("用户输入ids格式:{}",ids); + return ids; + } + + @RequestMapping(value={"/ua"},method=RequestMethod.GET) + @ResponseBody + public UserAgent ua(HttpServletRequest request){ + UserAgent userAgent = UserAgent.parseUserAgentString(request.getHeader("User-Agent")); + logger.debug("用户ua:{}",userAgent); + return userAgent; + } + + /** + * 会在视图中添加key为“user”的model,而不是“u”! + * @param u + * @return + */ + @RequestMapping(value="/testmodelattr1") + public String testmodelattr1(User u){ + logger.debug("testmodelattr1,u:{}",u); + return "test"; + } + + /** + * 会在视图中添加key为“user”的model,和key为“u”的model! + * @param u + * @param m + */ + @RequestMapping(value="/testmodelattr2") + public String testmodelattr2(User u,Model m){ + logger.debug("testmodelattr2,u:{}",u); + m.addAttribute("u", u); + return "test"; + } + + /** + * 会在视图中添加key为“u”的model,此时不会再添加key为“user”的model了 + * @param u + * @return + */ + @RequestMapping(value="/testmodelattr3") + public String testmodelattr3(@ModelAttribute(value="u")User u){ + logger.debug("testmodelattr3,u:{}",u); + return "test"; + } + + @RequestMapping(value="/serverip") + public @ResponseBody String getLocalIP(){ + String ip=AjaxUtils.getLocalIP(); + logger.debug("getLocalIP:{}",ip); + return ip; + } + + @RequestMapping(value="/indexurl") + public @ResponseBody String indexurl(HttpServletRequest request){ + String indexurl=request.getScheme()+"://"+AjaxUtils.getLocalIP()+":"+configProperties.getProperty("appport")+request.getContextPath(); + logger.debug("indexurl:{}",indexurl); + return indexurl; + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/UserController.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/UserController.java new file mode 100644 index 00000000..0331a1c2 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/controller/UserController.java @@ -0,0 +1,193 @@ +package cn.netbuffer.ssmbootstrap_table.controller; + +import java.io.UnsupportedEncodingException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import javax.annotation.Resource; +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.ui.Model; +import org.springframework.ui.ModelMap; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestMethod; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.ResponseBody; +import org.springframework.web.servlet.ModelAndView; +import com.alibaba.fastjson.JSON; +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.model.query.QueryUser; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; +import cn.netbuffer.ssmbootstrap_table.util.BeanMapUtil; + +@Controller +@RequestMapping("/user") +public class UserController { + + @Resource + private IUserService userService; + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @RequestMapping(value="/photos",method={RequestMethod.GET,RequestMethod.HEAD}) + public String photos() { + logger.debug("go to user-photos"); + return "user/photos"; + } + + @RequestMapping("/showUser/{id}") + public String toIndex(@PathVariable("id") int id, + HttpServletRequest request, Model model) { + logger.info("进入:{},参数:{}", request.getRequestURI(), model.toString()); + int userId = id; + User user = userService.getUserById(userId); + model.addAttribute("user", user); + return "su"; + } + + @RequestMapping("/testmodel") + public ModelAndView model() { + ModelAndView mav = new ModelAndView(); + User u = new User(); + u.setName("tianyu"); + u.setAge(11); + u.setDeliveryaddress("收货地址"); + mav.addObject("model", u); + return mav; + } + + /** + * 访问pdf视图 http://localhost:8080/ssmbootstrap_table/user/userpdfview.pdf + * @param model + * @return + */ + @RequestMapping("/userpdfview") + public String userpdfview(Model model) { + model.addAttribute("users",userService.getUserList("desc",10,0)); + List columns=new ArrayList<>(); + columns.add("姓名"); + columns.add("性别"); + columns.add("年龄"); + columns.add("手机号"); + model.addAttribute("columns", columns); + return "userpdfview"; + } + + /** + * 访问excel视图 http://localhost:8080/ssmbootstrap_table/user/userxlsview.xls + */ + @RequestMapping("/userxlsview") + public String userxlsview(Model model) { + List users=userService.getUserList("desc",10,0); + List> mps = new ArrayList>( + users.size()); + int userCount=users.size(); + for (int i = 0; i < userCount; i++) { + Map m = BeanMapUtil.transBean2Map(users.get(i)); + mps.add(m); + } + model.addAttribute("users",mps); + List columns=new ArrayList<>(); + columns.add("姓名"); + columns.add("性别"); + columns.add("年龄"); + columns.add("手机号"); + List keys=new ArrayList<>(); + keys.add("name"); + keys.add("sex"); + keys.add("age"); + keys.add("phone"); + model.addAttribute("keys", keys); + model.addAttribute("columns", columns); + return "userxlsview"; + } + + /** + * http://localhost:8080/ssmbootstrap_table/user/userlist?order=asc&limit=10 + * &offset=0 + * + * @param order + * @param limit + * @param offset + * @param model + * @return + */ + @RequestMapping("/userlist") + public String userlist(@RequestParam(value="search",required=false)String search,String order, int limit, int offset, Model model) { + long startTime = System.nanoTime(); + logger.info("参数:{},{},{}", order, limit, offset); + if(search!=null){ + try { + //get参数乱码问题:http://luanxiyuan.iteye.com/blog/1849169 + search=new String(search.getBytes("ISO-8859-1"), "UTF-8"); + logger.info("查询参数:{}", search); + } catch (UnsupportedEncodingException e) { + e.printStackTrace(); + } + + } + List users =search==null? userService.getUserList(order, limit, offset): userService.getUserList(search,order, limit, offset); + long total = userService.getUserListCount(); + Map params = new HashMap(); + model.addAttribute("total", total); + model.addAttribute("rows", users); + logger.info("结果:{}", params); + long estimatedTime = System.nanoTime() - startTime; + logger.debug("userlist execute with:{}ns",estimatedTime); + return "userlist"; + } + + @RequestMapping("/userlistq") + public String userlist(QueryUser query,ModelMap map) { + logger.info("查询参数:{}", query); + map.addAttribute("query", query); + String querystr=JSON.toJSONString(query); + map.addAttribute("querystr",querystr); + logger.debug("querystr:{}",querystr); + return "testquery"; + } + + @RequestMapping("/delete") + @ResponseBody + public String delete(@RequestParam(value="id",required=false,defaultValue="0") String id) { + logger.info("删除用户:{}", id); + userService.deleteById(Long.parseLong(id)); + return "delete"; + } + + @RequestMapping("/showUserXML") + public ModelAndView showUserXML(HttpServletRequest request, Model model) { + ModelAndView mav = new ModelAndView("xStreamMarshallingView"); + int userId = Integer.parseInt("1"); + User user = userService.getUserById(userId); + return mav; + } + + @RequestMapping(method = RequestMethod.GET, value = "/u/{id}", headers = "Accept=application/json") + public @ResponseBody User getEmp(@PathVariable String id) { + User e = userService.getUserById(1); + return e; + } + + @RequestMapping(method = RequestMethod.GET, value = "/us", headers = "Accept=application/json") + public @ResponseBody List ListinggetAllEmp() { + List us = new ArrayList(); + us.add(userService.getUserById(1)); + us.add(userService.getUserById(2)); + return us; + } + + /** + * 测试异步方法执行 + */ + @RequestMapping(value = "/testasync",method = RequestMethod.GET) + public @ResponseBody String testasync() { + //会立即返回响应success + userService.execute(); + return "success"; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/IMenuDao.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/IMenuDao.java new file mode 100644 index 00000000..8bebe9a2 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/IMenuDao.java @@ -0,0 +1,8 @@ +package cn.netbuffer.ssmbootstrap_table.dao; + +import cn.netbuffer.ssmbootstrap_table.model.Menu; + +public interface IMenuDao { + Menu getMenuById(Long l); + void insert(Menu m); +} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/dao/IUserDao.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/IUserDao.java similarity index 57% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/dao/IUserDao.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/dao/IUserDao.java index f14c76db..c40b3d15 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/dao/IUserDao.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/IUserDao.java @@ -1,26 +1,36 @@ -package cn.com.ttblog.ssmbootstrap_table.dao; - -import java.util.List; -import java.util.Map; - -import cn.com.ttblog.ssmbootstrap_table.model.User; - -public interface IUserDao { - int deleteByPrimaryKey(Long id); - - int insert(User record); - - int insertSelective(User record); - - User selectByPrimaryKey(Long id); - - int updateByPrimaryKeySelective(User record); - - int updateByPrimaryKey(User record); - - long getUserListCount(); - - int getNewData(); - - List> getDataSum(); +package cn.netbuffer.ssmbootstrap_table.dao; + +import java.util.List; +import java.util.Map; + +import org.apache.ibatis.annotations.Param; + +import cn.netbuffer.ssmbootstrap_table.model.User; + +public interface IUserDao { + int deleteByPrimaryKey(Long id); + + int insert(User record); + + int insertSelective(User record); + + User selectByPrimaryKey(Long id); + + int updateByPrimaryKeySelective(User record); + + int updateByPrimaryKey(User record); + + long getUserListCount(); + + int getNewData(); + + List> getDataSum(); + + List getUsersByIds(List ids); + + List selectWhen(@Param("id")Integer id); + + void deleteById(Long id); + + User selectByName(String userName); } \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/MenuMapper.xml b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/MenuMapper.xml new file mode 100644 index 00000000..44ab81b9 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/MenuMapper.xml @@ -0,0 +1,24 @@ + + + + + + + + + + + + + + + + + insert into menu(name,parent_id) values(#{name},#{parentId}) + + + \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/dao/UserMapper.xml b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/UserMapper.xml similarity index 54% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/dao/UserMapper.xml rename to src/main/java/cn/netbuffer/ssmbootstrap_table/dao/UserMapper.xml index 1e6f03b6..f6cbef93 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/dao/UserMapper.xml +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao/UserMapper.xml @@ -1,151 +1,235 @@ - - - - - - - - - - - - - - id, name, sex, age, phone, deliveryaddress, adddate - - - - - - - - delete from user - where id = #{id,jdbcType=BIGINT} - - - insert into user (name, sex, - age, phone, deliveryaddress, - adddate) - values (#{name,jdbcType=VARCHAR}, - #{sex,jdbcType=VARCHAR}, - #{age,jdbcType=INTEGER}, - #{phone,jdbcType=VARCHAR}, - #{deliveryaddress,jdbcType=VARCHAR}, - #{adddate,jdbcType=INTEGER}) - - - - insert into user - - - id, - - - name, - - - sex, - - - age, - - - phone, - - - deliveryaddress, - - - adddate, - - - - - #{id,jdbcType=BIGINT}, - - - #{name,jdbcType=VARCHAR}, - - - #{sex,jdbcType=VARCHAR}, - - - #{age,jdbcType=INTEGER}, - - - #{phone,jdbcType=VARCHAR}, - - - #{deliveryaddress,jdbcType=VARCHAR}, - - - #{adddate,jdbcType=INTEGER}, - - - - - update user - - - name = #{name,jdbcType=VARCHAR}, - - - sex = #{sex,jdbcType=VARCHAR}, - - - age = #{age,jdbcType=INTEGER}, - - - phone = #{phone,jdbcType=VARCHAR}, - - - deliveryaddress = #{deliveryaddress,jdbcType=VARCHAR}, - - - adddate = #{adddate,jdbcType=INTEGER}, - - - where id = #{id,jdbcType=BIGINT} - - - update user - set - name = #{name,jdbcType=VARCHAR}, - sex = #{sex,jdbcType=VARCHAR}, - age = - #{age,jdbcType=INTEGER}, - phone = #{phone,jdbcType=VARCHAR}, - deliveryaddress = #{deliveryaddress,jdbcType=VARCHAR}, - adddate = - #{adddate,jdbcType=INTEGER} - where id = #{id,jdbcType=BIGINT} - - - - - - - - - + + + + + + + + + + + + + id, name, sex, age, phone, deliveryaddress, adddate + + + + + + + + + + + + delete from user + where id = #{id,jdbcType=BIGINT} + + + + delete from user where id = #{id,jdbcType=BIGINT} + + + + + + select LAST_INSERT_ID() as id + + insert into user (name, sex, + age, phone, deliveryaddress, + adddate) + values (#{name,jdbcType=VARCHAR}, + #{sex,jdbcType=VARCHAR}, + #{age,jdbcType=INTEGER}, + #{phone,jdbcType=VARCHAR}, + #{deliveryaddress,jdbcType=VARCHAR}, + #{adddate,jdbcType=INTEGER}) + + + + insert into user + + + id, + + + name, + + + sex, + + + age, + + + phone, + + + deliveryaddress, + + + adddate, + + + + + #{id,jdbcType=BIGINT}, + + + #{name,jdbcType=VARCHAR}, + + + #{sex,jdbcType=VARCHAR}, + + + #{age,jdbcType=INTEGER}, + + + #{phone,jdbcType=VARCHAR}, + + + #{deliveryaddress,jdbcType=VARCHAR}, + + + #{adddate,jdbcType=INTEGER}, + + + + + update user + + + name = #{name,jdbcType=VARCHAR}, + + + sex = #{sex,jdbcType=VARCHAR}, + + + age = #{age,jdbcType=INTEGER}, + + + phone = #{phone,jdbcType=VARCHAR}, + + + deliveryaddress = #{deliveryaddress,jdbcType=VARCHAR}, + + + adddate = #{adddate,jdbcType=INTEGER}, + + + where id = #{id,jdbcType=BIGINT} + + + update user + set + name = #{name,jdbcType=VARCHAR}, + sex = #{sex,jdbcType=VARCHAR}, + age = + #{age,jdbcType=INTEGER}, + phone = #{phone,jdbcType=VARCHAR}, + deliveryaddress = #{deliveryaddress,jdbcType=VARCHAR}, + adddate = + #{adddate,jdbcType=INTEGER} + where id = #{id,jdbcType=BIGINT} + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/dao2/IUserDaoTest.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao2/IUserDaoTest.java new file mode 100644 index 00000000..1c07da24 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao2/IUserDaoTest.java @@ -0,0 +1,5 @@ +package cn.netbuffer.ssmbootstrap_table.dao2; + +public interface IUserDaoTest { + int getSum(); +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/dao2/UserMapper.xml b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao2/UserMapper.xml new file mode 100644 index 00000000..1749189b --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/dao2/UserMapper.xml @@ -0,0 +1,7 @@ + + + + + \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/enumeration/Config.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/enumeration/Config.java new file mode 100644 index 00000000..3efc55c5 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/enumeration/Config.java @@ -0,0 +1,16 @@ +package cn.netbuffer.ssmbootstrap_table.enumeration; + +public enum Config { + + KEY("test"); + private final String value; + + Config(String value) { + this.value = value; + } + + public String getValue() { + return this.value; + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/event/LoginEvent.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/event/LoginEvent.java new file mode 100644 index 00000000..b7cf8c8b --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/event/LoginEvent.java @@ -0,0 +1,27 @@ +package cn.netbuffer.ssmbootstrap_table.event; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.springframework.context.ApplicationEvent; +import java.util.Map; + +public class LoginEvent extends ApplicationEvent { + + private Map data; + + public LoginEvent(Object source, Map data) { + super(source); + this.data=data; + } + + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/exception/CustomGenericException.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/exception/CustomGenericException.java new file mode 100644 index 00000000..ca8567cd --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/exception/CustomGenericException.java @@ -0,0 +1,46 @@ +package cn.netbuffer.ssmbootstrap_table.exception; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +/** + * 自定义异常 + * @author netbuffer + */ +public class CustomGenericException extends RuntimeException{ + + /** + * + */ + private static final long serialVersionUID = 1L; + public CustomGenericException(){ + + } + public CustomGenericException(int errCode,String errMsg){ + setErrCode(errCode); + setErrMsg(errMsg); + } + + private int errCode; + + public int getErrCode() { + return errCode; + } + + public void setErrCode(int errCode) { + this.errCode = errCode; + } + + public String getErrMsg() { + return errMsg; + } + + public void setErrMsg(String errMsg) { + this.errMsg = errMsg; + } + + private String errMsg; + + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/DomainFilter.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/DomainFilter.java new file mode 100644 index 00000000..6d01629e --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/DomainFilter.java @@ -0,0 +1,36 @@ +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DomainFilter implements Filter { + private static final Logger log = LoggerFactory + .getLogger(DomainFilter.class); + private FilterConfig filterConfig; + + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + public void destroy() { + } + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + boolean enable = Boolean.parseBoolean(filterConfig + .getInitParameter("enable")); + if (enable) { + chain.doFilter(new DomainHttpServletRequestWrapper((HttpServletRequest) request), response); + } else { + chain.doFilter(request, response); + } + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/DomainHttpServletRequestWrapper.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/DomainHttpServletRequestWrapper.java new file mode 100644 index 00000000..dd14455f --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/DomainHttpServletRequestWrapper.java @@ -0,0 +1,17 @@ +package cn.netbuffer.ssmbootstrap_table.filter; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class DomainHttpServletRequestWrapper extends HttpServletRequestWrapper { + private static final Logger log=LoggerFactory.getLogger(DomainHttpServletRequestWrapper.class); + public DomainHttpServletRequestWrapper(HttpServletRequest request) { + super(request); + } + public String getServerName() { + log.debug("wrapper-get servername"); + return "deny"; + } +} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/InjectionAttackFilter.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/InjectionAttackFilter.java similarity index 97% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/InjectionAttackFilter.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/filter/InjectionAttackFilter.java index e6841fbd..6556725a 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/InjectionAttackFilter.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/InjectionAttackFilter.java @@ -1,4 +1,4 @@ -package cn.com.ttblog.ssmbootstrap_table.filter; +package cn.netbuffer.ssmbootstrap_table.filter; import java.io.IOException; diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/InjectionAttackWrapper.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/InjectionAttackWrapper.java similarity index 96% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/InjectionAttackWrapper.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/filter/InjectionAttackWrapper.java index 0d1eea69..6a4fcfc2 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/InjectionAttackWrapper.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/InjectionAttackWrapper.java @@ -1,123 +1,123 @@ -/** -Copyright (c) 2011 Andrew C Slocum - -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - **/ - -package cn.com.ttblog.ssmbootstrap_table.filter; - -import java.util.HashMap; -import java.util.Map; -import java.util.Set; - -import javax.servlet.http.Cookie; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - -public class InjectionAttackWrapper extends HttpServletRequestWrapper { - private static final String EVENTS = "((?i)onload|onunload|onchange|onsubmit|onreset" - + "|onselect|onblur|onfocus|onkeydown|onkeypress|onkeyup" - + "|onclick|ondblclick|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup)"; - private static final String XSS_HTML_TAG = "(%3C)|(%3E)|[<>]+"; - private static final String XSS_INJECTION = "((%22%20)|(%22\\s)|('%22)|(%22\\+))\\w.*|(\\s|%20)" - + EVENTS + ".*|(%3D)|(%7C)"; - private static final String XSS_REGEX = XSS_HTML_TAG + "|" + XSS_INJECTION; - private static final String SQL_REGEX = "('.+--)|(--)|(\\|)|(%7C)"; - - boolean filterXSS = true; - boolean filterSQL = true; - - public InjectionAttackWrapper(HttpServletRequest request, - boolean filterXSS, boolean filterSQL) { - super(request); - this.filterXSS = filterXSS; - this.filterSQL = filterSQL; - } - - public InjectionAttackWrapper(HttpServletRequest request) { - this(request, true, true); - } - - @Override - public String getParameter(String name) { - String value = super.getParameter(name); - return filterParamString(value); - } - - @Override - public Map getParameterMap() { - Map rawMap = super.getParameterMap(); - Map filteredMap = new HashMap( - rawMap.size()); - Set keys = rawMap.keySet(); - for (String key : keys) { - String[] rawValue = rawMap.get(key); - String[] filteredValue = filterStringArray(rawValue); - filteredMap.put(key, filteredValue); - } - return filteredMap; - } - - protected String[] filterStringArray(String[] rawValue) { - String[] filteredArray = new String[rawValue.length]; - for (int i = 0; i < rawValue.length; i++) { - filteredArray[i] = filterParamString(rawValue[i]); - } - return filteredArray; - } - - @Override - public String[] getParameterValues(String name) { - String[] rawValues = super.getParameterValues(name); - if (rawValues == null) - return null; - String[] filteredValues = new String[rawValues.length]; - for (int i = 0; i < rawValues.length; i++) { - filteredValues[i] = filterParamString(rawValues[i]); - } - return filteredValues; - } - - protected String filterParamString(String rawValue) { - if (rawValue == null) { - return null; - } - if (filterXSS()) { - rawValue = rawValue.replaceAll(XSS_REGEX, ""); - } - if (filterSQL()) { - rawValue = rawValue.replaceAll(SQL_REGEX, ""); - } - return rawValue; - } - - @Override - public Cookie[] getCookies() { - Cookie[] existingCookies = super.getCookies(); - if (existingCookies != null) { - for (int i = 0; i < existingCookies.length; ++i) { - Cookie cookie = existingCookies[i]; - cookie.setValue(filterParamString(cookie.getValue())); - } - } - return existingCookies; - } - - @Override - public String getQueryString() { - return filterParamString(super.getQueryString()); - } - - protected boolean filterXSS() { - return filterXSS; - } - - protected boolean filterSQL() { - return filterSQL; - } - -} +/** +Copyright (c) 2011 Andrew C Slocum + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + **/ + +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +public class InjectionAttackWrapper extends HttpServletRequestWrapper { + private static final String EVENTS = "((?i)onload|onunload|onchange|onsubmit|onreset" + + "|onselect|onblur|onfocus|onkeydown|onkeypress|onkeyup" + + "|onclick|ondblclick|onmousedown|onmousemove|onmouseout|onmouseover|onmouseup)"; + private static final String XSS_HTML_TAG = "(%3C)|(%3E)|[<>]+"; + private static final String XSS_INJECTION = "((%22%20)|(%22\\s)|('%22)|(%22\\+))\\w.*|(\\s|%20)" + + EVENTS + ".*|(%3D)|(%7C)"; + private static final String XSS_REGEX = XSS_HTML_TAG + "|" + XSS_INJECTION; + private static final String SQL_REGEX = "('.+--)|(--)|(\\|)|(%7C)"; + + boolean filterXSS = true; + boolean filterSQL = true; + + public InjectionAttackWrapper(HttpServletRequest request, + boolean filterXSS, boolean filterSQL) { + super(request); + this.filterXSS = filterXSS; + this.filterSQL = filterSQL; + } + + public InjectionAttackWrapper(HttpServletRequest request) { + this(request, true, true); + } + + @Override + public String getParameter(String name) { + String value = super.getParameter(name); + return filterParamString(value); + } + + @Override + public Map getParameterMap() { + Map rawMap = super.getParameterMap(); + Map filteredMap = new HashMap( + rawMap.size()); + Set keys = rawMap.keySet(); + for (String key : keys) { + String[] rawValue = rawMap.get(key); + String[] filteredValue = filterStringArray(rawValue); + filteredMap.put(key, filteredValue); + } + return filteredMap; + } + + protected String[] filterStringArray(String[] rawValue) { + String[] filteredArray = new String[rawValue.length]; + for (int i = 0; i < rawValue.length; i++) { + filteredArray[i] = filterParamString(rawValue[i]); + } + return filteredArray; + } + + @Override + public String[] getParameterValues(String name) { + String[] rawValues = super.getParameterValues(name); + if (rawValues == null) + return null; + String[] filteredValues = new String[rawValues.length]; + for (int i = 0; i < rawValues.length; i++) { + filteredValues[i] = filterParamString(rawValues[i]); + } + return filteredValues; + } + + protected String filterParamString(String rawValue) { + if (rawValue == null) { + return null; + } + if (filterXSS()) { + rawValue = rawValue.replaceAll(XSS_REGEX, ""); + } + if (filterSQL()) { + rawValue = rawValue.replaceAll(SQL_REGEX, ""); + } + return rawValue; + } + + @Override + public Cookie[] getCookies() { + Cookie[] existingCookies = super.getCookies(); + if (existingCookies != null) { + for (int i = 0; i < existingCookies.length; ++i) { + Cookie cookie = existingCookies[i]; + cookie.setValue(filterParamString(cookie.getValue())); + } + } + return existingCookies; + } + + @Override + public String getQueryString() { + return filterParamString(super.getQueryString()); + } + + protected boolean filterXSS() { + return filterXSS; + } + + protected boolean filterSQL() { + return filterSQL; + } + +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/JsonpReferFilter.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/JsonpReferFilter.java new file mode 100644 index 00000000..e49ae80b --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/JsonpReferFilter.java @@ -0,0 +1,65 @@ +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.io.IOException; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * jsonp refer检测,只允许特定的refer调用jsonp接口 + * + * @author netbuffer + */ +public class JsonpReferFilter implements Filter { + + private FilterConfig filterConfig; + private static final Logger log=LoggerFactory.getLogger(JsonpReferFilter.class); + @Override + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + @Override + public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; + boolean enable = Boolean.parseBoolean(filterConfig.getInitParameter("enable")); + // 不起用的情况下直接通过 + if (!enable) { + filterChain.doFilter(httpServletRequest, httpServletResponse); + return ; + } + String callback=httpServletRequest.getParameter("callback"); + if(callback==null){ + log.debug("非jsonp请求"); + filterChain.doFilter(httpServletRequest, httpServletResponse); + }else{ + log.debug("jsonp请求:{}",httpServletRequest.getParameterMap()); + String referString = filterConfig.getInitParameter("refers"); + String[] refers = referString.split(";"); + if(refers.length>0){ + String userRefer=httpServletRequest.getHeader("Referer"); + log.debug("允许调用jsonp接口-refer列表:{},用户refer:{}",refers,userRefer); + if(userRefer!=null){ + for(String r:refers){ + if(userRefer.contains(r)){ + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + } + } + } + } + } + + @Override + public void destroy() { + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/LoginFilter.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/LoginFilter.java new file mode 100644 index 00000000..cbf4a92e --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/LoginFilter.java @@ -0,0 +1,143 @@ +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.io.IOException; +import java.util.Arrays; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.Cookie; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.constant.ConfigConstant; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import com.github.jscookie.javacookie.Cookies; +import cn.netbuffer.ssmbootstrap_table.util.AntPathMatcherUtil; + +public class LoginFilter implements Filter { + + private FilterConfig filterConfig; + @Autowired + private IUserService userService; + + private static final Logger LOG=LoggerFactory.getLogger(LoginFilter.class); + @Override + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + @Override + public void doFilter(ServletRequest servletRequest, + ServletResponse servletResponse, FilterChain filterChain) + throws IOException, ServletException { + HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest; + HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse; + String noFilterTagString = filterConfig.getInitParameter("noFilterTags").trim(); + boolean enable=Boolean.parseBoolean(filterConfig.getInitParameter("enable")); + //不起用的情况下直接通过 + if(!enable){ + filterChain.doFilter(httpServletRequest,httpServletResponse); + return ; + } + String[] noFilterTags = noFilterTagString.split("\n"); + int length=noFilterTags.length; + for(int i=0;i0){ + //从cookie检查登录状态 + checkStatusFromCookie(httpServletRequest,httpServletResponse,filterChain); + return; + }else{ + LOG.debug("^^^no cookie,no session"); + if(!httpServletResponse.isCommitted()){ + redirect(httpServletRequest,httpServletResponse); + return ; + }else { + LOG.info("no cookie&session httpServletResponse.isCommitted():{}",httpServletResponse.isCommitted()); + } + } + } + + private void checkStatusFromSession(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,FilterChain filterChain) throws IOException, ServletException { + LOG.debug("get login status from session"); + String uri = httpServletRequest.getRequestURI(); + if(uri.endsWith(ConfigConstant.PROJECTNAME+"/")){ + httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/manage.html"); + }else{ + filterChain.doFilter(httpServletRequest, httpServletResponse); + } + } + + private void checkStatusFromCookie(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse,FilterChain filterChain) throws IOException, ServletException { + LOG.debug("get login status from cookie"); + String uri = httpServletRequest.getRequestURI(); + Cookie[] cookiesArray=httpServletRequest.getCookies(); + boolean find=false; + for(Cookie cookie:cookiesArray){ + if(cookie.getName().equals(ConfigConstant.USERNAME)&&cookie.getValue().length()>0){ + User user=userService.getUserByName(cookie.getValue()); + LOG.warn("根据cookie:{}查询用户:{}",cookie,user); + if(user==null){ + break; + } + find=true; + httpServletRequest.getSession().setAttribute(ConfigConstant.ISLOGIN, true); + httpServletRequest.getSession().setAttribute(ConfigConstant.USERNAME, cookie.getValue()); + if(uri.endsWith(ConfigConstant.PROJECTNAME+"/")){ + httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/manage.html"); + }else{ + break; + } + } + } + if(!find){ + //关于committed状态 http://blog.csdn.net/jubincn/article/details/8920573 + if(!httpServletResponse.isCommitted()){ + redirect(httpServletRequest,httpServletResponse); + }else { + LOG.info("no cookie httpServletResponse.isCommitted():{}",httpServletResponse.isCommitted()); + } + }else { + filterChain.doFilter(httpServletRequest,httpServletResponse); + } + } + + private void redirect(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) throws IOException { + //记录之前访问的参数 + String uri = httpServletRequest.getRequestURI(); + if(StringUtils.isNotBlank(httpServletRequest.getQueryString())){ + uri+="?="+httpServletRequest.getQueryString(); + } + String base64uri=Base64.encodeBase64String(uri.getBytes()); + httpServletResponse.sendRedirect(httpServletRequest.getContextPath() + "/index.html?requri="+base64uri); + } + + @Override + public void destroy() { + LOG.debug("loginfilter destory"); + } +} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TimerFilter.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TimerFilter.java similarity index 93% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TimerFilter.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TimerFilter.java index fb7c95fb..fbfb7354 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TimerFilter.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TimerFilter.java @@ -1,55 +1,55 @@ -package cn.com.ttblog.ssmbootstrap_table.filter; - -import java.io.IOException; -import java.math.BigDecimal; -import java.text.DecimalFormat; -import java.text.NumberFormat; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * 计时器。用于记录请求执行时间。 - */ -public class TimerFilter implements Filter { - private FilterConfig filterConfig; - private static final Logger timerFilterlogger = LoggerFactory - .getLogger(TimerFilter.class); - public static final NumberFormat FORMAT = new DecimalFormat("0.000"); - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - boolean enable = Boolean.parseBoolean(filterConfig - .getInitParameter("enable")); - if (enable) { - long begin = System.currentTimeMillis(); - chain.doFilter(request, response); - if (timerFilterlogger.isDebugEnabled()) { - long end = System.currentTimeMillis(); - BigDecimal processed = new BigDecimal(end - begin) - .divide(new BigDecimal(1000)); - String uri = ((HttpServletRequest) request).getRequestURI(); - timerFilterlogger.debug("costs in {} second(s). URI={}", - FORMAT.format(processed), uri); - } - } else { - chain.doFilter(request, response); - } - } - - public void init(FilterConfig filterConfig) throws ServletException { - this.filterConfig = filterConfig; - } - - public void destroy() { - } - -} +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.io.IOException; +import java.math.BigDecimal; +import java.text.DecimalFormat; +import java.text.NumberFormat; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 计时器。用于记录请求执行时间。 + */ +public class TimerFilter implements Filter { + private FilterConfig filterConfig; + private static final Logger timerFilterlogger = LoggerFactory + .getLogger(TimerFilter.class); + public static final NumberFormat FORMAT = new DecimalFormat("0.000"); + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + boolean enable = Boolean.parseBoolean(filterConfig + .getInitParameter("enable")); + if (enable) { + long begin = System.currentTimeMillis(); + chain.doFilter(request, response); + if (timerFilterlogger.isDebugEnabled()) { + long end = System.currentTimeMillis(); + BigDecimal processed = new BigDecimal(end - begin) + .divide(new BigDecimal(1000)); + String uri = ((HttpServletRequest) request).getRequestURI(); + timerFilterlogger.debug("costs in {} second(s). URI={}", + FORMAT.format(processed), uri); + } + } else { + chain.doFilter(request, response); + } + } + + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + public void destroy() { + } + +} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TrimFilter.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TrimFilter.java similarity index 75% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TrimFilter.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TrimFilter.java index 7b916d55..1da69ce8 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TrimFilter.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TrimFilter.java @@ -1,44 +1,48 @@ -package cn.com.ttblog.ssmbootstrap_table.filter; - -import java.io.IOException; - -import javax.servlet.Filter; -import javax.servlet.FilterChain; -import javax.servlet.FilterConfig; -import javax.servlet.ServletException; -import javax.servlet.ServletRequest; -import javax.servlet.ServletResponse; -import javax.servlet.http.HttpServletRequest; - -/** - * 过滤空白符号filter - * - * @author champ - * - */ -public class TrimFilter implements Filter { - - private FilterConfig filterConfig; - - public void init(FilterConfig filterConfig) throws ServletException { - this.filterConfig = filterConfig; - } - - public void destroy() { - } - - public void doFilter(ServletRequest request, ServletResponse response, - FilterChain chain) throws IOException, ServletException { - boolean enable = Boolean.parseBoolean(filterConfig - .getInitParameter("enable")); - if (enable) { - System.out.println("清除空白"); - chain.doFilter( - new TrimRequestWrapper((HttpServletRequest) request), - response); - } else { - System.out.println("直接放行"); - chain.doFilter(request, response); - } - } -} +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.io.IOException; + +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * 过滤空白符号filter + * + * @author netbuffer + * + */ +public class TrimFilter implements Filter { + private static final Logger trimFilterlogger = LoggerFactory + .getLogger(TrimFilter.class); + private FilterConfig filterConfig; + + public void init(FilterConfig filterConfig) throws ServletException { + this.filterConfig = filterConfig; + } + + public void destroy() { + } + + public void doFilter(ServletRequest request, ServletResponse response, + FilterChain chain) throws IOException, ServletException { + boolean enable = Boolean.parseBoolean(filterConfig + .getInitParameter("enable")); + if (enable) { + trimFilterlogger.trace("清除空白"); + chain.doFilter( + new TrimRequestWrapper((HttpServletRequest) request), + response); + } else { + trimFilterlogger.trace("直接放行"); + chain.doFilter(request, response); + } + } +} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TrimRequestWrapper.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TrimRequestWrapper.java similarity index 77% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TrimRequestWrapper.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TrimRequestWrapper.java index 00320feb..5edc5140 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/filter/TrimRequestWrapper.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/filter/TrimRequestWrapper.java @@ -1,40 +1,44 @@ -package cn.com.ttblog.ssmbootstrap_table.filter; - -import java.util.Arrays; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletRequestWrapper; - -/** - * TrimRequestWrapper 删除多余空格,装饰HttpServletRequest对象,装饰模式的使用 - * @author netbuffer - * - */ -public class TrimRequestWrapper extends HttpServletRequestWrapper { - - public TrimRequestWrapper(HttpServletRequest request) { - super(request); - } - - /** - * 重写getParameterValues方法来删除多余的空格 - */ - public String[] getParameterValues(String parameter) { - String[] results = super.getParameterValues(parameter); - if (results == null) - return null; - int count = results.length; - String[] trimResults = new String[count]; - for (int i = 0; i < count; i++) { - trimResults[i] = results[i].trim(); - } - System.out.println("过滤空格:"+Arrays.toString(trimResults)); - return trimResults; - } - /** - * 重写getParameter方法去空白 - */ - public String getParameter(String name){ - return null!=super.getParameter(name)?super.getParameter(name).trim():""; - } -} +package cn.netbuffer.ssmbootstrap_table.filter; + +import java.util.Arrays; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletRequestWrapper; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * TrimRequestWrapper 删除多余空格,装饰HttpServletRequest对象,装饰模式的使用 + * @author netbuffer + * + */ +public class TrimRequestWrapper extends HttpServletRequestWrapper { + private static final Logger trimWrapperlogger = LoggerFactory + .getLogger(TrimRequestWrapper.class); + public TrimRequestWrapper(HttpServletRequest request) { + super(request); + } + + /** + * 重写getParameterValues方法来删除多余的空格 + */ + public String[] getParameterValues(String parameter) { + String[] results = super.getParameterValues(parameter); + if (results == null) + return null; + int count = results.length; + String[] trimResults = new String[count]; + for (int i = 0; i < count; i++) { + trimResults[i] = results[i].trim(); + } + trimWrapperlogger.trace("过滤空格:"+Arrays.toString(trimResults)); + return trimResults; + } + /** + * 重写getParameter方法去空白 + */ + public String getParameter(String name){ + return null!=super.getParameter(name)?super.getParameter(name).trim():""; + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/AsyncInterceptor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/AsyncInterceptor.java new file mode 100644 index 00000000..37680f16 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/AsyncInterceptor.java @@ -0,0 +1,43 @@ +package cn.netbuffer.ssmbootstrap_table.interceptor; + +import java.util.concurrent.Callable; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.async.CallableProcessingInterceptor; + +public class AsyncInterceptor implements CallableProcessingInterceptor { + private static final Logger log=LoggerFactory.getLogger(AsyncInterceptor.class); + @Override + public void beforeConcurrentHandling(NativeWebRequest request, + Callable task) throws Exception { + log.info("beforeConcurrentHandling:{}-{}",request,task); + } + + @Override + public void preProcess(NativeWebRequest request, Callable task) + throws Exception { + log.info("preProcess:{}-{}",request,task); + } + + @Override + public void postProcess(NativeWebRequest request, Callable task, + Object concurrentResult) throws Exception { + log.info("postProcess:{}-{}-{}",request,task,concurrentResult); + } + + @Override + public Object handleTimeout(NativeWebRequest request, Callable task) + throws Exception { + log.info("handleTimeout:{}-{}",request,task); + return "timeout"; + } + + @Override + public void afterCompletion(NativeWebRequest request, Callable task) + throws Exception { + log.info("afterCompletion:{}-{}",request,task); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/DefferedAsyncInterceptor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/DefferedAsyncInterceptor.java new file mode 100644 index 00000000..cf2b638b --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/DefferedAsyncInterceptor.java @@ -0,0 +1,38 @@ +package cn.netbuffer.ssmbootstrap_table.interceptor; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.context.request.async.DeferredResult; +import org.springframework.web.context.request.async.DeferredResultProcessingInterceptor; + +public class DefferedAsyncInterceptor implements DeferredResultProcessingInterceptor { + + private static final Logger LOGGER=LoggerFactory.getLogger(DefferedAsyncInterceptor.class); + + @Override + public void beforeConcurrentHandling(NativeWebRequest nativeWebRequest, DeferredResult deferredResult) throws Exception { + LOGGER.info("before deffered request :{},deferredResult:{}",nativeWebRequest,deferredResult); + } + + @Override + public void preProcess(NativeWebRequest nativeWebRequest, DeferredResult deferredResult) throws Exception { + LOGGER.info("preProcess deffered request :{},deferredResult:{}",nativeWebRequest,deferredResult); + } + + @Override + public void postProcess(NativeWebRequest nativeWebRequest, DeferredResult deferredResult, Object o) throws Exception { + LOGGER.info("postProcess deffered request :{},deferredResult:{}",nativeWebRequest,deferredResult); + } + + @Override + public boolean handleTimeout(NativeWebRequest nativeWebRequest, DeferredResult deferredResult) throws Exception { + LOGGER.info("handleTimeout deffered request :{},deferredResult:{}",nativeWebRequest,deferredResult); + return true; + } + + @Override + public void afterCompletion(NativeWebRequest nativeWebRequest, DeferredResult deferredResult) throws Exception { + LOGGER.info("after deffered request :{},deferredResult:{}",nativeWebRequest,deferredResult); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/HandshakeInterceptor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/HandshakeInterceptor.java new file mode 100644 index 00000000..2e82ad37 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/HandshakeInterceptor.java @@ -0,0 +1,30 @@ +package cn.netbuffer.ssmbootstrap_table.interceptor; + +import java.util.Map; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.http.server.ServerHttpRequest; +import org.springframework.http.server.ServerHttpResponse; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.server.support.HttpSessionHandshakeInterceptor; + +public class HandshakeInterceptor extends HttpSessionHandshakeInterceptor { + + private static final Logger log=LoggerFactory.getLogger(HandshakeInterceptor.class); + + @Override + public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, + Map attributes) throws Exception { + log.warn("Before Handshake"); + return super.beforeHandshake(request, response, wsHandler, attributes); + } + + @Override + public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, + Exception ex) { + log.warn("After Handshake"); + super.afterHandshake(request, response, wsHandler, ex); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/MybatisPagerInterceptor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/MybatisPagerInterceptor.java new file mode 100644 index 00000000..5aff51ab --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/MybatisPagerInterceptor.java @@ -0,0 +1,53 @@ +package cn.netbuffer.ssmbootstrap_table.interceptor; + +import java.sql.Connection; +import java.util.Properties; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.apache.ibatis.executor.statement.StatementHandler; +import org.apache.ibatis.mapping.MappedStatement; +import org.apache.ibatis.plugin.Interceptor; +import org.apache.ibatis.plugin.Intercepts; +import org.apache.ibatis.plugin.Invocation; +import org.apache.ibatis.plugin.Plugin; +import org.apache.ibatis.plugin.Signature; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import cn.netbuffer.ssmbootstrap_table.util.ReflectUtil; + +/** + * mybatis拦截器 + * @author netbuffer + * + */ +@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})}) +public class MybatisPagerInterceptor implements Interceptor { + private Logger log=LoggerFactory.getLogger(getClass()); + private Properties properties; + @Override + public Object intercept(Invocation invocation) throws Throwable { + if(!Boolean.parseBoolean(properties.getProperty("enable"))){ + return invocation.proceed(); + } + log.warn("===========================执行mybatis拦截器开始==========================="); + StatementHandler stmt=(StatementHandler)invocation.getTarget(); + StatementHandler delegate = (StatementHandler)ReflectUtil.getFieldValue(stmt, "delegate"); + MappedStatement mappedStatement = (MappedStatement)ReflectUtil.getFieldValue(delegate, "mappedStatement"); + log.info("拦截到的 执行的sql-id:{}",mappedStatement.getId()); + log.info("拦截到的 sql:{},param:{}",stmt.getBoundSql().getSql(),ToStringBuilder.reflectionToString(stmt.getBoundSql().getParameterObject())); + log.warn("===========================执行mybatis拦截器完成==========================="); + return invocation.proceed(); + } + + @Override + public Object plugin(Object target) { + return Plugin.wrap(target, this); + } + + @Override + public void setProperties(Properties properties) { + log.info("set "+getClass().getName()+" properties to:{}",properties.getProperty("enable")); + this.properties=properties; + } + +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/SpringMVCInterceptor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/SpringMVCInterceptor.java new file mode 100644 index 00000000..e6e8457c --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/SpringMVCInterceptor.java @@ -0,0 +1,73 @@ +package cn.netbuffer.ssmbootstrap_table.interceptor; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.HandlerInterceptor; +import org.springframework.web.servlet.ModelAndView; +import org.springframework.web.util.UrlPathHelper; + +/** + * http://haohaoxuexi.iteye.com/blog/1750680 拦截器测试 + */ +public class SpringMVCInterceptor implements HandlerInterceptor { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + /** + * preHandle方法是进行处理器拦截用的,顾名思义,该方法将在Controller处理之前进行调用, + * SpringMVC中的Interceptor拦截器是链式的,可以同时存在 + * 多个Interceptor,然后SpringMVC会根据声明的前后顺序一个接一个的执行 + * ,而且所有的Interceptor中的preHandle方法都会在 + * Controller方法调用之前调用。SpringMVC的这种Interceptor链式结构也是可以进行中断的 + * ,这种中断方式是令preHandle的返 回值为false,当preHandle的返回值为false的时候整个请求就结束了。 + */ + @Override + public boolean preHandle(HttpServletRequest request, + HttpServletResponse response, Object handler) throws Exception { + // 拿到requet数据处理,response处理 + logger.trace("执行拦截器:{}", getClass().getName()); + UrlPathHelper ut=new UrlPathHelper(); + logger.info("ut.getLookupPathForRequest(request):{}",ut.getLookupPathForRequest(request)); + if(handler.getClass().equals(HandlerMethod.class)){ + String invokeControllerClassName=((HandlerMethod)handler).getBeanType().toString(); + String invokeControllerMethodName=((HandlerMethod)handler).getMethod().getName(); + String invokeControllerFullMethodSign=handler.toString(); + logger.info("控制器名称:{},方法名称:{},方法签名:{}.",new String[]{invokeControllerClassName,invokeControllerMethodName,invokeControllerFullMethodSign}); + } + return true; + } + + /** + * 这个方法只会在当前这个Interceptor的preHandle方法返回值为true的时候才会执行。postHandle是进行处理器拦截用的, + * 它的执行时间是在处理器进行处理之 + * 后,也就是在Controller的方法调用之后执行,但是它会在DispatcherServlet进行视图的渲染之前执行 + * ,也就是说在这个方法中你可以对ModelAndView进行操 + * 作。这个方法的链式结构跟正常访问的方向是相反的,也就是说先声明的Interceptor拦截器该方法反而会后调用 + * ,这跟Struts2里面的拦截器的执行过程有点像, + * 只是Struts2里面的intercept方法中要手动的调用ActionInvocation的invoke方法 + * ,Struts2中调用ActionInvocation的invoke方法就是调用下一个Interceptor + * 或者是调用action,然后要在Interceptor之前调用的内容都写在调用invoke之前 + * ,要在Interceptor之后调用的内容都写在调用invoke方法之后。 + */ + @Override + public void postHandle(HttpServletRequest request, + HttpServletResponse response, Object handler, + ModelAndView modelAndView) throws Exception { + } + + /** + * 该方法也是需要当前对应的Interceptor的preHandle方法的返回值为true时才会执行。该方法将在整个请求完成之后, + * 也就是DispatcherServlet渲染了视图执行, + * 这个方法的主要作用是用于清理资源的,当然这个方法也只能在当前这个Interceptor的preHandle方法的返回值为true时才会执行。 + */ + @Override + public void afterCompletion(HttpServletRequest request, + HttpServletResponse response, Object handler, Exception ex) + throws Exception { + } + +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/TokenInterceptor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/TokenInterceptor.java new file mode 100644 index 00000000..721a64e7 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/interceptor/TokenInterceptor.java @@ -0,0 +1,75 @@ +package cn.netbuffer.ssmbootstrap_table.interceptor; + +import java.lang.reflect.Method; +import java.util.UUID; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.method.HandlerMethod; +import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; +import cn.netbuffer.ssmbootstrap_table.annotation.Token; +import cn.netbuffer.ssmbootstrap_table.util.AjaxUtils; + +/** + * token form + */ +public class TokenInterceptor extends HandlerInterceptorAdapter { + + private static final Logger log = LoggerFactory.getLogger(TokenInterceptor.class); + + @Override + public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) + throws Exception { + if (handler instanceof HandlerMethod) { + HandlerMethod handlerMethod = (HandlerMethod) handler; + Method method = handlerMethod.getMethod(); + Token annotation = method.getAnnotation(Token.class); + if (annotation != null) { + boolean needSaveSession = annotation.save(); + if (needSaveSession) { + String token = UUID.randomUUID().toString(); + log.warn("生成表单token:{}", token); + request.getSession(false).setAttribute(annotation.tokenname(), token); + } + boolean needRemoveSession = annotation.remove(); + if (needRemoveSession) { + if (isRepeatSubmit(request,annotation.tokenname())) { + if(AjaxUtils.isAjaxRequest(request)){ + log.warn("ajax提交表单失败"); + response.getWriter().write("deny"); + }else{ + log.warn("提交表单失败,跳转:{}",annotation.failuri()); + request.getRequestDispatcher(annotation.failuri()).forward(request, response); + return false; + } + + } + request.getSession(false).removeAttribute(annotation.tokenname()); + } + } + return true; + } else { + return super.preHandle(request, response, handler); + } + } + + private boolean isRepeatSubmit(HttpServletRequest request,String tokenname) { + String serverToken = (String) request.getSession(false).getAttribute(tokenname); + if (serverToken == null) { + log.warn("发现重复表单提交请求serverToken==null"); + return true; + } + String clinetToken = request.getParameter(tokenname); + if (clinetToken == null) { + log.warn("发现非法请求clinetToken==null"); + return true; + } + if (!serverToken.equals(clinetToken)) { + log.warn("发现非法表单提交请求serverToken!=clinetToken"); + return true; + } + return false; + } + +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/ApplicationListener.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/ApplicationListener.java new file mode 100644 index 00000000..c3134f98 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/ApplicationListener.java @@ -0,0 +1,22 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import javax.servlet.ServletContextEvent; + +import org.springframework.web.context.ContextLoaderListener; + +/** + * 设置webroot路径 + * @author netbuffer + */ +public class ApplicationListener extends ContextLoaderListener { + + public void contextDestroyed(ServletContextEvent sce) { + } + + public void contextInitialized(ServletContextEvent sce) { + String webAppRootKey = sce.getServletContext().getRealPath("/"); + String param=sce.getServletContext().getInitParameter("webAppRootKey"); + System.setProperty(param , webAppRootKey); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/CustomCacheManagerEventListener.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/CustomCacheManagerEventListener.java new file mode 100644 index 00000000..9c6a2ffd --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/CustomCacheManagerEventListener.java @@ -0,0 +1,48 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import net.sf.ehcache.CacheException; +import net.sf.ehcache.CacheManager; +import net.sf.ehcache.Status; +import net.sf.ehcache.event.CacheManagerEventListener; + +public class CustomCacheManagerEventListener implements CacheManagerEventListener { + + private static final Logger log=LoggerFactory.getLogger(CustomCacheManagerEventListener.class); + + private final CacheManager cacheManager; + + public CustomCacheManagerEventListener(CacheManager cacheManager) { + this.cacheManager = cacheManager; + } + + @Override + public void init() throws CacheException { + log.info("init....."); + } + + @Override + public Status getStatus() { + log.info("getStatus....."); + return null; + } + + @Override + public void dispose() throws CacheException { + log.info("dispose......"); + } + + @Override + public void notifyCacheAdded(String cacheName) { + log.info("cacheAdded......." + cacheName); + log.info("getcache:{}",cacheManager.getCache(cacheName)); + } + + @Override + public void notifyCacheRemoved(String cacheName) { + log.info("cacheRemoved......" + cacheName); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/CustomCacheManagerEventListenerFactory.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/CustomCacheManagerEventListenerFactory.java new file mode 100644 index 00000000..ec708877 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/CustomCacheManagerEventListenerFactory.java @@ -0,0 +1,14 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import java.util.Properties; +import net.sf.ehcache.event.CacheManagerEventListener; +import net.sf.ehcache.event.CacheManagerEventListenerFactory; + +public class CustomCacheManagerEventListenerFactory extends CacheManagerEventListenerFactory { + + @Override + public CacheManagerEventListener createCacheManagerEventListener(Properties properties) { + return null; + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/HealthCheckServletContextListener.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/HealthCheckServletContextListener.java new file mode 100644 index 00000000..7856f911 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/HealthCheckServletContextListener.java @@ -0,0 +1,14 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import com.codahale.metrics.health.HealthCheckRegistry; +import com.codahale.metrics.servlets.HealthCheckServlet; + +public class HealthCheckServletContextListener extends HealthCheckServlet.ContextListener{ + + public static final HealthCheckRegistry HEALTH_CHECK_REGISTRY = new HealthCheckRegistry(); + + @Override + protected HealthCheckRegistry getHealthCheckRegistry() { + return HEALTH_CHECK_REGISTRY; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/LoginContextListener.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/LoginContextListener.java new file mode 100644 index 00000000..b8df0e8e --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/LoginContextListener.java @@ -0,0 +1,30 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.ApplicationListener; +import org.springframework.context.event.ContextStartedEvent; +import org.springframework.stereotype.Component; + +import cn.netbuffer.ssmbootstrap_table.event.LoginEvent; + +@Component +public class LoginContextListener implements ApplicationListener { + + private static final Logger log=LoggerFactory.getLogger(LoginContextListener.class); + + @Override + public void onApplicationEvent(ApplicationEvent e) { +// http://jinnianshilongnian.iteye.com/blog/1902886 + if (e instanceof ContextStartedEvent) { + log.warn("it was contextStartedEvent!"); + } + + if (e instanceof LoginEvent) { + log.warn("LoginEvent事件响应:{}",e.getSource()); + } + + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/LoginProcessListener.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/LoginProcessListener.java new file mode 100644 index 00000000..32a0b9fc --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/LoginProcessListener.java @@ -0,0 +1,30 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import cn.netbuffer.ssmbootstrap_table.event.LoginEvent; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationListener; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; +import java.util.concurrent.TimeUnit; + +@Component +public class LoginProcessListener implements ApplicationListener { + + private static final Logger LOG=LoggerFactory.getLogger(LoginProcessListener.class); + + /** + * @Async异步处理 + */ + @Async + @Override + public void onApplicationEvent(LoginEvent loginEvent) { + LOG.warn("开始异步记录用户登录日志"); + try { + TimeUnit.SECONDS.sleep(10); + } catch (InterruptedException e) { + LOG.error("sleep error",e); + } + LOG.warn("结束异步记录用户登录日志:{}",loginEvent); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/MetricsServletContextListener.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/MetricsServletContextListener.java new file mode 100644 index 00000000..4f65f7f6 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/MetricsServletContextListener.java @@ -0,0 +1,16 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.servlets.MetricsServlet; + +public class MetricsServletContextListener extends MetricsServlet.ContextListener { + + public static final MetricRegistry METRIC_REGISTRY = new MetricRegistry(); + + @Override + protected MetricRegistry getMetricRegistry() { + return METRIC_REGISTRY; + } + + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/TestReceiveLoginEventListener1.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/TestReceiveLoginEventListener1.java new file mode 100644 index 00000000..bc97c624 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/TestReceiveLoginEventListener1.java @@ -0,0 +1,36 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.SmartApplicationListener; +import org.springframework.stereotype.Component; +import cn.netbuffer.ssmbootstrap_table.event.LoginEvent; + +@Component +public class TestReceiveLoginEventListener1 implements SmartApplicationListener { + + private static final Logger log = LoggerFactory.getLogger(TestReceiveLoginEventListener1.class); + + @Override + public boolean supportsEventType(final Class eventType) { + return eventType == LoginEvent.class; + } + + @Override + public boolean supportsSourceType(final Class sourceType) { + //这里传具体的类才生效,测试使用Map.class无效 + return sourceType == HashMap.class; + } + + @Override + public void onApplicationEvent(final ApplicationEvent event) { + log.info("{}收到loginevent:{}" ,this.getClass().getName(), event.getSource()); + } + + @Override + public int getOrder() { + return 1; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/TestReceiveLoginEventListener2.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/TestReceiveLoginEventListener2.java new file mode 100644 index 00000000..64207774 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/listener/TestReceiveLoginEventListener2.java @@ -0,0 +1,35 @@ +package cn.netbuffer.ssmbootstrap_table.listener; + +import java.util.HashMap; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.context.ApplicationEvent; +import org.springframework.context.event.SmartApplicationListener; +import org.springframework.stereotype.Component; +import cn.netbuffer.ssmbootstrap_table.event.LoginEvent; + +@Component +public class TestReceiveLoginEventListener2 implements SmartApplicationListener { + + private static final Logger log = LoggerFactory.getLogger(TestReceiveLoginEventListener2.class); + + @Override + public boolean supportsEventType(final Class eventType) { + return eventType == LoginEvent.class; + } + + @Override + public boolean supportsSourceType(final Class sourceType) { + return sourceType == HashMap.class; + } + + @Override + public void onApplicationEvent(final ApplicationEvent event) { + log.info("{}收到loginevent:{}" ,this.getClass().getName(), ((LoginEvent)event).getSource()); + } + + @Override + public int getOrder() { + return 2; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/mbean/BeanMonitor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/mbean/BeanMonitor.java new file mode 100644 index 00000000..3dc43871 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/mbean/BeanMonitor.java @@ -0,0 +1,78 @@ +package cn.netbuffer.ssmbootstrap_table.mbean; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.jmx.export.annotation.ManagedAttribute; +import org.springframework.jmx.export.annotation.ManagedOperation; +import org.springframework.jmx.export.annotation.ManagedResource; + +/** + * http://blog.csdn.net/shirdrn/article/details/6358688 + * http://blog.csdn.net/yaerfeng/article/details/28232435 + * + * @author netbuffer 将类标记为JMX受控资源 + */ +@ManagedResource(objectName = "annojmx:myjao=BeanMonitor", description = "测试mbean使用") +public class BeanMonitor { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + private long startTime; + private long endTime; + private long duration; + + /** + * 将getter或者setter标识为部分jmx属性 + * + * @return + */ + @ManagedAttribute + public long getStartTime() { + return startTime; + } + + @ManagedAttribute + public void setStartTime(long startTime) { + logger.debug("设置starttime:{}", startTime); + this.startTime = startTime; + } + + @ManagedAttribute + public long getEndTime() { + logger.debug("获取getEndTime:{}", endTime); + return endTime; + } + + @ManagedAttribute + public void setEndTime(long endTime) { + logger.debug("设置setEndTime:{}", endTime); + this.endTime = endTime; + } + + @ManagedAttribute + public long getDuration() { + logger.debug("获取getDuration:{}", duration); + return duration; + } + + @ManagedAttribute + public void setDuration(long duration) { + logger.debug("设置setDuration:{}", duration); + this.duration = duration; + } + + /** + * jmx操作方法 + * + * @return + */ + @ManagedOperation + public String show() { + logger.debug("调用toString:{}", this); + return toString(); + } + + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Address.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Address.java new file mode 100644 index 00000000..9ec79625 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Address.java @@ -0,0 +1,42 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +import java.io.Serializable; + +public class Address implements Serializable{ + + private Long userId; + + private String province; + + private String city; + + public Long getUserId() { + return userId; + } + + public void setUserId(Long userId) { + this.userId = userId; + } + + public String getProvince() { + return province; + } + + public void setProvince(String province) { + this.province = province == null ? null : province.trim(); + } + + public String getCity() { + return city; + } + + public void setCity(String city) { + this.city = city == null ? null : city.trim(); + } + + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Card.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Card.java new file mode 100644 index 00000000..886f3633 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Card.java @@ -0,0 +1,24 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import java.io.Serializable; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import lombok.AllArgsConstructor; +import lombok.Data; +import lombok.NoArgsConstructor; + +/** + * 使用lombok简化代码 https://projectlombok.org/features/index.html + * @package cn.netbuffer.ssmbootstrap_table.model + * @author netbuffer + */ +@Data +@NoArgsConstructor +@AllArgsConstructor +public class Card implements Serializable{ + private Long userId; + private String cardNo; + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/ExtendUser.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/ExtendUser.java new file mode 100644 index 00000000..4d693fea --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/ExtendUser.java @@ -0,0 +1,20 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import java.io.Serializable; +import org.apache.commons.lang3.builder.ToStringBuilder; + +public class ExtendUser extends User implements Serializable { + + private String[] photo; + + public String[] getPhoto() { + return photo; + } + public void setPhoto(String[] photo) { + this.photo = photo; + } + + public String toString() { + return ToStringBuilder.reflectionToString(this,null,true); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/FileMsgBean.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/FileMsgBean.java new file mode 100644 index 00000000..348725c9 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/FileMsgBean.java @@ -0,0 +1,55 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +public class FileMsgBean { + private String name; + private long size; + private String url; + private String thumbnailUrl; + private String deleteUrl; + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public long getSize() { + return size; + } + + public void setSize(long size) { + this.size = size; + } + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getThumbnailUrl() { + return thumbnailUrl; + } + + public void setThumbnailUrl(String thumbnailUrl) { + this.thumbnailUrl = thumbnailUrl; + } + + public String getDeleteUrl() { + return deleteUrl; + } + + public void setDeleteUrl(String deleteUrl) { + this.deleteUrl = deleteUrl; + } + + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Menu.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Menu.java new file mode 100644 index 00000000..e5d7ea80 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/Menu.java @@ -0,0 +1,52 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import java.util.List; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +public class Menu { + + private Long id; + + private String name; + + private Long parentId; + + List menus; + + public List getMenus() { + return menus; + } + + public void setMenus(List menus) { + this.menus = menus; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name == null ? null : name.trim(); + } + + public Long getParentId() { + return parentId; + } + + public void setParentId(Long parentId) { + this.parentId = parentId; + } + + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/User.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/User.java new file mode 100644 index 00000000..aa65bb19 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/User.java @@ -0,0 +1,192 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import java.io.Serializable; +import java.util.List; +import java.util.concurrent.TimeUnit; + +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Size; +import javax.xml.bind.annotation.XmlRootElement; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.hibernate.validator.constraints.Range; + +@XmlRootElement +public class User implements Serializable { + + /** + * + */ + private static final long serialVersionUID = 4193866401992779318L; + /** + * 用户id + */ + private Long id; + @Size(min = 2, max = 6, message = "{用户名长度必须在2到6个字符之间}") + private String name; + + private String sex; + + @NotNull(message = "年龄不能为空") + @Range(min = 1, max = 150) + private Integer age; + + private String phone; + + private String deliveryaddress; + + private Integer adddate; + + private transient String comments; + + private String[] img; + + public String[] getImg() { + return img; + } + + public void setImg(String[] img) { + this.img = img; + } + + public String getComments() { + return comments; + } + + public void setComments(String comments) { + this.comments = comments; + } + + // 用户使用的地址 + List
addresses; + + private Card card; + + public Card getCard() { + return card; + } + + public void setCard(Card card) { + this.card = card; + } + + public List
getAddresses() { + return addresses; + } + + public void setAddresses(List
addresses) { + this.addresses = addresses; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name == null ? null : name.trim(); + } + + public String getSex() { + return sex; + } + + public void setSex(String sex) { + this.sex = sex == null ? null : sex.trim(); + } + + public Integer getAge() { + return age; + } + + public void setAge(Integer age) { + this.age = age; + } + + public String getPhone() { + return phone; + } + + public void setPhone(String phone) { + this.phone = phone == null ? null : phone.trim(); + } + + public String getDeliveryaddress() { + return deliveryaddress; + } + + public void setDeliveryaddress(String deliveryaddress) { + this.deliveryaddress = deliveryaddress == null ? null : deliveryaddress.trim(); + } + + public Integer getAdddate() { + return adddate; + } + + public void setAdddate(Integer adddate) { + this.adddate = adddate; + } + + public User(String name, String sex, Integer age, String phone, String deliveryaddress, Integer adddate, + String comments, List
addresses, Card card) { + super(); + this.name = name; + this.sex = sex; + this.age = age; + this.phone = phone; + this.deliveryaddress = deliveryaddress; + this.adddate = adddate; + this.comments = comments; + this.addresses = addresses; + this.card = card; + } + + public User() { + + } + + public void init(){ + System.out.println("user init!"); + } + +// public synchronized void syn(){ +// System.out.println("syn!"); +// try { +// TimeUnit.SECONDS.sleep(20); +// } catch (InterruptedException e) { +// e.printStackTrace(); +// } +// } + + public void syn(){ + synchronized(this){ + System.out.println("syn!"); + try { + TimeUnit.SECONDS.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + + public synchronized void syn2() { + System.out.println("syn2!"); + try { + TimeUnit.SECONDS.sleep(20); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + public String toString() { + //允许打印transient成员 + return ToStringBuilder.reflectionToString(this,null,true); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/model/UserListModel.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/UserListModel.java new file mode 100644 index 00000000..c90cbc70 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/UserListModel.java @@ -0,0 +1,22 @@ +package cn.netbuffer.ssmbootstrap_table.model; + +import java.util.List; +import javax.xml.bind.annotation.XmlRootElement; +import org.apache.commons.lang3.builder.ToStringBuilder; + +@XmlRootElement +public class UserListModel { + private List users; + + public List getUsers() { + return users; + } + + public void setUsers(List users) { + this.users = users; + } + + public String toString() { + return ToStringBuilder.reflectionToString(this); + } +} \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/model/User.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/query/QueryUser.java similarity index 51% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/model/User.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/model/query/QueryUser.java index dcc9af73..5558449b 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/model/User.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/model/query/QueryUser.java @@ -1,80 +1,72 @@ -package cn.com.ttblog.ssmbootstrap_table.model; - -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement -public class User { - /** - * 用户id - */ - private Long id; - - private String name; - - private String sex; - - private Integer age; - - private String phone; - - private String deliveryaddress; - - private Integer adddate; - - public Long getId() { - return id; - } - - public void setId(Long id) { - this.id = id; - } - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name == null ? null : name.trim(); - } - - public String getSex() { - return sex; - } - - public void setSex(String sex) { - this.sex = sex == null ? null : sex.trim(); - } - - public Integer getAge() { - return age; - } - - public void setAge(Integer age) { - this.age = age; - } - - public String getPhone() { - return phone; - } - - public void setPhone(String phone) { - this.phone = phone == null ? null : phone.trim(); - } - - public String getDeliveryaddress() { - return deliveryaddress; - } - - public void setDeliveryaddress(String deliveryaddress) { - this.deliveryaddress = deliveryaddress == null ? null : deliveryaddress - .trim(); - } - - public Integer getAdddate() { - return adddate; - } - - public void setAdddate(Integer adddate) { - this.adddate = adddate; - } -} \ No newline at end of file +package cn.netbuffer.ssmbootstrap_table.model.query; + +import org.apache.commons.lang3.builder.ToStringBuilder; + +/** + * 查询User实体 + * @author netbuffer + */ +public class QueryUser { + + private Long id; + private String name; + private String sex; + private Integer age; + private String phone; + private String deliveryaddress; + private Integer beginDate; + private Integer endDate; + + public Long getId() { + return id; + } + public void setId(Long id) { + this.id = id; + } + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + public String getSex() { + return sex; + } + public void setSex(String sex) { + this.sex = sex; + } + public Integer getAge() { + return age; + } + public void setAge(Integer age) { + this.age = age; + } + public String getPhone() { + return phone; + } + public void setPhone(String phone) { + this.phone = phone; + } + public String getDeliveryaddress() { + return deliveryaddress; + } + public void setDeliveryaddress(String deliveryaddress) { + this.deliveryaddress = deliveryaddress; + } + public Integer getBeginDate() { + return beginDate; + } + public void setBeginDate(Integer beginDate) { + this.beginDate = beginDate; + } + public Integer getEndDate() { + return endDate; + } + public void setEndDate(Integer endDate) { + this.endDate = endDate; + } + + public String toString(){ + return ToStringBuilder.reflectionToString(this); + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/service/IMenuService.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/service/IMenuService.java new file mode 100644 index 00000000..3519372d --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/service/IMenuService.java @@ -0,0 +1,7 @@ +package cn.netbuffer.ssmbootstrap_table.service; + +import cn.netbuffer.ssmbootstrap_table.model.Menu; + +public interface IMenuService { + public void addMenu(Menu m); +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/service/IUserService.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/service/IUserService.java new file mode 100644 index 00000000..5083f752 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/service/IUserService.java @@ -0,0 +1,22 @@ +package cn.netbuffer.ssmbootstrap_table.service; + +import java.util.List; +import java.util.Map; + +import cn.netbuffer.ssmbootstrap_table.model.User; + +public interface IUserService { + public User getUserById(long userId); + public User getUserByName(String userName); + public void addUser(User user); + public List getUserList(String order, int limit, int offset); + //带有查询条件 + public List getUserList(String search, String order, int limit,int offset); + public long getUserListCount(); + public int getNewData(); + public List> getDataSum(); + public void addUM(); + public void addUMtest() throws IllegalArgumentException; + public void deleteById(Long id); + void execute(); +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/serviceimpl/MenuServiceImpl.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/serviceimpl/MenuServiceImpl.java new file mode 100644 index 00000000..7e7c733c --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/serviceimpl/MenuServiceImpl.java @@ -0,0 +1,23 @@ +package cn.netbuffer.ssmbootstrap_table.serviceimpl; + +import javax.annotation.Resource; + +import cn.netbuffer.ssmbootstrap_table.dao.IMenuDao; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Service; + +import cn.netbuffer.ssmbootstrap_table.model.Menu; +import cn.netbuffer.ssmbootstrap_table.service.IMenuService; + +@Service("menuService") +public class MenuServiceImpl implements IMenuService { + private Logger logger=LoggerFactory.getLogger(getClass()); + @Resource + private IMenuDao menuDao; + @Override + public void addMenu(Menu m) { + menuDao.insert(m); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/serviceimpl/UserServiceImpl.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/serviceimpl/UserServiceImpl.java new file mode 100644 index 00000000..6847aa3a --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/serviceimpl/UserServiceImpl.java @@ -0,0 +1,144 @@ +package cn.netbuffer.ssmbootstrap_table.serviceimpl; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; +import java.util.concurrent.TimeUnit; + +import javax.annotation.Resource; + +import cn.netbuffer.ssmbootstrap_table.dao.IMenuDao; +import cn.netbuffer.ssmbootstrap_table.dao.IUserDao; +import org.apache.commons.lang3.RandomStringUtils; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.mybatis.spring.SqlSessionTemplate; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.cache.annotation.Cacheable; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; +import org.springframework.transaction.interceptor.TransactionAspectSupport; + +import cn.netbuffer.ssmbootstrap_table.model.Menu; +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; + +@Service("userService") +public class UserServiceImpl implements IUserService { + private Logger logger=LoggerFactory.getLogger(getClass()); + /** + * @resource 是按照name注入,@autowired是按照type注入 + */ + @Resource + private IUserDao userDao; + @Resource + private SqlSessionTemplate sqlSession; + @Resource + private IMenuDao menuDao; + +// @Cacheable(value = { "userCache" }) + @Override + public User getUserById(long userId) { + return this.userDao.selectByPrimaryKey(userId); + } + + @Override + public void addUser(User user) { + Random r = new Random(); + sqlSession.insert(IUserDao.class.getName() + ".insert", user); + // 事务测试 +// int i=1/0; + } + + @Override + public void addUM(){ + System.out.println(String.format("tran1:%s %n tran1detail:%s", TransactionAspectSupport.currentTransactionStatus().toString(),ToStringBuilder.reflectionToString(TransactionAspectSupport.currentTransactionStatus()))); + User u=new User(); + u.setName(RandomStringUtils.randomAlphabetic(4)); + addUser(u); + Menu m=new Menu(); + m.setName(RandomStringUtils.randomAlphabetic(4)); + menuDao.insert(m); + System.out.println(String.format("tran2:%s %n tran2detail:%s", TransactionAspectSupport.currentTransactionStatus().toString(),ToStringBuilder.reflectionToString(TransactionAspectSupport.currentTransactionStatus()))); + throw new RuntimeException("error"); + } + +// @Transactional + @Override + public void addUMtest() throws IllegalArgumentException { + User u=new User(); + u.setName(RandomStringUtils.randomAlphabetic(4)); + addUser(u); + Menu m=new Menu(); + m.setName(RandomStringUtils.randomAlphabetic(4)); + menuDao.insert(m); + throw new IllegalArgumentException("test"); + } + + /** + * getUserList + * @param order order by adddate ${order} asc desc + */ + @Cacheable(value = { "userCache" }) + @Override + public List getUserList(String order, int limit, int offset) { + Map params = new HashMap(); + params.put("order", order); + params.put("limit", limit); + params.put("offset", offset); + return sqlSession.selectList(IUserDao.class.getName() + ".selectList", + params); + } + +// @Cacheable(value = { "userCache" }) + @Override + public List getUserList(String search, String order, int limit, + int offset) { + Map params = new HashMap(); + params.put("order", order); + params.put("limit", limit); + params.put("offset", offset); + params.put("search", search); + return sqlSession.selectList(IUserDao.class.getName() + ".selectListWithQuery", + params); + } + + @Override + public long getUserListCount() { + return userDao.getUserListCount(); + } + + @Override + public int getNewData() { + return userDao.getNewData(); + } + + @Override + public List> getDataSum() { + return userDao.getDataSum(); + } + + @Override + public void deleteById(Long id) { + userDao.deleteById(id); + } + + @Override + public User getUserByName(String userName) { + return userDao.selectByName(userName); + } + + @Async + @Override + public void execute() { + logger.warn("异步方法开始执行"); + try { + TimeUnit.SECONDS.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + logger.warn("异步方法结束执行"); + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/servlet/TestServlet.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/servlet/TestServlet.java new file mode 100644 index 00000000..6d35801c --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/servlet/TestServlet.java @@ -0,0 +1,26 @@ +package cn.netbuffer.ssmbootstrap_table.servlet; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import javax.servlet.ServletException; +import javax.servlet.annotation.WebServlet; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import java.io.IOException; + +@WebServlet(name = "Servlet",urlPatterns = "/testservlet") +public class TestServlet extends HttpServlet{ + + private static final Logger LOG= LoggerFactory.getLogger(TestServlet.class); + + protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + + } + + protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + LOG.debug("doget"); + response.getWriter().write("hello"); + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/AjaxUtils.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/AjaxUtils.java new file mode 100644 index 00000000..ac3b3de6 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/AjaxUtils.java @@ -0,0 +1,52 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import java.net.InetAddress; +import java.net.UnknownHostException; + +import javax.servlet.http.HttpServletRequest; + +import org.springframework.web.context.request.WebRequest; + +public class AjaxUtils { + + public static boolean isAjaxRequest(WebRequest webRequest) { + String requestedWith = webRequest.getHeader("X-Requested-With"); + return requestedWith != null ? "XMLHttpRequest".equals(requestedWith) + : false; + } + + public static boolean isAjaxRequest(HttpServletRequest webRequest) { + String requestedWith = webRequest.getHeader("X-Requested-With"); + return requestedWith != null ? "XMLHttpRequest".equals(requestedWith) + : false; + } + + public static boolean isAjaxUploadRequest(WebRequest webRequest) { + return webRequest.getParameter("ajaxUpload") != null; + } + + public static String getLocalIP() { + InetAddress addr = null; + try { + addr = InetAddress.getLocalHost(); + } catch (UnknownHostException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + byte[] ipAddr = addr.getAddress(); + String ipAddrStr = ""; + for (int i = 0; i < ipAddr.length; i++) { + if (i > 0) { + ipAddrStr += "."; + } + ipAddrStr += ipAddr[i] & 0xFF; + } + // System.out.println(ipAddrStr); + return ipAddrStr; + } + + private AjaxUtils() { + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/AntPathMatcherUtil.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/AntPathMatcherUtil.java new file mode 100644 index 00000000..ce38a31a --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/AntPathMatcherUtil.java @@ -0,0 +1,27 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.util.AntPathMatcher; + +public class AntPathMatcherUtil { + + private static final AntPathMatcher ap = new AntPathMatcher(); + private static final Logger LOG=LoggerFactory.getLogger(AntPathMatcherUtil.class); + + public static boolean isMatch(String[] mapping,String uri){ + if(mapping==null||mapping.length==0){ + throw new IllegalArgumentException("mapping不能为空"); + } + for(String m:mapping){ + if(m.length()>0){ + String ms=m.trim(); + if(ap.match(ms,uri)){ + LOG.warn("匹配:{}---{}",ms,uri); + return true; + } + } + } + return false; + } +} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/BeanMapUtil.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/BeanMapUtil.java similarity index 93% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/util/BeanMapUtil.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/util/BeanMapUtil.java index 4db1ad2f..97856112 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/BeanMapUtil.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/BeanMapUtil.java @@ -1,57 +1,57 @@ -package cn.com.ttblog.ssmbootstrap_table.util; - -import java.beans.BeanInfo; -import java.beans.Introspector; -import java.beans.PropertyDescriptor; -import java.lang.reflect.Method; -import java.util.LinkedHashMap; -import java.util.Map; - -public class BeanMapUtil { - public static void transMap2Bean(Map map, Object obj) { - try { - BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); - PropertyDescriptor[] propertyDescriptors = beanInfo - .getPropertyDescriptors(); - for (PropertyDescriptor property : propertyDescriptors) { - String key = property.getName(); - - if (map.containsKey(key)) { - Object value = map.get(key); - // 得到property对应的setter方法 - Method setter = property.getWriteMethod(); - setter.invoke(obj, value); - } - } - - } catch (Exception e) { - System.out.println("transMap2Bean Error " + e); - } - return; - } - public static Map transBean2Map(Object obj) { - if (obj == null) { - return null; - } - Map map = new LinkedHashMap(); - try { - BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); - PropertyDescriptor[] propertyDescriptors = beanInfo - .getPropertyDescriptors(); - for (PropertyDescriptor property : propertyDescriptors) { - String key = property.getName(); - // 过滤class属性 - if (!key.equals("class")) { - // 得到property对应的getter方法 - Method getter = property.getReadMethod(); - Object value = getter.invoke(obj); - map.put(key, value); - } - - } - } catch (Exception e) { - System.out.println("transBean2Map Error " + e); - } - return map; - } -} +package cn.netbuffer.ssmbootstrap_table.util; + +import java.beans.BeanInfo; +import java.beans.Introspector; +import java.beans.PropertyDescriptor; +import java.lang.reflect.Method; +import java.util.LinkedHashMap; +import java.util.Map; + +public class BeanMapUtil { + public static void transMap2Bean(Map map, Object obj) { + try { + BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo + .getPropertyDescriptors(); + for (PropertyDescriptor property : propertyDescriptors) { + String key = property.getName(); + + if (map.containsKey(key)) { + Object value = map.get(key); + // 得到property对应的setter方法 + Method setter = property.getWriteMethod(); + setter.invoke(obj, value); + } + } + + } catch (Exception e) { + System.out.println("transMap2Bean Error " + e); + } + return; + } + public static Map transBean2Map(Object obj) { + if (obj == null) { + return null; + } + Map map = new LinkedHashMap(); + try { + BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); + PropertyDescriptor[] propertyDescriptors = beanInfo + .getPropertyDescriptors(); + for (PropertyDescriptor property : propertyDescriptors) { + String key = property.getName(); + // 过滤class属性 + if (!key.equals("class")) { + // 得到property对应的getter方法 + Method getter = property.getReadMethod(); + Object value = getter.invoke(obj); + map.put(key, value); + } + + } + } catch (Exception e) { + System.out.println("transBean2Map Error " + e); + } + return map; + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/Config.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/Config.java new file mode 100644 index 00000000..8b78c10c --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/Config.java @@ -0,0 +1,48 @@ +//package cn.netbuffer.ssmbootstrap_table.util; +// +//import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler; +//import org.springframework.context.annotation.Configuration; +//import org.springframework.scheduling.annotation.AsyncConfigurer; +//import org.springframework.scheduling.annotation.EnableAsync; +//import java.lang.reflect.Method; +//import java.util.concurrent.Executor; +//import java.util.concurrent.ExecutorService; +//import java.util.concurrent.Executors; +//import java.util.concurrent.ThreadFactory; +// +///** +// * 启用异步方法 +// * 发现在xml中配置不生效, +// * 基于java config是生效的 +// * http://docs.spring.io/spring/docs/current/javadoc-api/org/springframework/scheduling/annotation/EnableAsync.html +// * http://docs.spring.io/spring/docs/4.2.9.RELEASE/spring-framework-reference/htmlsingle/#scheduling-annotation-support-async +// */ +//@Configuration +//@EnableAsync +//public class Config implements AsyncConfigurer { +// +// /** +// * 自定义实现Executor +// * @return +// */ +// @Override +// public Executor getAsyncExecutor() { +// ExecutorService executorService=Executors.newSingleThreadExecutor(new ThreadFactory() { +// @Override +// public Thread newThread(Runnable r) { +// return new Thread(r,"task"); +// } +// }); +// return executorService; +// } +// +// @Override +// public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() { +// return new AsyncUncaughtExceptionHandler() { +// @Override +// public void handleUncaughtException(Throwable throwable, Method method, Object... objects) { +// System.out.printf("throwable:%s,method:%s,objects:%s",throwable,method,objects); +// } +// }; +// } +//} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/DateUtils.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/DateUtils.java new file mode 100644 index 00000000..bdffffdf --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/DateUtils.java @@ -0,0 +1,457 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import java.text.SimpleDateFormat; +import java.util.Calendar; +import java.util.Date; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * http://blog.csdn.net/dreamthen/article/details/8447332 + * @author zengms + * @date 2012-12-27 + * + */ +public class DateUtils { + + private static final Log logger = LogFactory.getLog(DateUtils.class); + + public static final String YYYYMMDD = "yyyy-MM-dd"; + + public static final String YYYYMMDD_ZH = "yyyy年MM月dd日"; + + public static final int FIRST_DAY_OF_WEEK = Calendar.MONDAY; // 中国周一是一周的第一天 + + /** + * + * @param strDate + * @return + */ + public static Date parseDate(String strDate) { + return parseDate(strDate, null); + } + + /** + * parseDate + * + * @param strDate + * @param pattern + * @return + */ + public static Date parseDate(String strDate, String pattern) { + Date date = null; + try { + if (pattern == null) { + pattern = YYYYMMDD; + } + SimpleDateFormat format = new SimpleDateFormat(pattern); + date = format.parse(strDate); + } catch (Exception e) { + logger.error("parseDate error:" + e); + } + return date; + } + + /** + * format date + * + * @param date + * @return + */ + public static String formatDate(Date date) { + return formatDate(date, null); + } + + /** + * format date + * + * @param date + * @param pattern + * @return + */ + public static String formatDate(Date date, String pattern) { + String strDate = null; + try { + if (pattern == null) { + pattern = YYYYMMDD; + } + SimpleDateFormat format = new SimpleDateFormat(pattern); + strDate = format.format(date); + } catch (Exception e) { + logger.error("formatDate error:", e); + } + return strDate; + } + + /** + * 取得日期:年 + * + * @param date + * @return + */ + public static int getYear(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + int year = c.get(Calendar.YEAR); + return year; + } + + /** + * 取得日期:年 + * + * @param date + * @return + */ + public static int getMonth(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + int month = c.get(Calendar.MONTH); + return month + 1; + } + + /** + * 取得日期:年 + * + * @param date + * @return + */ + public static int getDay(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + int da = c.get(Calendar.DAY_OF_MONTH); + return da; + } + + /** + * 取得当天日期是周几 + * + * @param date + * @return + */ + public static int getWeekDay(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + int week_of_year = c.get(Calendar.DAY_OF_WEEK); + return week_of_year - 1; + } + + /** + * 取得一年的第几周 + * + * @param date + * @return + */ + public static int getWeekOfYear(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + int week_of_year = c.get(Calendar.WEEK_OF_YEAR); + return week_of_year; + } + + /** + * getWeekBeginAndEndDate + * + * @param date + * @param pattern + * @return + */ + public static String getWeekBeginAndEndDate(Date date, String pattern) { + Date monday = getMondayOfWeek(date); + Date sunday = getSundayOfWeek(date); + return formatDate(monday, pattern) + " - " + + formatDate(sunday, pattern); + } + + /** + * 根据日期取得对应周周一日期 + * + * @param date + * @return + */ + public static Date getMondayOfWeek(Date date) { + Calendar monday = Calendar.getInstance(); + monday.setTime(date); + monday.setFirstDayOfWeek(FIRST_DAY_OF_WEEK); + monday.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + return monday.getTime(); + } + + /** + * 根据日期取得对应周周日日期 + * + * @param date + * @return + */ + public static Date getSundayOfWeek(Date date) { + Calendar sunday = Calendar.getInstance(); + sunday.setTime(date); + sunday.setFirstDayOfWeek(FIRST_DAY_OF_WEEK); + sunday.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY); + return sunday.getTime(); + } + + /** + * 取得月的剩余天数 + * + * @param date + * @return + */ + public static int getRemainDayOfMonth(Date date) { + int dayOfMonth = getDayOfMonth(date); + int day = getPassDayOfMonth(date); + return dayOfMonth - day; + } + + /** + * 取得月已经过的天数 + * + * @param date + * @return + */ + public static int getPassDayOfMonth(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + return c.get(Calendar.DAY_OF_MONTH); + } + + /** + * 取得月天数 + * + * @param date + * @return + */ + public static int getDayOfMonth(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + return c.getActualMaximum(Calendar.DAY_OF_MONTH); + } + + /** + * 取得月第一天 + * + * @param date + * @return + */ + public static Date getFirstDateOfMonth(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.set(Calendar.DAY_OF_MONTH, c.getActualMinimum(Calendar.DAY_OF_MONTH)); + return c.getTime(); + } + + /** + * 取得月最后一天 + * + * @param date + * @return + */ + public static Date getLastDateOfMonth(Date date) { + Calendar c = Calendar.getInstance(); + c.setTime(date); + c.set(Calendar.DAY_OF_MONTH, c.getActualMaximum(Calendar.DAY_OF_MONTH)); + return c.getTime(); + } + + /** + * 取得季度第一天 + * + * @param date + * @return + */ + public static Date getFirstDateOfSeason(Date date) { + return getFirstDateOfMonth(getSeasonDate(date)[0]); + } + + /** + * 取得季度最后一天 + * + * @param date + * @return + */ + public static Date getLastDateOfSeason(Date date) { + return getLastDateOfMonth(getSeasonDate(date)[2]); + } + + /** + * 取得季度天数 + * + * @param date + * @return + */ + public static int getDayOfSeason(Date date) { + int day = 0; + Date[] seasonDates = getSeasonDate(date); + for (Date date2 : seasonDates) { + day += getDayOfMonth(date2); + } + return day; + } + + /** + * 取得季度剩余天数 + * + * @param date + * @return + */ + public static int getRemainDayOfSeason(Date date) { + return getDayOfSeason(date) - getPassDayOfSeason(date); + } + + /** + * 取得季度已过天数 + * + * @param date + * @return + */ + public static int getPassDayOfSeason(Date date) { + int day = 0; + + Date[] seasonDates = getSeasonDate(date); + + Calendar c = Calendar.getInstance(); + c.setTime(date); + int month = c.get(Calendar.MONTH); + + if (month == Calendar.JANUARY || month == Calendar.APRIL + || month == Calendar.JULY || month == Calendar.OCTOBER) {// 季度第一个月 + day = getPassDayOfMonth(seasonDates[0]); + } else if (month == Calendar.FEBRUARY || month == Calendar.MAY + || month == Calendar.AUGUST || month == Calendar.NOVEMBER) {// 季度第二个月 + day = getDayOfMonth(seasonDates[0]) + + getPassDayOfMonth(seasonDates[1]); + } else if (month == Calendar.MARCH || month == Calendar.JUNE + || month == Calendar.SEPTEMBER || month == Calendar.DECEMBER) {// 季度第三个月 + day = getDayOfMonth(seasonDates[0]) + getDayOfMonth(seasonDates[1]) + + getPassDayOfMonth(seasonDates[2]); + } + return day; + } + + /** + * 取得季度月 + * + * @param date + * @return + */ + public static Date[] getSeasonDate(Date date) { + Date[] season = new Date[3]; + + Calendar c = Calendar.getInstance(); + c.setTime(date); + + int nSeason = getSeason(date); + if (nSeason == 1) {// 第一季度 + c.set(Calendar.MONTH, Calendar.JANUARY); + season[0] = c.getTime(); + c.set(Calendar.MONTH, Calendar.FEBRUARY); + season[1] = c.getTime(); + c.set(Calendar.MONTH, Calendar.MARCH); + season[2] = c.getTime(); + } else if (nSeason == 2) {// 第二季度 + c.set(Calendar.MONTH, Calendar.APRIL); + season[0] = c.getTime(); + c.set(Calendar.MONTH, Calendar.MAY); + season[1] = c.getTime(); + c.set(Calendar.MONTH, Calendar.JUNE); + season[2] = c.getTime(); + } else if (nSeason == 3) {// 第三季度 + c.set(Calendar.MONTH, Calendar.JULY); + season[0] = c.getTime(); + c.set(Calendar.MONTH, Calendar.AUGUST); + season[1] = c.getTime(); + c.set(Calendar.MONTH, Calendar.SEPTEMBER); + season[2] = c.getTime(); + } else if (nSeason == 4) {// 第四季度 + c.set(Calendar.MONTH, Calendar.OCTOBER); + season[0] = c.getTime(); + c.set(Calendar.MONTH, Calendar.NOVEMBER); + season[1] = c.getTime(); + c.set(Calendar.MONTH, Calendar.DECEMBER); + season[2] = c.getTime(); + } + return season; + } + + /** + * + * 1 第一季度 2 第二季度 3 第三季度 4 第四季度 + * + * @param date + * @return + */ + public static int getSeason(Date date) { + + int season = 0; + + Calendar c = Calendar.getInstance(); + c.setTime(date); + int month = c.get(Calendar.MONTH); + switch (month) { + case Calendar.JANUARY: + case Calendar.FEBRUARY: + case Calendar.MARCH: + season = 1; + break; + case Calendar.APRIL: + case Calendar.MAY: + case Calendar.JUNE: + season = 2; + break; + case Calendar.JULY: + case Calendar.AUGUST: + case Calendar.SEPTEMBER: + season = 3; + break; + case Calendar.OCTOBER: + case Calendar.NOVEMBER: + case Calendar.DECEMBER: + season = 4; + break; + default: + break; + } + return season; + } + + public static void main(String[] args) { + + String strDate = "2013-01-01"; + + Date date = parseDate(strDate); + + System.out.println(strDate + " 今天是哪一年?" + getYear(date)); + System.out.println(strDate + " 今天是哪个月?" + getMonth(date)); + System.out.println(strDate + " 今天是几号?" + getDay(date)); + System.out.println(strDate + " 今天是周几?" + getWeekDay(date)); + System.out.println(strDate + " 是一年的第几周?" + getWeekOfYear(date)); + System.out.println(strDate + " 所在周起始结束日期?" + + getWeekBeginAndEndDate(date, "yyyy年MM月dd日")); + System.out.println(strDate + " 所在周周一是?" + + formatDate(getMondayOfWeek(date))); + System.out.println(strDate + " 所在周周日是?" + + formatDate(getSundayOfWeek(date))); + + System.out.println(strDate + " 当月第一天日期?" + + formatDate(getFirstDateOfMonth(date))); + System.out.println(strDate + " 当月最后一天日期?" + + formatDate(getLastDateOfMonth(date))); + System.out.println(strDate + " 当月天数?" + getDayOfMonth(date)); + System.out.println(strDate + " 当月已过多少天?" + getPassDayOfMonth(date)); + System.out.println(strDate + " 当月剩余多少天?" + getRemainDayOfMonth(date)); + + System.out.println(strDate + " 所在季度第一天日期?" + + formatDate(getFirstDateOfSeason(date))); + System.out.println(strDate + " 所在季度最后一天日期?" + + formatDate(getLastDateOfSeason(date))); + System.out.println(strDate + " 所在季度天数?" + getDayOfSeason(date)); + System.out.println(strDate + " 所在季度已过多少天?" + getPassDayOfSeason(date)); + System.out + .println(strDate + " 所在季度剩余多少天?" + getRemainDayOfSeason(date)); + System.out.println(strDate + " 是第几季度?" + getSeason(date)); + System.out.println(strDate + " 所在季度月份?" + + formatDate(getSeasonDate(date)[0], "yyyy年MM月") + "/" + + formatDate(getSeasonDate(date)[1], "yyyy年MM月") + "/" + + formatDate(getSeasonDate(date)[2], "yyyy年MM月")); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/JodaTimeUtil.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/JodaTimeUtil.java new file mode 100644 index 00000000..1c5d60b6 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/JodaTimeUtil.java @@ -0,0 +1,138 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import org.joda.time.DateTime; + +/** + * @author netbuffer + */ +public class JodaTimeUtil { + + /** + * 本周开始时间 + * + * @param d + * @return + */ + public static DateTime getWeekStart(DateTime d) { + int day = d.getDayOfWeek(); + int min = d.dayOfWeek().getMinimumValue(); + return d.plusDays(-(day - min)); + } + + /** + * 本周结束时间 + * + * @param d + * @return + */ + public static DateTime getWeekEnd(DateTime d) { + int day = d.getDayOfWeek(); + int max = d.dayOfWeek().getMaximumValue(); + return d.plusDays((max - day)); + } + + /** + * 本月开始时间 + * + * @param d + * @return + */ + public static DateTime getMonthStart(DateTime d) { + int day = d.getDayOfMonth(); + int min = d.dayOfMonth().getMinimumValue(); + return d.plusDays(-(day - min)); + } + + /** + * 本月结束时间 + * + * @param d + * @return + */ + public static DateTime getMonthEnd(DateTime d) { + int day = d.getDayOfMonth(); + int max = d.dayOfMonth().getMaximumValue(); + return d.plusDays((max - day)); + } + + /** + * 本季度开始时间 + * @param d + * @return + */ + public static DateTime getSeasonStart(DateTime d) { + int season=getSeason(d); + switch (season) { + case 1: + return new DateTime(d.getYear(),1,1,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + case 2: + return new DateTime(d.getYear(),4,1,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + case 3: + return new DateTime(d.getYear(),7,1,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + case 4: + return new DateTime(d.getYear(),10,1,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + default: + return new DateTime(d.getYear(),1,1,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + } + } + + /** + * 本季度结束时间 + * @param d + * @return + */ + public static DateTime getSeasonEnd(DateTime d) { + int season=getSeason(d); + switch (season) { + case 1: + return new DateTime(d.getYear(),3,31,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + case 2: + return new DateTime(d.getYear(),6,30,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + case 3: + return new DateTime(d.getYear(),9,30,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + case 4: + return new DateTime(d.getYear(),12,31,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + default: + return new DateTime(d.getYear(),3,31,d.getHourOfDay(),d.getMinuteOfHour(),d.getSecondOfMinute()); + } + } + + /* + * 获取季度 + */ + public static int getSeason(DateTime d) { + int season=0; + int month=d.getMonthOfYear(); + if (month >= 1 && month <= 3) { + season = 1; + } + if (month >= 4 && month <= 6) { + season = 2; + } + if (month >= 7 && month <= 9) { + season = 3; + } + if (month >= 10 && month <= 12) { + season = 4; + } + return season; + } + + /** + * 本年开始时间 + * @param d + * @return + */ + public static DateTime getYearStart(DateTime d) { + return new DateTime(d.getYear(),1,1,0,0,0); + } + + /** + * 本年结束时间 + * @param d + * @return + */ + public static DateTime getYearEnd(DateTime d) { + return new DateTime(d.getYear(),12,31,23,59,59); + } +} diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/LongToDateTag.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/LongToDateTag.java similarity index 73% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/util/LongToDateTag.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/util/LongToDateTag.java index d46166f4..755a381d 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/LongToDateTag.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/LongToDateTag.java @@ -1,42 +1,36 @@ -package cn.com.ttblog.ssmbootstrap_table.util; - -import java.io.IOException; -import java.text.SimpleDateFormat; -import java.util.Date; - -import javax.servlet.jsp.JspException; -import javax.servlet.jsp.tagext.SimpleTagSupport; -/** - * 自定义标签开发 - * 教程:http://www.runoob.com/jsp/jsp-custom-tags.html - * @author netbuffer - * - */ -public class LongToDateTag extends SimpleTagSupport { - private Object value; - public Object getValue() { - return value; - } - public void setValue(Object value) { - this.value = value; - } - public String getFormat() { - return format; - } - public void setFormat(String format) { - this.format = format; - } - private String format; - public void doTag() throws JspException, IOException { - if(getValue()!=null&&getFormat()!=null){ - SimpleDateFormat fmt=new SimpleDateFormat(getFormat()); - getJspContext().getOut().print(fmt.format(new Date((long)getValue()))); - } - - } - public static void main(String[] args) { - long s=1454491047609L; - System.out.println(new Date(s).toGMTString()); - } - +package cn.netbuffer.ssmbootstrap_table.util; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import javax.servlet.jsp.JspException; +import javax.servlet.jsp.tagext.SimpleTagSupport; +/** + * 自定义标签开发 + * 教程:http://www.runoob.com/jsp/jsp-custom-tags.html + * @author netbuffer + * + */ +public class LongToDateTag extends SimpleTagSupport { + private Object value; + public Object getValue() { + return value; + } + public void setValue(Object value) { + this.value = value; + } + public String getFormat() { + return format; + } + public void setFormat(String format) { + this.format = format; + } + private String format; + public void doTag() throws JspException, IOException { + if(getValue()!=null&&getFormat()!=null){ + SimpleDateFormat fmt=new SimpleDateFormat(getFormat()); + getJspContext().getOut().print(fmt.format(new Date(Long.parseLong(getValue().toString())))); + } + + } } \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/LongToDateTag.tld b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/LongToDateTag.tld similarity index 82% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/util/LongToDateTag.tld rename to src/main/java/cn/netbuffer/ssmbootstrap_table/util/LongToDateTag.tld index da07bed9..799549e1 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/LongToDateTag.tld +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/LongToDateTag.tld @@ -1,24 +1,24 @@ - - 1.0 - 2.0 - Example TLD with Body - - l2d - convert long to date - cn.com.ttblog.jfinal_bootstrap_table.util.LongToDateTag - - empty - - value - true - java.lang.Object - true - - - format - true - java.lang.String - true - - + + 1.0 + 2.0 + Example TLD with Body + + l2d + convert long to date + cn.netbuffer.ssmbootstrap_table.util.LongToDateTag + + empty + + value + true + java.lang.Object + true + + + format + true + java.lang.String + true + + \ No newline at end of file diff --git a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/POIExcelUtil.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/POIExcelUtil.java similarity index 92% rename from src/main/java/cn/com/ttblog/ssmbootstrap_table/util/POIExcelUtil.java rename to src/main/java/cn/netbuffer/ssmbootstrap_table/util/POIExcelUtil.java index 0413f481..d6237e09 100644 --- a/src/main/java/cn/com/ttblog/ssmbootstrap_table/util/POIExcelUtil.java +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/POIExcelUtil.java @@ -1,169 +1,171 @@ -package cn.com.ttblog.ssmbootstrap_table.util; - -import java.io.FileOutputStream; -import java.io.IOException; -import java.util.HashMap; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.poi.hssf.usermodel.HSSFWorkbook; -import org.apache.poi.ss.usermodel.Cell; -import org.apache.poi.ss.usermodel.CellStyle; -import org.apache.poi.ss.usermodel.CreationHelper; -import org.apache.poi.ss.usermodel.Font; -import org.apache.poi.ss.usermodel.Hyperlink; -import org.apache.poi.ss.usermodel.IndexedColors; -import org.apache.poi.ss.usermodel.Row; -import org.apache.poi.ss.usermodel.Sheet; -import org.apache.poi.ss.usermodel.Workbook; -import org.apache.poi.ss.util.CellUtil; - -public class POIExcelUtil { - public static void exec(String path) { - Workbook wb = new HSSFWorkbook(); // or new XSSFWorkbook(); - CreationHelper createHelper = wb.getCreationHelper(); - Sheet sheet = wb.createSheet("用户信息"); - // 冻结该行,使其无法移动 - sheet.createFreezePane(0, 1, 0, 1); - // Header header = sheet1.getHeader(); - // header.setCenter("Center Header"); - // header.setLeft("Left Header"); - // header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + - // HSSFHeader.fontSize((short) 16) + - // "Right w/ Stencil-Normal Italic font and size 16"); - Row row = sheet.createRow((short) 0); - row.setHeightInPoints(30); - Cell cell = row.createCell(0); - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(CellStyle.ALIGN_CENTER); - cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); - cell.setCellValue("用户昵称"); - cell.setCellStyle(cellStyle); - row.createCell(1).setCellValue("用户性别"); - - CellStyle hlink_style = wb.createCellStyle(); - Font hlink_font = wb.createFont(); - hlink_font.setUnderline(Font.U_SINGLE); - hlink_font.setColor(IndexedColors.BLUE.getIndex()); - hlink_style.setFont(hlink_font); - hlink_style.setAlignment(CellStyle.ALIGN_CENTER); - hlink_style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); - Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL); - link.setAddress("http://poi.apache.org/"); - cell.setHyperlink(link); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_TOP, CellStyle.BORDER_MEDIUM); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_MEDIUM); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_LEFT, CellStyle.BORDER_MEDIUM); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_RIGHT, CellStyle.BORDER_MEDIUM); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.TOP_BORDER_COLOR,IndexedColors.RED.getIndex()); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.BOTTOM_BORDER_COLOR, IndexedColors.RED.getIndex()); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.LEFT_BORDER_COLOR,IndexedColors.RED.getIndex()); - CellUtil.setCellStyleProperty(cell, wb, CellUtil.RIGHT_BORDER_COLOR, IndexedColors.RED.getIndex()); - row.createCell(2).setCellValue( - createHelper.createRichTextString("This is a string用户年龄")); - row.createCell(3).setCellValue("用户手机"); - row.createCell(4).setCellValue("收货地址"); - row.createCell(5).setCellValue("注册时间"); - sheet.autoSizeColumn(0); // adjust width of the first column - sheet.autoSizeColumn(1); - sheet.autoSizeColumn(2); - sheet.autoSizeColumn(3); - sheet.autoSizeColumn(4); - - FileOutputStream fileOut; - try { - fileOut = new FileOutputStream(path); - wb.write(fileOut); - fileOut.close(); - } catch (IOException e) { - e.printStackTrace(); - } - - } - - public static void export(List titles,List> datas,String path) { - Workbook wb = new HSSFWorkbook(); - CreationHelper createHelper = wb.getCreationHelper(); - Sheet sheet = wb.createSheet(titles.get(0)); - // 冻结该行,使其无法移动 - sheet.createFreezePane(0, 1, 0, 1); - // Header header = sheet1.getHeader(); - // header.setCenter("Center Header"); - // header.setLeft("Left Header"); - // header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + - // HSSFHeader.fontSize((short) 16) + - // "Right w/ Stencil-Normal Italic font and size 16"); - Row row = sheet.createRow((short) 0); - row.setHeightInPoints(30); - int titleCount=titles.size(); - Font titleFont=wb.createFont(); - titleFont.setBold(true); - titleFont.setColor(IndexedColors.AQUA.getIndex()); - CellStyle cellStyle = wb.createCellStyle(); - cellStyle.setAlignment(CellStyle.ALIGN_CENTER); - cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); - cellStyle.setFont(titleFont); - for(int i=0;i data=datas.get(i-1); - Set dataSet=data.keySet(); - Iterator d=dataSet.iterator(); - int k=0; - while (d.hasNext()) { - Cell cell = rowIndex.createCell(k); - cell.setCellStyle(contentStyle); - String key = (String) d.next(); - cell.setCellValue(data.get(key).toString()); - k++; - } - } -// CellStyle hlink_style = wb.createCellStyle(); -// Font hlink_font = wb.createFont(); -// hlink_font.setUnderline(Font.U_SINGLE); -// hlink_font.setColor(IndexedColors.BLUE.getIndex()); -// hlink_style.setFont(hlink_font); -// hlink_style.setAlignment(CellStyle.ALIGN_CENTER); -// hlink_style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); -// Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL); -// link.setAddress("http://poi.apache.org/"); -// cell.setHyperlink(link); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_TOP, CellStyle.BORDER_MEDIUM); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_MEDIUM); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_LEFT, CellStyle.BORDER_MEDIUM); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_RIGHT, CellStyle.BORDER_MEDIUM); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.TOP_BORDER_COLOR,IndexedColors.RED.getIndex()); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.BOTTOM_BORDER_COLOR, IndexedColors.RED.getIndex()); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.LEFT_BORDER_COLOR,IndexedColors.RED.getIndex()); -// CellUtil.setCellStyleProperty(cell, wb, CellUtil.RIGHT_BORDER_COLOR, IndexedColors.RED.getIndex()); -// row.createCell(2).setCellValue( -// createHelper.createRichTextString("This is a string用户年龄")); -// row.createCell(3).setCellValue("用户手机"); -// row.createCell(4).setCellValue("收货地址"); -// row.createCell(5).setCellValue("注册时间"); -// sheet.autoSizeColumn(0); // adjust width of the first column -// sheet.autoSizeColumn(1); -// sheet.autoSizeColumn(2); -// sheet.autoSizeColumn(3); -// sheet.autoSizeColumn(4); - FileOutputStream fileOut; - try { - fileOut = new FileOutputStream(path); - wb.write(fileOut); - fileOut.close(); - } catch (IOException e) { - e.printStackTrace(); - } - - } -} +package cn.netbuffer.ssmbootstrap_table.util; + +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.Hyperlink; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.apache.poi.ss.usermodel.Workbook; +import org.apache.poi.ss.util.CellUtil; +import org.joda.time.DateTime; + +public class POIExcelUtil { + public static void exec(String path) { + Workbook wb = new HSSFWorkbook(); // or new XSSFWorkbook(); + CreationHelper createHelper = wb.getCreationHelper(); + Sheet sheet = wb.createSheet("用户信息"); + // 冻结该行,使其无法移动 + sheet.createFreezePane(0, 1, 0, 1); + // Header header = sheet1.getHeader(); + // header.setCenter("Center Header"); + // header.setLeft("Left Header"); + // header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + + // HSSFHeader.fontSize((short) 16) + + // "Right w/ Stencil-Normal Italic font and size 16"); + Row row = sheet.createRow((short) 0); + row.setHeightInPoints(30); + Cell cell = row.createCell(0); + CellStyle cellStyle = wb.createCellStyle(); + cellStyle.setAlignment(CellStyle.ALIGN_CENTER); + cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + cell.setCellValue("用户昵称"); + cell.setCellStyle(cellStyle); + row.createCell(1).setCellValue("用户性别"); + + CellStyle hlink_style = wb.createCellStyle(); + Font hlink_font = wb.createFont(); + hlink_font.setUnderline(Font.U_SINGLE); + hlink_font.setColor(IndexedColors.BLUE.getIndex()); + hlink_style.setFont(hlink_font); + hlink_style.setAlignment(CellStyle.ALIGN_CENTER); + hlink_style.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + Hyperlink link = createHelper.createHyperlink(Hyperlink.LINK_URL); + link.setAddress("http://poi.apache.org/"); + cell.setHyperlink(link); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_TOP, CellStyle.BORDER_MEDIUM); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_BOTTOM, CellStyle.BORDER_MEDIUM); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_LEFT, CellStyle.BORDER_MEDIUM); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.BORDER_RIGHT, CellStyle.BORDER_MEDIUM); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.TOP_BORDER_COLOR,IndexedColors.RED.getIndex()); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.BOTTOM_BORDER_COLOR, IndexedColors.RED.getIndex()); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.LEFT_BORDER_COLOR,IndexedColors.RED.getIndex()); + CellUtil.setCellStyleProperty(cell, wb, CellUtil.RIGHT_BORDER_COLOR, IndexedColors.RED.getIndex()); + row.createCell(2).setCellValue( + createHelper.createRichTextString("This is a string用户年龄")); + row.createCell(3).setCellValue("用户手机"); + row.createCell(4).setCellValue("收货地址"); + row.createCell(5).setCellValue("注册时间"); + sheet.autoSizeColumn(0); // adjust width of the first column + sheet.autoSizeColumn(1); + sheet.autoSizeColumn(2); + sheet.autoSizeColumn(3); + sheet.autoSizeColumn(4); + + FileOutputStream fileOut; + try { + fileOut = new FileOutputStream(path); + wb.write(fileOut); + fileOut.close(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public static void export(List titles,List columns, List> datas,String path) { + Workbook wb = new HSSFWorkbook(); + CreationHelper createHelper = wb.getCreationHelper(); + Sheet sheet = wb.createSheet(titles.get(0)); + // 冻结该行,使其无法移动 + sheet.createFreezePane(0, 1, 0, 1); + // Header header = sheet1.getHeader(); + // header.setCenter("Center Header"); + // header.setLeft("Left Header"); + // header.setRight(HSSFHeader.font("Stencil-Normal", "Italic") + + // HSSFHeader.fontSize((short) 16) + + // "Right w/ Stencil-Normal Italic font and size 16"); + Row row = sheet.createRow((short) 0); + row.setHeightInPoints(30); + int titleCount=titles.size(); + Font titleFont=wb.createFont(); + titleFont.setBold(true); + titleFont.setColor(IndexedColors.AQUA.getIndex()); + CellStyle cellStyle = wb.createCellStyle(); + cellStyle.setAlignment(CellStyle.ALIGN_CENTER); + cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + cellStyle.setFont(titleFont); + for(int i=0;i data=datas.get(i-1); + for(int k=0;k clazz = obj.getClass(); clazz != Object.class; clazz = clazz + .getSuperclass()) { + try { + field = clazz.getDeclaredField(fieldName); + break; + } catch (NoSuchFieldException e) { + // 这里不用做处理,子类没有该字段可能对应的父类有,都没有就返回null。 + } + } + return field; + } + + /** + * 利用反射设置指定对象的指定属性为指定的值 + * + * @param obj + * 目标对象 + * @param fieldName + * 目标属性 + * @param fieldValue + * 目标值 + */ + public static void setFieldValue(Object obj, String fieldName, + String fieldValue) { + Field field = ReflectUtil.getField(obj, fieldName); + if (field != null) { + try { + field.setAccessible(true); + field.set(obj, fieldValue); + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/SpringConfiguringClass.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/SpringConfiguringClass.java new file mode 100644 index 00000000..4e7c8dfc --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/SpringConfiguringClass.java @@ -0,0 +1,23 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import java.util.concurrent.TimeUnit; +import org.springframework.context.annotation.Configuration; +import com.codahale.metrics.ConsoleReporter; +import com.codahale.metrics.MetricRegistry; +import com.codahale.metrics.SharedMetricRegistries; +import com.ryantenney.metrics.spring.config.annotation.EnableMetrics; +import com.ryantenney.metrics.spring.config.annotation.MetricsConfigurerAdapter; + +@Configuration +@EnableMetrics +public class SpringConfiguringClass extends MetricsConfigurerAdapter { + @Override + public void configureReporters(MetricRegistry metricRegistry) { + // registerReporter allows the MetricsConfigurerAdapter to + // shut down the reporter when the Spring context is closed + registerReporter(ConsoleReporter + .forRegistry(metricRegistry) + .build()) + .start(1, TimeUnit.MINUTES); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/SwaggerConfig.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/SwaggerConfig.java new file mode 100644 index 00000000..a2c78468 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/SwaggerConfig.java @@ -0,0 +1,61 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.ComponentScan; +import org.springframework.web.servlet.config.annotation.EnableWebMvc; + +import com.google.common.base.Predicate; + +import springfox.documentation.builders.PathSelectors; +import springfox.documentation.service.ApiInfo; +import springfox.documentation.service.Contact; +import springfox.documentation.spi.DocumentationType; +import springfox.documentation.spring.web.plugins.Docket; +import springfox.documentation.swagger2.annotations.EnableSwagger2; + +//@Configuration 在线文档:http://springfox.github.io/springfox/docs/current/ +//前端访问http://localhost:8080/ssmbootstrap_table/swagger-ui.html +@EnableWebMvc +@EnableSwagger2 +@ComponentScan(basePackages = { "cn.netbuffer.ssmbootstrap_table" }) +public class SwaggerConfig { + /** + + * Every SwaggerSpringMvcPlugin bean is picked up by the swagger-mvc + + * framework - allowing for multiple swagger groups i.e. same code base + + * multiple swagger resource listings. + + * + + * @return SwaggerSpringMvcPlugin + + */ + @Bean + public Docket customImplementation() { + + return new Docket(DocumentationType.SWAGGER_2).apiInfo(getApiInfo()) + .select().paths(paths()).build().pathMapping("/"); + } + + private Predicate paths() { + return PathSelectors.any(); + } + + /** + + * A method that returns the API Info + + * + + * @return ApiInfo The Information including description + + */ + public ApiInfo getApiInfo() { + return new ApiInfo("ssmbootstrap_table-api", + "api接口列表", "版本号", + "https://github.com/netbuffer/", new Contact("netbuffer", "https://github.com/netbuffer/", "javawiki@163.com"), null, null); + } +} + diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/util/TestBeanPostProcessor.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/TestBeanPostProcessor.java new file mode 100644 index 00000000..e016dc00 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/util/TestBeanPostProcessor.java @@ -0,0 +1,85 @@ +package cn.netbuffer.ssmbootstrap_table.util; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.BeansException; +import org.springframework.beans.factory.config.BeanPostProcessor; +/** + * 如果我们需要在Spring容器完成Bean的实例化、配置和其他的初始化前后添加一些自己的逻辑处理需要用到 + * @package cn.netbuffer.ssmbootstrap_table.util + * @Description: TODO() + */ +public class TestBeanPostProcessor implements BeanPostProcessor { + private static final Logger log = LoggerFactory + .getLogger(TestBeanPostProcessor.class); + + public Object postProcessAfterInitialization(Object bean, String beanName) + throws BeansException { + log.info("postProcess-[After]-init:{}",beanName); + return bean; + } + + public Object postProcessBeforeInitialization(Object bean, String beanName) + throws BeansException { + log.info("postProcess-[Before]-init:{}",beanName); + List> clazzes = getAllClasses(bean); + + for (Class clazz : clazzes) { + initializeLog(bean, clazz); + } + + return bean; + } + + /** + * 取得指定bean的class以及所有父类的列表, 该列表排列顺序为从父类到当前类 + * + * @param bean + * @return + */ + private List> getAllClasses(Object bean) { +// log.info("getAllClasses"); + Class clazz = bean.getClass(); + List> clazzes = new ArrayList>(); + while (clazz != null) { + clazzes.add(clazz); + clazz = clazz.getSuperclass(); + } + Collections.reverse(clazzes); + return clazzes; + } + + /** + * 对logger变量进行初始化 + * + * @param bean + * @param clazz + */ + private void initializeLog(Object bean, Class clazz) { + Field[] fields = clazz.getDeclaredFields(); + // for (Field field : fields) { + // if (field.getAnnotation(Logger.class) == null) { + // continue; + // } + // + // if (!field.getType().isAssignableFrom(Log.class)) { + // continue; + // } + // + // field.setAccessible(true); + // try { + // field.set(bean, LogFactory.getLog(clazz)); + // } catch (Exception e) { + // throw new BeanInitializationException(String.format( + // "初始化logger失败!bean=%s;field=%s", bean, field)); + // } + // + // } + } + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/validator/UserValidator.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/validator/UserValidator.java new file mode 100644 index 00000000..f1a6606c --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/validator/UserValidator.java @@ -0,0 +1,35 @@ +package cn.netbuffer.ssmbootstrap_table.validator; + +import org.springframework.validation.Errors; +import org.springframework.validation.ValidationUtils; +import org.springframework.validation.Validator; + +import cn.netbuffer.ssmbootstrap_table.model.User; +/** + * spring mvc 数据较验方式 + * @author netbuffer + * + */ +public class UserValidator implements Validator { + + @Override + public boolean supports(Class clazz) { + return User.class.equals(clazz); + } + + /** + * 校验数据 + */ + @Override + public void validate(Object target, Errors errors) { + ValidationUtils.rejectIfEmpty(errors, "name", null, + "name is empty."); + User user = (User) target; + if (null == user.getName() || "".equals(user.getName())) { + errors.rejectValue("name", null, "name is empty."); + } + if(null==user.getAge()||"".equals(user.getAge())){ + errors.rejectValue("age", null, "age is empty."); + } + } +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/view/AbstractIText5PdfView.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/view/AbstractIText5PdfView.java new file mode 100644 index 00000000..b7f5682f --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/view/AbstractIText5PdfView.java @@ -0,0 +1,66 @@ +package cn.netbuffer.ssmbootstrap_table.view; + +import java.io.ByteArrayOutputStream; +import java.io.OutputStream; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.springframework.web.servlet.view.AbstractView; + +import com.itextpdf.text.Document; +import com.itextpdf.text.DocumentException; +import com.itextpdf.text.PageSize; +import com.itextpdf.text.pdf.PdfWriter; + +public abstract class AbstractIText5PdfView extends AbstractView { + + public AbstractIText5PdfView() { + setContentType("application/pdf"); + } + + @Override + protected boolean generatesDownloadContent() { + return true; + } + + @Override + protected final void renderMergedOutputModel(Map model, HttpServletRequest request, + HttpServletResponse response) throws Exception { + ByteArrayOutputStream baos = createTemporaryOutputStream(); + Document document = newDocument(); + PdfWriter writer = newWriter(document, baos); + prepareWriter(model, writer, request); + buildPdfMetadata(model, document, request); + document.open(); + buildPdfDocument(model, document, writer, request, response); + document.close(); + writeToResponse(response, baos); + } + + protected Document newDocument() { + return new Document(PageSize.A4); + } + + protected PdfWriter newWriter(Document document, OutputStream os) throws DocumentException { + return PdfWriter.getInstance(document, os); + } + + protected void prepareWriter(Map model, PdfWriter writer, HttpServletRequest request) + throws DocumentException { + + writer.setViewerPreferences(getViewerPreferences()); + } + + protected int getViewerPreferences() { + return PdfWriter.ALLOW_PRINTING | PdfWriter.PageLayoutSinglePage; + } + + protected void buildPdfMetadata(Map model, Document document, HttpServletRequest request) { + } + + protected abstract void buildPdfDocument(Map model, Document document, PdfWriter writer, + HttpServletRequest request, HttpServletResponse response) throws Exception; + +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/view/ExcelView.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/view/ExcelView.java new file mode 100644 index 00000000..c065b953 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/view/ExcelView.java @@ -0,0 +1,64 @@ +package cn.netbuffer.ssmbootstrap_table.view; + +import java.util.List; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.apache.poi.hssf.usermodel.HSSFWorkbook; +import org.apache.poi.ss.usermodel.Cell; +import org.apache.poi.ss.usermodel.CellStyle; +import org.apache.poi.ss.usermodel.CreationHelper; +import org.apache.poi.ss.usermodel.Font; +import org.apache.poi.ss.usermodel.IndexedColors; +import org.apache.poi.ss.usermodel.Row; +import org.apache.poi.ss.usermodel.Sheet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.servlet.view.document.AbstractExcelView; + +public class ExcelView extends AbstractExcelView { + + private static final Logger LOG = LoggerFactory.getLogger(ExcelView.class); + + @Override + protected void buildExcelDocument(Map model, HSSFWorkbook workbook, HttpServletRequest request, + HttpServletResponse response) throws Exception { + List columns=(List) model.get("columns"); + List keys=(List) model.get("keys"); + CreationHelper createHelper = workbook.getCreationHelper(); + Sheet sheet = workbook.createSheet("sheet"); + // 冻结该行,使其无法移动 + sheet.createFreezePane(0, 1, 0, 1); + Row row = sheet.createRow((short) 0); + row.setHeightInPoints(30); + int titleCount=columns.size(); + Font titleFont=workbook.createFont(); + titleFont.setBold(true); + titleFont.setColor(IndexedColors.AQUA.getIndex()); + CellStyle cellStyle = workbook.createCellStyle(); + cellStyle.setAlignment(CellStyle.ALIGN_CENTER); + cellStyle.setVerticalAlignment(CellStyle.VERTICAL_CENTER); + cellStyle.setFont(titleFont); + for(int i=0;i> datas=(List>) model.get("users"); + LOG.debug("[excel-view]-columns:{},keys:{},datas:{}",columns,keys,datas); + int dataCount=datas.size(); + for(int i=1;i model, Document document, PdfWriter writer, + HttpServletRequest request, HttpServletResponse response) throws Exception { + response.setCharacterEncoding("utf-8"); + Font pfont=getChineseFont(); + pfont.setSize(24); + Paragraph header = new Paragraph(new Chunk("PDF 输出测试", pfont)); + document.add(header); + document.addTitle("title"); + document.addSubject("subject"); + document.addHeader("heaer-name","header-content"); + document.add(new Paragraph("测试", getChineseFont())); + PdfPTable table = new PdfPTable(4); + table.setWidthPercentage(100.0f); + table.setWidths(new float[] { 3.0f, 2.0f, 2.0f, 3.0f}); + table.setSpacingBefore(10); + // define font for table header row +// FontFactory.getFont(FontFactory.HELVETICA) + Font font = getChineseFont(); + font.setColor(BaseColor.CYAN); + // define table header cell + PdfPCell cell = new PdfPCell(); + cell.setBackgroundColor(new BaseColor(66,133,244)); + cell.setBorderColor(BaseColor.CYAN); + cell.setPadding(5); + List columns = (List) model.get("columns"); + if (columns == null || columns.size() <= 0) { + throw new IllegalArgumentException("请设置列名columns"); + } + LOG.debug("[PdfView]-columns:{}",columns); + // write table header + for (String column : columns) { + LOG.debug("添加column:{}",column); + cell.setPhrase(new Phrase(column, font)); + table.addCell(cell); + } + + // write table row data + List users = (List) model.get("users"); + if (users == null || users.size() <= 0) { + throw new IllegalArgumentException("请添加users数据"); + } + LOG.debug("[PdfView]-users:{}",users); + for (User u : users) { + table.addCell(u.getName()); + PdfPCell sexCell = new PdfPCell(); + sexCell.setPhrase(new Phrase(u.getSex(), font)); + table.addCell(sexCell); + table.addCell(String.valueOf(u.getAge())); + table.addCell(u.getPhone()); + } + document.add(table); + } + + private static final Font getChineseFont() { + Font FontChinese = null; + try { + BaseFont baseFont = BaseFont.createFont("STSong-Light", "UniGB-UCS2-H", BaseFont.NOT_EMBEDDED); + FontChinese = new Font(baseFont); + } catch (DocumentException de) { + System.err.println(de.getMessage()); + } catch (IOException ioe) { + System.err.println(ioe.getMessage()); + } + return FontChinese; + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/LicenseHandler.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/LicenseHandler.java new file mode 100644 index 00000000..13e9a898 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/LicenseHandler.java @@ -0,0 +1,89 @@ +package cn.netbuffer.ssmbootstrap_table.webservice; + +import java.util.Iterator; +import java.util.Set; + +import javax.xml.namespace.QName; +import javax.xml.soap.SOAPBody; +import javax.xml.soap.SOAPEnvelope; +import javax.xml.soap.SOAPException; +import javax.xml.soap.SOAPFault; +import javax.xml.soap.SOAPHeader; +import javax.xml.soap.SOAPHeaderElement; +import javax.xml.soap.SOAPMessage; +import javax.xml.ws.handler.MessageContext; +import javax.xml.ws.handler.soap.SOAPHandler; +import javax.xml.ws.handler.soap.SOAPMessageContext; +import javax.xml.ws.soap.SOAPFaultException; +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Node; + +/** + * 可以在这里处理头部认证信息 + * + * @author champ + * + */ +public class LicenseHandler implements SOAPHandler { + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @SuppressWarnings("unchecked") + @Override + public boolean handleMessage(SOAPMessageContext context) { + try { + Boolean out = (Boolean) context + .get(MessageContext.MESSAGE_OUTBOUND_PROPERTY); + logger.debug("LicenseHandler:{}",out); + if (!out) { + SOAPMessage message = context.getMessage(); + logger.debug("SOAPMessage:{}",ToStringBuilder.reflectionToString(message)); + SOAPEnvelope enve = message.getSOAPPart().getEnvelope(); + SOAPHeader header = enve.getHeader(); + SOAPBody body = enve.getBody(); + Node bn = body.getChildNodes().item(0); + String partname = bn.getLocalName(); + if ("getUser".equals(partname)) { + if (header == null) { + // 添加一个错误信息 + SOAPFault fault = body.addFault(); + fault.setFaultString("头部信息不能为空!"); + throw new SOAPFaultException(fault); + } + Iterator iterator = header + .extractAllHeaderElements(); + if (!iterator.hasNext()) { + // 添加一个错误信息 + SOAPFault fault = body.addFault(); + fault.setFaultString("头部信息不正确!"); + throw new SOAPFaultException(fault); + } + while (iterator.hasNext()) { + SOAPHeaderElement ele = iterator.next(); + System.out.println(ele.getTextContent()); + } + } + } + } catch (SOAPException e) { + e.printStackTrace(); + } + return true; + } + + @Override + public boolean handleFault(SOAPMessageContext context) { + return false; + } + + @Override + public void close(MessageContext context) { + + } + + @Override + public Set getHeaders() { + return null; + } + +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/UserServiceEndpoint.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/UserServiceEndpoint.java new file mode 100644 index 00000000..7d725523 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/UserServiceEndpoint.java @@ -0,0 +1,24 @@ +package cn.netbuffer.ssmbootstrap_table.webservice; + +import javax.annotation.Resource; +import javax.jws.HandlerChain; + +import org.springframework.stereotype.Service; + +import cn.netbuffer.ssmbootstrap_table.model.User; +import cn.netbuffer.ssmbootstrap_table.service.IUserService; + +@Service("userServiceWebservice") +@HandlerChain(file="cxf-handler-chain.xml") +public class UserServiceEndpoint implements UserServiceWebservice { + + @Resource + private IUserService userService; + + @Override + public User getUser(Long id) { +// return new User(); + return userService.getUserById(id); + } + +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/UserServiceWebservice.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/UserServiceWebservice.java new file mode 100644 index 00000000..264de46f --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/UserServiceWebservice.java @@ -0,0 +1,13 @@ +package cn.netbuffer.ssmbootstrap_table.webservice; + +import javax.jws.WebMethod; +import javax.jws.WebParam; +import javax.jws.WebService; +import cn.netbuffer.ssmbootstrap_table.model.User; + +@WebService +public interface UserServiceWebservice { + + @WebMethod + public User getUser(@WebParam(name = "id") Long id); +} diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/cxf-handler-chain.xml b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/cxf-handler-chain.xml new file mode 100644 index 00000000..7cb49b08 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/webservice/cxf-handler-chain.xml @@ -0,0 +1,10 @@ + + + + + cn.netbuffer.ssmbootstrap_table.webservice.LicenseHandler + + + + \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/websocket/MySpringTextWsHandler.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/websocket/MySpringTextWsHandler.java new file mode 100644 index 00000000..0d9a7863 --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/websocket/MySpringTextWsHandler.java @@ -0,0 +1,28 @@ +package cn.netbuffer.ssmbootstrap_table.websocket; + +import org.apache.commons.lang3.builder.ToStringBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.web.socket.TextMessage; +import org.springframework.web.socket.WebSocketSession; +import org.springframework.web.socket.handler.TextWebSocketHandler; + +public class MySpringTextWsHandler extends TextWebSocketHandler { + + private static final Logger log=LoggerFactory.getLogger(MySpringTextWsHandler.class); + + @Override + protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception { + if (session.isOpen()) { + log.warn("receive websocket message:{} session:{}",ToStringBuilder.reflectionToString(message),ToStringBuilder.reflectionToString(session)); + TextMessage returnMessage = new TextMessage(message.getPayload() + " received at server"); + session.sendMessage(returnMessage); + } + } + + @Override + public void afterConnectionEstablished(WebSocketSession session) throws Exception { + super.afterConnectionEstablished(session); + // SpringWebsocketConstant.map.put("1", session); + } +} \ No newline at end of file diff --git a/src/main/java/cn/netbuffer/ssmbootstrap_table/websocket/SpringWebSocketConfig.java b/src/main/java/cn/netbuffer/ssmbootstrap_table/websocket/SpringWebSocketConfig.java new file mode 100644 index 00000000..92925a3d --- /dev/null +++ b/src/main/java/cn/netbuffer/ssmbootstrap_table/websocket/SpringWebSocketConfig.java @@ -0,0 +1,32 @@ +package cn.netbuffer.ssmbootstrap_table.websocket; + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; +import org.springframework.web.socket.WebSocketHandler; +import org.springframework.web.socket.config.annotation.EnableWebSocket; +import org.springframework.web.socket.config.annotation.WebSocketConfigurer; +import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry; + +@Configuration +@EnableWebSocket +public class SpringWebSocketConfig extends WebMvcConfigurerAdapter implements WebSocketConfigurer { + + @Override + public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) { + registry.addHandler(myWsHandler(), "/ws"); + registry.addHandler(myWsHandler(), "/wsockjs").withSockJS(); + } + + @Bean + public WebSocketHandler myWsHandler() { + return new MySpringTextWsHandler(); + } + + // Allow serving HTML files through the default Servlet + @Override + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { + configurer.enable(); + } +} \ No newline at end of file diff --git a/src/main/java/com/baidu/ueditor/ActionEnter.java b/src/main/java/com/baidu/ueditor/ActionEnter.java new file mode 100644 index 00000000..33a3dc7b --- /dev/null +++ b/src/main/java/com/baidu/ueditor/ActionEnter.java @@ -0,0 +1,127 @@ +package com.baidu.ueditor; + +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import com.baidu.ueditor.define.ActionMap; +import com.baidu.ueditor.define.AppInfo; +import com.baidu.ueditor.define.BaseState; +import com.baidu.ueditor.define.State; +import com.baidu.ueditor.hunter.FileManager; +import com.baidu.ueditor.hunter.ImageHunter; +import com.baidu.ueditor.upload.Uploader; + +public class ActionEnter { + + private HttpServletRequest request = null; + + private String rootPath = null; + private String contextPath = null; + + private String actionType = null; + + private ConfigManager configManager = null; + + public ActionEnter ( HttpServletRequest request, String rootPath ) { + + this.request = request; + this.rootPath = rootPath; + this.actionType = request.getParameter( "action" ); + this.contextPath = request.getContextPath(); + this.configManager = ConfigManager.getInstance( this.rootPath, this.contextPath, request.getRequestURI() ); + + } + + public String exec () { + + String callbackName = this.request.getParameter("callback"); + + if ( callbackName != null ) { + + if ( !validCallbackName( callbackName ) ) { + return new BaseState( false, AppInfo.ILLEGAL ).toJSONString(); + } + + return callbackName+"("+this.invoke()+");"; + + } else { + return this.invoke(); + } + + } + + public String invoke() { + + if ( actionType == null || !ActionMap.mapping.containsKey( actionType ) ) { + return new BaseState( false, AppInfo.INVALID_ACTION ).toJSONString(); + } + + if ( this.configManager == null || !this.configManager.valid() ) { + return new BaseState( false, AppInfo.CONFIG_ERROR ).toJSONString(); + } + + State state = null; + + int actionCode = ActionMap.getType( this.actionType ); + + Map conf = null; + + switch ( actionCode ) { + + case ActionMap.CONFIG: + return this.configManager.getAllConfig().toString(); + + case ActionMap.UPLOAD_IMAGE: + case ActionMap.UPLOAD_SCRAWL: + case ActionMap.UPLOAD_VIDEO: + case ActionMap.UPLOAD_FILE: + conf = this.configManager.getConfig( actionCode ); + state = new Uploader( request, conf ).doExec(); + break; + + case ActionMap.CATCH_IMAGE: + conf = configManager.getConfig( actionCode ); + String[] list = this.request.getParameterValues( (String)conf.get( "fieldName" ) ); + state = new ImageHunter( conf ).capture( list ); + break; + + case ActionMap.LIST_IMAGE: + case ActionMap.LIST_FILE: + conf = configManager.getConfig( actionCode ); + int start = this.getStartIndex(); + state = new FileManager( conf ).listFile( start ); + break; + + } + + return state.toJSONString(); + + } + + public int getStartIndex () { + + String start = this.request.getParameter( "start" ); + + try { + return Integer.parseInt( start ); + } catch ( Exception e ) { + return 0; + } + + } + + /** + * callback参数验证 + */ + public boolean validCallbackName ( String name ) { + + if ( name.matches( "^[a-zA-Z_]+[\\w0-9_]*$" ) ) { + return true; + } + + return false; + + } + +} \ No newline at end of file diff --git a/src/main/java/com/baidu/ueditor/ConfigManager.java b/src/main/java/com/baidu/ueditor/ConfigManager.java new file mode 100644 index 00000000..5551ee90 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/ConfigManager.java @@ -0,0 +1,222 @@ +package com.baidu.ueditor; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; +import java.util.HashMap; +import java.util.Map; + +import org.json.JSONArray; +import org.json.JSONObject; + +import com.baidu.ueditor.define.ActionMap; + +/** + * 配置管理器 + * @author hancong03@baidu.com + * + */ +public final class ConfigManager { + + private final String rootPath; + private final String originalPath; + private final String contextPath; + private static final String configFileName = "config.json"; + private String parentPath = null; + private JSONObject jsonConfig = null; + // 涂鸦上传filename定义 + private final static String SCRAWL_FILE_NAME = "scrawl"; + // 远程图片抓取filename定义 + private final static String REMOTE_FILE_NAME = "remote"; + + /* + * 通过一个给定的路径构建一个配置管理器, 该管理器要求地址路径所在目录下必须存在config.properties文件 + */ + private ConfigManager ( String rootPath, String contextPath, String uri ) throws FileNotFoundException, IOException { + + rootPath = rootPath.replace( "\\", "/" ); + + this.rootPath = rootPath; + this.contextPath = contextPath; + + if ( contextPath.length() > 0 ) { + this.originalPath = this.rootPath + uri.substring( contextPath.length() ); + } else { + this.originalPath = this.rootPath + uri; + } + + this.initEnv(); + + } + + /** + * 配置管理器构造工厂 + * @param rootPath 服务器根路径 + * @param contextPath 服务器所在项目路径 + * @param uri 当前访问的uri + * @return 配置管理器实例或者null + */ + public static ConfigManager getInstance ( String rootPath, String contextPath, String uri ) { + + try { + return new ConfigManager(rootPath, contextPath, uri); + } catch ( Exception e ) { + return null; + } + + } + + // 验证配置文件加载是否正确 + public boolean valid () { + return this.jsonConfig != null; + } + + public JSONObject getAllConfig () { + + return this.jsonConfig; + + } + + public Map getConfig ( int type ) { + + Map conf = new HashMap(); + String savePath = null; + + switch ( type ) { + + case ActionMap.UPLOAD_FILE: + conf.put( "isBase64", "false" ); + conf.put( "maxSize", this.jsonConfig.getLong( "fileMaxSize" ) ); + conf.put( "allowFiles", this.getArray( "fileAllowFiles" ) ); + conf.put( "fieldName", this.jsonConfig.getString( "fileFieldName" ) ); + savePath = this.jsonConfig.getString( "filePathFormat" ); + break; + + case ActionMap.UPLOAD_IMAGE: + conf.put( "isBase64", "false" ); + conf.put( "maxSize", this.jsonConfig.getLong( "imageMaxSize" ) ); + conf.put( "allowFiles", this.getArray( "imageAllowFiles" ) ); + conf.put( "fieldName", this.jsonConfig.getString( "imageFieldName" ) ); + savePath = this.jsonConfig.getString( "imagePathFormat" ); + break; + + case ActionMap.UPLOAD_VIDEO: + conf.put( "maxSize", this.jsonConfig.getLong( "videoMaxSize" ) ); + conf.put( "allowFiles", this.getArray( "videoAllowFiles" ) ); + conf.put( "fieldName", this.jsonConfig.getString( "videoFieldName" ) ); + savePath = this.jsonConfig.getString( "videoPathFormat" ); + break; + + case ActionMap.UPLOAD_SCRAWL: + conf.put( "filename", ConfigManager.SCRAWL_FILE_NAME ); + conf.put( "maxSize", this.jsonConfig.getLong( "scrawlMaxSize" ) ); + conf.put( "fieldName", this.jsonConfig.getString( "scrawlFieldName" ) ); + conf.put( "isBase64", "true" ); + savePath = this.jsonConfig.getString( "scrawlPathFormat" ); + break; + + case ActionMap.CATCH_IMAGE: + conf.put( "filename", ConfigManager.REMOTE_FILE_NAME ); + conf.put( "filter", this.getArray( "catcherLocalDomain" ) ); + conf.put( "maxSize", this.jsonConfig.getLong( "catcherMaxSize" ) ); + conf.put( "allowFiles", this.getArray( "catcherAllowFiles" ) ); + conf.put( "fieldName", this.jsonConfig.getString( "catcherFieldName" ) + "[]" ); + savePath = this.jsonConfig.getString( "catcherPathFormat" ); + break; + + case ActionMap.LIST_IMAGE: + conf.put( "allowFiles", this.getArray( "imageManagerAllowFiles" ) ); + conf.put( "dir", this.jsonConfig.getString( "imageManagerListPath" ) ); + conf.put( "count", this.jsonConfig.getInt( "imageManagerListSize" ) ); + break; + + case ActionMap.LIST_FILE: + conf.put( "allowFiles", this.getArray( "fileManagerAllowFiles" ) ); + conf.put( "dir", this.jsonConfig.getString( "fileManagerListPath" ) ); + conf.put( "count", this.jsonConfig.getInt( "fileManagerListSize" ) ); + break; + + } + + conf.put( "savePath", savePath ); + conf.put( "rootPath", this.rootPath ); + + return conf; + + } + + private void initEnv () throws FileNotFoundException, IOException { + + File file = new File( this.originalPath ); + + if ( !file.isAbsolute() ) { + file = new File( file.getAbsolutePath() ); + } + + this.parentPath = file.getParent(); + + String configContent = this.readFile( this.getConfigPath() ); + + try{ + JSONObject jsonConfig = new JSONObject( configContent ); + this.jsonConfig = jsonConfig; + } catch ( Exception e ) { + this.jsonConfig = null; + } + + } + + private String getConfigPath () { + return this.parentPath + File.separator + ConfigManager.configFileName; + } + + private String[] getArray ( String key ) { + + JSONArray jsonArray = this.jsonConfig.getJSONArray( key ); + String[] result = new String[ jsonArray.length() ]; + + for ( int i = 0, len = jsonArray.length(); i < len; i++ ) { + result[i] = jsonArray.getString( i ); + } + + return result; + + } + + private String readFile ( String path ) throws IOException { + + StringBuilder builder = new StringBuilder(); + + try { + + InputStreamReader reader = new InputStreamReader( new FileInputStream( path ), "UTF-8" ); + BufferedReader bfReader = new BufferedReader( reader ); + + String tmpContent = null; + + while ( ( tmpContent = bfReader.readLine() ) != null ) { + builder.append( tmpContent ); + } + + bfReader.close(); + + } catch ( UnsupportedEncodingException e ) { + // 忽略 + } + + return this.filter( builder.toString() ); + + } + + // 过滤输入字符串, 剔除多行注释以及替换掉反斜杠 + private String filter ( String input ) { + + return input.replaceAll( "/\\*[\\s\\S]*?\\*/", "" ); + + } + +} diff --git a/src/main/java/com/baidu/ueditor/Encoder.java b/src/main/java/com/baidu/ueditor/Encoder.java new file mode 100644 index 00000000..00bce19b --- /dev/null +++ b/src/main/java/com/baidu/ueditor/Encoder.java @@ -0,0 +1,24 @@ +package com.baidu.ueditor; + +public class Encoder { + + public static String toUnicode ( String input ) { + + StringBuilder builder = new StringBuilder(); + char[] chars = input.toCharArray(); + + for ( char ch : chars ) { + + if ( ch < 256 ) { + builder.append( ch ); + } else { + builder.append( "\\u" + Integer.toHexString( ch& 0xffff ) ); + } + + } + + return builder.toString(); + + } + +} \ No newline at end of file diff --git a/src/main/java/com/baidu/ueditor/PathFormat.java b/src/main/java/com/baidu/ueditor/PathFormat.java new file mode 100644 index 00000000..080ea48f --- /dev/null +++ b/src/main/java/com/baidu/ueditor/PathFormat.java @@ -0,0 +1,157 @@ +package com.baidu.ueditor; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class PathFormat { + + private static final String TIME = "time"; + private static final String FULL_YEAR = "yyyy"; + private static final String YEAR = "yy"; + private static final String MONTH = "mm"; + private static final String DAY = "dd"; + private static final String HOUR = "hh"; + private static final String MINUTE = "ii"; + private static final String SECOND = "ss"; + private static final String RAND = "rand"; + + private static Date currentDate = null; + + public static String parse ( String input ) { + + Pattern pattern = Pattern.compile( "\\{([^\\}]+)\\}", Pattern.CASE_INSENSITIVE ); + Matcher matcher = pattern.matcher(input); + + PathFormat.currentDate = new Date(); + + StringBuffer sb = new StringBuffer(); + + while ( matcher.find() ) { + + matcher.appendReplacement(sb, PathFormat.getString( matcher.group( 1 ) ) ); + + } + + matcher.appendTail(sb); + + return sb.toString(); + } + + /** + * 格式化路径, 把windows路径替换成标准路径 + * @param input 待格式化的路径 + * @return 格式化后的路径 + */ + public static String format ( String input ) { + + return input.replace( "\\", "/" ); + + } + + public static String parse ( String input, String filename ) { + + Pattern pattern = Pattern.compile( "\\{([^\\}]+)\\}", Pattern.CASE_INSENSITIVE ); + Matcher matcher = pattern.matcher(input); + String matchStr = null; + + PathFormat.currentDate = new Date(); + + StringBuffer sb = new StringBuffer(); + + while ( matcher.find() ) { + + matchStr = matcher.group( 1 ); + if ( matchStr.indexOf( "filename" ) != -1 ) { + filename = filename.replace( "$", "\\$" ).replaceAll( "[\\/:*?\"<>|]", "" ); + matcher.appendReplacement(sb, filename ); + } else { + matcher.appendReplacement(sb, PathFormat.getString( matchStr ) ); + } + + } + + matcher.appendTail(sb); + + return sb.toString(); + } + + private static String getString ( String pattern ) { + + pattern = pattern.toLowerCase(); + + // time 处理 + if ( pattern.indexOf( PathFormat.TIME ) != -1 ) { + return PathFormat.getTimestamp(); + } else if ( pattern.indexOf( PathFormat.FULL_YEAR ) != -1 ) { + return PathFormat.getFullYear(); + } else if ( pattern.indexOf( PathFormat.YEAR ) != -1 ) { + return PathFormat.getYear(); + } else if ( pattern.indexOf( PathFormat.MONTH ) != -1 ) { + return PathFormat.getMonth(); + } else if ( pattern.indexOf( PathFormat.DAY ) != -1 ) { + return PathFormat.getDay(); + } else if ( pattern.indexOf( PathFormat.HOUR ) != -1 ) { + return PathFormat.getHour(); + } else if ( pattern.indexOf( PathFormat.MINUTE ) != -1 ) { + return PathFormat.getMinute(); + } else if ( pattern.indexOf( PathFormat.SECOND ) != -1 ) { + return PathFormat.getSecond(); + } else if ( pattern.indexOf( PathFormat.RAND ) != -1 ) { + return PathFormat.getRandom( pattern ); + } + + return pattern; + + } + + private static String getTimestamp () { + return System.currentTimeMillis() + ""; + } + + private static String getFullYear () { + return new SimpleDateFormat( "yyyy" ).format( PathFormat.currentDate ); + } + + private static String getYear () { + return new SimpleDateFormat( "yy" ).format( PathFormat.currentDate ); + } + + private static String getMonth () { + return new SimpleDateFormat( "MM" ).format( PathFormat.currentDate ); + } + + private static String getDay () { + return new SimpleDateFormat( "dd" ).format( PathFormat.currentDate ); + } + + private static String getHour () { + return new SimpleDateFormat( "HH" ).format( PathFormat.currentDate ); + } + + private static String getMinute () { + return new SimpleDateFormat( "mm" ).format( PathFormat.currentDate ); + } + + private static String getSecond () { + return new SimpleDateFormat( "ss" ).format( PathFormat.currentDate ); + } + + private static String getRandom ( String pattern ) { + + int length = 0; + pattern = pattern.split( ":" )[ 1 ].trim(); + + length = Integer.parseInt( pattern ); + + return ( Math.random() + "" ).replace( ".", "" ).substring( 0, length ); + + } + + public static void main(String[] args) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/ActionMap.java b/src/main/java/com/baidu/ueditor/define/ActionMap.java new file mode 100644 index 00000000..88f4f324 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/ActionMap.java @@ -0,0 +1,42 @@ +package com.baidu.ueditor.define; + +import java.util.Map; +import java.util.HashMap; + +/** + * 定义请求action类型 + * @author hancong03@baidu.com + * + */ +@SuppressWarnings("serial") +public final class ActionMap { + + public static final Map mapping; + // 获取配置请求 + public static final int CONFIG = 0; + public static final int UPLOAD_IMAGE = 1; + public static final int UPLOAD_SCRAWL = 2; + public static final int UPLOAD_VIDEO = 3; + public static final int UPLOAD_FILE = 4; + public static final int CATCH_IMAGE = 5; + public static final int LIST_FILE = 6; + public static final int LIST_IMAGE = 7; + + static { + mapping = new HashMap(){{ + put( "config", ActionMap.CONFIG ); + put( "uploadimage", ActionMap.UPLOAD_IMAGE ); + put( "uploadscrawl", ActionMap.UPLOAD_SCRAWL ); + put( "uploadvideo", ActionMap.UPLOAD_VIDEO ); + put( "uploadfile", ActionMap.UPLOAD_FILE ); + put( "catchimage", ActionMap.CATCH_IMAGE ); + put( "listfile", ActionMap.LIST_FILE ); + put( "listimage", ActionMap.LIST_IMAGE ); + }}; + } + + public static int getType ( String key ) { + return ActionMap.mapping.get( key ); + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/ActionState.java b/src/main/java/com/baidu/ueditor/define/ActionState.java new file mode 100644 index 00000000..b0fad34f --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/ActionState.java @@ -0,0 +1,5 @@ +package com.baidu.ueditor.define; + +public enum ActionState { + UNKNOW_ERROR +} diff --git a/src/main/java/com/baidu/ueditor/define/AppInfo.java b/src/main/java/com/baidu/ueditor/define/AppInfo.java new file mode 100644 index 00000000..b869f2aa --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/AppInfo.java @@ -0,0 +1,77 @@ +package com.baidu.ueditor.define; + +import java.util.HashMap; +import java.util.Map; + +public final class AppInfo { + + public static final int SUCCESS = 0; + public static final int MAX_SIZE = 1; + public static final int PERMISSION_DENIED = 2; + public static final int FAILED_CREATE_FILE = 3; + public static final int IO_ERROR = 4; + public static final int NOT_MULTIPART_CONTENT = 5; + public static final int PARSE_REQUEST_ERROR = 6; + public static final int NOTFOUND_UPLOAD_DATA = 7; + public static final int NOT_ALLOW_FILE_TYPE = 8; + + public static final int INVALID_ACTION = 101; + public static final int CONFIG_ERROR = 102; + + public static final int PREVENT_HOST = 201; + public static final int CONNECTION_ERROR = 202; + public static final int REMOTE_FAIL = 203; + + public static final int NOT_DIRECTORY = 301; + public static final int NOT_EXIST = 302; + + public static final int ILLEGAL = 401; + + public static Map info = new HashMap(){{ + + put( AppInfo.SUCCESS, "SUCCESS" ); + + // 无效的Action + put( AppInfo.INVALID_ACTION, "\u65E0\u6548\u7684Action" ); + // 配置文件初始化失败 + put( AppInfo.CONFIG_ERROR, "\u914D\u7F6E\u6587\u4EF6\u521D\u59CB\u5316\u5931\u8D25" ); + // 抓取远程图片失败 + put( AppInfo.REMOTE_FAIL, "\u6293\u53D6\u8FDC\u7A0B\u56FE\u7247\u5931\u8D25" ); + + // 被阻止的远程主机 + put( AppInfo.PREVENT_HOST, "\u88AB\u963B\u6B62\u7684\u8FDC\u7A0B\u4E3B\u673A" ); + // 远程连接出错 + put( AppInfo.CONNECTION_ERROR, "\u8FDC\u7A0B\u8FDE\u63A5\u51FA\u9519" ); + + // "文件大小超出限制" + put( AppInfo.MAX_SIZE, "\u6587\u4ef6\u5927\u5c0f\u8d85\u51fa\u9650\u5236" ); + // 权限不足, 多指写权限 + put( AppInfo.PERMISSION_DENIED, "\u6743\u9650\u4E0D\u8DB3" ); + // 创建文件失败 + put( AppInfo.FAILED_CREATE_FILE, "\u521B\u5EFA\u6587\u4EF6\u5931\u8D25" ); + // IO错误 + put( AppInfo.IO_ERROR, "IO\u9519\u8BEF" ); + // 上传表单不是multipart/form-data类型 + put( AppInfo.NOT_MULTIPART_CONTENT, "\u4E0A\u4F20\u8868\u5355\u4E0D\u662Fmultipart/form-data\u7C7B\u578B" ); + // 解析上传表单错误 + put( AppInfo.PARSE_REQUEST_ERROR, "\u89E3\u6790\u4E0A\u4F20\u8868\u5355\u9519\u8BEF" ); + // 未找到上传数据 + put( AppInfo.NOTFOUND_UPLOAD_DATA, "\u672A\u627E\u5230\u4E0A\u4F20\u6570\u636E" ); + // 不允许的文件类型 + put( AppInfo.NOT_ALLOW_FILE_TYPE, "\u4E0D\u5141\u8BB8\u7684\u6587\u4EF6\u7C7B\u578B" ); + + // 指定路径不是目录 + put( AppInfo.NOT_DIRECTORY, "\u6307\u5B9A\u8DEF\u5F84\u4E0D\u662F\u76EE\u5F55" ); + // 指定路径并不存在 + put( AppInfo.NOT_EXIST, "\u6307\u5B9A\u8DEF\u5F84\u5E76\u4E0D\u5B58\u5728" ); + + // callback参数名不合法 + put( AppInfo.ILLEGAL, "Callback\u53C2\u6570\u540D\u4E0D\u5408\u6CD5" ); + + }}; + + public static String getStateInfo ( int key ) { + return AppInfo.info.get( key ); + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/BaseState.java b/src/main/java/com/baidu/ueditor/define/BaseState.java new file mode 100644 index 00000000..dcc881b1 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/BaseState.java @@ -0,0 +1,90 @@ +package com.baidu.ueditor.define; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +import com.baidu.ueditor.Encoder; + +public class BaseState implements State { + + private boolean state = false; + private String info = null; + + private Map infoMap = new HashMap(); + + public BaseState () { + this.state = true; + } + + public BaseState ( boolean state ) { + this.setState( state ); + } + + public BaseState ( boolean state, String info ) { + this.setState( state ); + this.info = info; + } + + public BaseState ( boolean state, int infoCode ) { + this.setState( state ); + this.info = AppInfo.getStateInfo( infoCode ); + } + + public boolean isSuccess () { + return this.state; + } + + public void setState ( boolean state ) { + this.state = state; + } + + public void setInfo ( String info ) { + this.info = info; + } + + public void setInfo ( int infoCode ) { + this.info = AppInfo.getStateInfo( infoCode ); + } + + @Override + public String toJSONString() { + return this.toString(); + } + + public String toString () { + + String key = null; + String stateVal = this.isSuccess() ? AppInfo.getStateInfo( AppInfo.SUCCESS ) : this.info; + + StringBuilder builder = new StringBuilder(); + + builder.append( "{\"state\": \"" + stateVal + "\"" ); + + Iterator iterator = this.infoMap.keySet().iterator(); + + while ( iterator.hasNext() ) { + + key = iterator.next(); + + builder.append( ",\"" + key + "\": \"" + this.infoMap.get(key) + "\"" ); + + } + + builder.append( "}" ); + + return Encoder.toUnicode( builder.toString() ); + + } + + @Override + public void putInfo(String name, String val) { + this.infoMap.put(name, val); + } + + @Override + public void putInfo(String name, long val) { + this.putInfo(name, val+""); + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/FileType.java b/src/main/java/com/baidu/ueditor/define/FileType.java new file mode 100644 index 00000000..9195b85b --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/FileType.java @@ -0,0 +1,31 @@ +package com.baidu.ueditor.define; + +import java.util.HashMap; +import java.util.Map; + +public class FileType { + + public static final String JPG = "JPG"; + + private static final Map types = new HashMap(){{ + + put( FileType.JPG, ".jpg" ); + + }}; + + public static String getSuffix ( String key ) { + return FileType.types.get( key ); + } + + /** + * 根据给定的文件名,获取其后缀信息 + * @param filename + * @return + */ + public static String getSuffixByFilename ( String filename ) { + + return filename.substring( filename.lastIndexOf( "." ) ).toLowerCase(); + + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/MIMEType.java b/src/main/java/com/baidu/ueditor/define/MIMEType.java new file mode 100644 index 00000000..77c6cddf --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/MIMEType.java @@ -0,0 +1,20 @@ +package com.baidu.ueditor.define; + +import java.util.HashMap; +import java.util.Map; + +public class MIMEType { + + public static final Map types = new HashMap(){{ + put( "image/gif", ".gif" ); + put( "image/jpeg", ".jpg" ); + put( "image/jpg", ".jpg" ); + put( "image/png", ".png" ); + put( "image/bmp", ".bmp" ); + }}; + + public static String getSuffix ( String mime ) { + return MIMEType.types.get( mime ); + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/MultiState.java b/src/main/java/com/baidu/ueditor/define/MultiState.java new file mode 100644 index 00000000..26caefb7 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/MultiState.java @@ -0,0 +1,112 @@ +package com.baidu.ueditor.define; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import com.baidu.ueditor.Encoder; + +/** + * 多状态集合状态 + * 其包含了多个状态的集合, 其本身自己也是一个状态 + * @author hancong03@baidu.com + * + */ +public class MultiState implements State { + + private boolean state = false; + private String info = null; + private Map intMap = new HashMap(); + private Map infoMap = new HashMap(); + private List stateList = new ArrayList(); + + public MultiState ( boolean state ) { + this.state = state; + } + + public MultiState ( boolean state, String info ) { + this.state = state; + this.info = info; + } + + public MultiState ( boolean state, int infoKey ) { + this.state = state; + this.info = AppInfo.getStateInfo( infoKey ); + } + + @Override + public boolean isSuccess() { + return this.state; + } + + public void addState ( State state ) { + stateList.add( state.toJSONString() ); + } + + /** + * 该方法调用无效果 + */ + @Override + public void putInfo(String name, String val) { + this.infoMap.put(name, val); + } + + @Override + public String toJSONString() { + + String stateVal = this.isSuccess() ? AppInfo.getStateInfo( AppInfo.SUCCESS ) : this.info; + + StringBuilder builder = new StringBuilder(); + + builder.append( "{\"state\": \"" + stateVal + "\"" ); + + // 数字转换 + Iterator iterator = this.intMap.keySet().iterator(); + + while ( iterator.hasNext() ) { + + stateVal = iterator.next(); + + builder.append( ",\""+ stateVal +"\": " + this.intMap.get( stateVal ) ); + + } + + iterator = this.infoMap.keySet().iterator(); + + while ( iterator.hasNext() ) { + + stateVal = iterator.next(); + + builder.append( ",\""+ stateVal +"\": \"" + this.infoMap.get( stateVal ) + "\"" ); + + } + + builder.append( ", list: [" ); + + + iterator = this.stateList.iterator(); + + while ( iterator.hasNext() ) { + + builder.append( iterator.next() + "," ); + + } + + if ( this.stateList.size() > 0 ) { + builder.deleteCharAt( builder.length() - 1 ); + } + + builder.append( " ]}" ); + + return Encoder.toUnicode( builder.toString() ); + + } + + @Override + public void putInfo(String name, long val) { + this.intMap.put( name, val ); + } + +} diff --git a/src/main/java/com/baidu/ueditor/define/State.java b/src/main/java/com/baidu/ueditor/define/State.java new file mode 100644 index 00000000..8f222749 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/define/State.java @@ -0,0 +1,18 @@ +package com.baidu.ueditor.define; + +/** + * 处理状态接口 + * @author hancong03@baidu.com + * + */ +public interface State { + + public boolean isSuccess (); + + public void putInfo( String name, String val ); + + public void putInfo ( String name, long val ); + + public String toJSONString (); + +} diff --git a/src/main/java/com/baidu/ueditor/hunter/FileManager.java b/src/main/java/com/baidu/ueditor/hunter/FileManager.java new file mode 100644 index 00000000..5a8c1a05 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/hunter/FileManager.java @@ -0,0 +1,112 @@ +package com.baidu.ueditor.hunter; + +import java.io.File; +import java.util.Arrays; +import java.util.Collection; +import java.util.Map; + +import org.apache.commons.io.FileUtils; + +import com.baidu.ueditor.PathFormat; +import com.baidu.ueditor.define.AppInfo; +import com.baidu.ueditor.define.BaseState; +import com.baidu.ueditor.define.MultiState; +import com.baidu.ueditor.define.State; + +public class FileManager { + + private String dir = null; + private String rootPath = null; + private String[] allowFiles = null; + private int count = 0; + + public FileManager ( Map conf ) { + + this.rootPath = (String)conf.get( "rootPath" ); + this.dir = this.rootPath + (String)conf.get( "dir" ); + this.allowFiles = this.getAllowFiles( conf.get("allowFiles") ); + this.count = (Integer)conf.get( "count" ); + + } + + public State listFile ( int index ) { + + File dir = new File( this.dir ); + State state = null; + + if ( !dir.exists() ) { + return new BaseState( false, AppInfo.NOT_EXIST ); + } + + if ( !dir.isDirectory() ) { + return new BaseState( false, AppInfo.NOT_DIRECTORY ); + } + + Collection list = FileUtils.listFiles( dir, this.allowFiles, true ); + + if ( index < 0 || index > list.size() ) { + state = new MultiState( true ); + } else { + Object[] fileList = Arrays.copyOfRange( list.toArray(), index, index + this.count ); + state = this.getState( fileList ); + } + + state.putInfo( "start", index ); + state.putInfo( "total", list.size() ); + + return state; + + } + + private State getState ( Object[] files ) { + + MultiState state = new MultiState( true ); + BaseState fileState = null; + + File file = null; + + for ( Object obj : files ) { + if ( obj == null ) { + break; + } + file = (File)obj; + fileState = new BaseState( true ); + fileState.putInfo( "url", PathFormat.format( this.getPath( file ) ) ); + state.addState( fileState ); + } + + return state; + + } + + private String getPath ( File file ) { + + String path = file.getAbsolutePath(); + + return path.replace( this.rootPath, "/" ); + + } + + private String[] getAllowFiles ( Object fileExt ) { + + String[] exts = null; + String ext = null; + + if ( fileExt == null ) { + return new String[ 0 ]; + } + + exts = (String[])fileExt; + + for ( int i = 0, len = exts.length; i < len; i++ ) { + + ext = exts[ i ]; + exts[ i ] = ext.replace( ".", "" ); + + } + + return exts; + + } + +} diff --git a/src/main/java/com/baidu/ueditor/hunter/ImageHunter.java b/src/main/java/com/baidu/ueditor/hunter/ImageHunter.java new file mode 100644 index 00000000..265bfed4 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/hunter/ImageHunter.java @@ -0,0 +1,144 @@ +package com.baidu.ueditor.hunter; + +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.URL; +import java.net.UnknownHostException; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import com.baidu.ueditor.PathFormat; +import com.baidu.ueditor.define.AppInfo; +import com.baidu.ueditor.define.BaseState; +import com.baidu.ueditor.define.MIMEType; +import com.baidu.ueditor.define.MultiState; +import com.baidu.ueditor.define.State; +import com.baidu.ueditor.upload.StorageManager; + +/** + * 图片抓取器 + * @author hancong03@baidu.com + * + */ +public class ImageHunter { + + private String filename = null; + private String savePath = null; + private String rootPath = null; + private List allowTypes = null; + private long maxSize = -1; + + private List filters = null; + + public ImageHunter ( Map conf ) { + + this.filename = (String)conf.get( "filename" ); + this.savePath = (String)conf.get( "savePath" ); + this.rootPath = (String)conf.get( "rootPath" ); + this.maxSize = (Long)conf.get( "maxSize" ); + this.allowTypes = Arrays.asList( (String[])conf.get( "allowFiles" ) ); + this.filters = Arrays.asList( (String[])conf.get( "filter" ) ); + + } + + public State capture ( String[] list ) { + + MultiState state = new MultiState( true ); + + for ( String source : list ) { + state.addState( captureRemoteData( source ) ); + } + + return state; + + } + + public State captureRemoteData ( String urlStr ) { + + HttpURLConnection connection = null; + URL url = null; + String suffix = null; + + try { + url = new URL( urlStr ); + + if ( !validHost( url.getHost() ) ) { + return new BaseState( false, AppInfo.PREVENT_HOST ); + } + + connection = (HttpURLConnection) url.openConnection(); + + connection.setInstanceFollowRedirects( true ); + connection.setUseCaches( true ); + + if ( !validContentState( connection.getResponseCode() ) ) { + return new BaseState( false, AppInfo.CONNECTION_ERROR ); + } + + suffix = MIMEType.getSuffix( connection.getContentType() ); + + if ( !validFileType( suffix ) ) { + return new BaseState( false, AppInfo.NOT_ALLOW_FILE_TYPE ); + } + + if ( !validFileSize( connection.getContentLength() ) ) { + return new BaseState( false, AppInfo.MAX_SIZE ); + } + + String savePath = this.getPath( this.savePath, this.filename, suffix ); + String physicalPath = this.rootPath + savePath; + + State state = StorageManager.saveFileByInputStream( connection.getInputStream(), physicalPath ); + + if ( state.isSuccess() ) { + state.putInfo( "url", PathFormat.format( savePath ) ); + state.putInfo( "source", urlStr ); + } + + return state; + + } catch ( Exception e ) { + return new BaseState( false, AppInfo.REMOTE_FAIL ); + } + + } + + private String getPath ( String savePath, String filename, String suffix ) { + + return PathFormat.parse( savePath + suffix, filename ); + + } + + private boolean validHost ( String hostname ) { + try { + InetAddress ip = InetAddress.getByName(hostname); + + if (ip.isSiteLocalAddress()) { + return false; + } + } catch (UnknownHostException e) { + return false; + } + + return !filters.contains( hostname ); + + } + + private boolean validContentState ( int code ) { + + return HttpURLConnection.HTTP_OK == code; + + } + + private boolean validFileType ( String type ) { + + return this.allowTypes.contains( type ); + + } + + private boolean validFileSize ( int size ) { + return size < this.maxSize; + } + +} diff --git a/src/main/java/com/baidu/ueditor/upload/Base64Uploader.java b/src/main/java/com/baidu/ueditor/upload/Base64Uploader.java new file mode 100644 index 00000000..2f81076a --- /dev/null +++ b/src/main/java/com/baidu/ueditor/upload/Base64Uploader.java @@ -0,0 +1,52 @@ +package com.baidu.ueditor.upload; + +import com.baidu.ueditor.PathFormat; +import com.baidu.ueditor.define.AppInfo; +import com.baidu.ueditor.define.BaseState; +import com.baidu.ueditor.define.FileType; +import com.baidu.ueditor.define.State; + +import java.util.Map; + +import org.apache.commons.codec.binary.Base64; + +public final class Base64Uploader { + + public static State save(String content, Map conf) { + + byte[] data = decode(content); + + long maxSize = ((Long) conf.get("maxSize")).longValue(); + + if (!validSize(data, maxSize)) { + return new BaseState(false, AppInfo.MAX_SIZE); + } + + String suffix = FileType.getSuffix("JPG"); + + String savePath = PathFormat.parse((String) conf.get("savePath"), + (String) conf.get("filename")); + + savePath = savePath + suffix; + String physicalPath = (String) conf.get("rootPath") + savePath; + + State storageState = StorageManager.saveBinaryFile(data, physicalPath); + + if (storageState.isSuccess()) { + storageState.putInfo("url", PathFormat.format(savePath)); + storageState.putInfo("type", suffix); + storageState.putInfo("original", ""); + } + + return storageState; + } + + private static byte[] decode(String content) { + return Base64.decodeBase64(content); + } + + private static boolean validSize(byte[] data, long length) { + return data.length <= length; + } + +} \ No newline at end of file diff --git a/src/main/java/com/baidu/ueditor/upload/BinaryUploader.java b/src/main/java/com/baidu/ueditor/upload/BinaryUploader.java new file mode 100644 index 00000000..c69f9ddd --- /dev/null +++ b/src/main/java/com/baidu/ueditor/upload/BinaryUploader.java @@ -0,0 +1,98 @@ +package com.baidu.ueditor.upload; + +import com.baidu.ueditor.PathFormat; +import com.baidu.ueditor.define.AppInfo; +import com.baidu.ueditor.define.BaseState; +import com.baidu.ueditor.define.FileType; +import com.baidu.ueditor.define.State; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Arrays; +import java.util.List; +import java.util.Map; + +import javax.servlet.http.HttpServletRequest; + +import org.apache.commons.fileupload.FileItemIterator; +import org.apache.commons.fileupload.FileItemStream; +import org.apache.commons.fileupload.FileUploadException; +import org.apache.commons.fileupload.disk.DiskFileItemFactory; +import org.apache.commons.fileupload.servlet.ServletFileUpload; + +public class BinaryUploader { + + public static final State save(HttpServletRequest request, + Map conf) { + FileItemStream fileStream = null; + boolean isAjaxUpload = request.getHeader( "X_Requested_With" ) != null; + + if (!ServletFileUpload.isMultipartContent(request)) { + return new BaseState(false, AppInfo.NOT_MULTIPART_CONTENT); + } + + ServletFileUpload upload = new ServletFileUpload( + new DiskFileItemFactory()); + + if ( isAjaxUpload ) { + upload.setHeaderEncoding( "UTF-8" ); + } + + try { + FileItemIterator iterator = upload.getItemIterator(request); + + while (iterator.hasNext()) { + fileStream = iterator.next(); + + if (!fileStream.isFormField()) + break; + fileStream = null; + } + + if (fileStream == null) { + return new BaseState(false, AppInfo.NOTFOUND_UPLOAD_DATA); + } + + String savePath = (String) conf.get("savePath"); + String originFileName = fileStream.getName(); + String suffix = FileType.getSuffixByFilename(originFileName); + + originFileName = originFileName.substring(0, + originFileName.length() - suffix.length()); + savePath = savePath + suffix; + + long maxSize = ((Long) conf.get("maxSize")).longValue(); + + if (!validType(suffix, (String[]) conf.get("allowFiles"))) { + return new BaseState(false, AppInfo.NOT_ALLOW_FILE_TYPE); + } + + savePath = PathFormat.parse(savePath, originFileName); + + String physicalPath = (String) conf.get("rootPath") + savePath; + + InputStream is = fileStream.openStream(); + State storageState = StorageManager.saveFileByInputStream(is, + physicalPath, maxSize); + is.close(); + + if (storageState.isSuccess()) { + storageState.putInfo("url", PathFormat.format(savePath)); + storageState.putInfo("type", suffix); + storageState.putInfo("original", originFileName + suffix); + } + + return storageState; + } catch (FileUploadException e) { + return new BaseState(false, AppInfo.PARSE_REQUEST_ERROR); + } catch (IOException e) { + } + return new BaseState(false, AppInfo.IO_ERROR); + } + + private static boolean validType(String type, String[] allowTypes) { + List list = Arrays.asList(allowTypes); + + return list.contains(type); + } +} diff --git a/src/main/java/com/baidu/ueditor/upload/StorageManager.java b/src/main/java/com/baidu/ueditor/upload/StorageManager.java new file mode 100644 index 00000000..33911c64 --- /dev/null +++ b/src/main/java/com/baidu/ueditor/upload/StorageManager.java @@ -0,0 +1,155 @@ +package com.baidu.ueditor.upload; + +import com.baidu.ueditor.define.AppInfo; +import com.baidu.ueditor.define.BaseState; +import com.baidu.ueditor.define.State; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; + +import org.apache.commons.io.FileUtils; + +public class StorageManager { + public static final int BUFFER_SIZE = 8192; + + public StorageManager() { + } + + public static State saveBinaryFile(byte[] data, String path) { + File file = new File(path); + + State state = valid(file); + + if (!state.isSuccess()) { + return state; + } + + try { + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(file)); + bos.write(data); + bos.flush(); + bos.close(); + } catch (IOException ioe) { + return new BaseState(false, AppInfo.IO_ERROR); + } + + state = new BaseState(true, file.getAbsolutePath()); + state.putInfo( "size", data.length ); + state.putInfo( "title", file.getName() ); + return state; + } + + public static State saveFileByInputStream(InputStream is, String path, + long maxSize) { + State state = null; + + File tmpFile = getTmpFile(); + + byte[] dataBuf = new byte[ 2048 ]; + BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE); + + try { + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE); + + int count = 0; + while ((count = bis.read(dataBuf)) != -1) { + bos.write(dataBuf, 0, count); + } + bos.flush(); + bos.close(); + + if (tmpFile.length() > maxSize) { + tmpFile.delete(); + return new BaseState(false, AppInfo.MAX_SIZE); + } + + state = saveTmpFile(tmpFile, path); + + if (!state.isSuccess()) { + tmpFile.delete(); + } + + return state; + + } catch (IOException e) { + } + return new BaseState(false, AppInfo.IO_ERROR); + } + + public static State saveFileByInputStream(InputStream is, String path) { + State state = null; + + File tmpFile = getTmpFile(); + + byte[] dataBuf = new byte[ 2048 ]; + BufferedInputStream bis = new BufferedInputStream(is, StorageManager.BUFFER_SIZE); + + try { + BufferedOutputStream bos = new BufferedOutputStream( + new FileOutputStream(tmpFile), StorageManager.BUFFER_SIZE); + + int count = 0; + while ((count = bis.read(dataBuf)) != -1) { + bos.write(dataBuf, 0, count); + } + bos.flush(); + bos.close(); + + state = saveTmpFile(tmpFile, path); + + if (!state.isSuccess()) { + tmpFile.delete(); + } + + return state; + } catch (IOException e) { + } + return new BaseState(false, AppInfo.IO_ERROR); + } + + private static File getTmpFile() { + File tmpDir = FileUtils.getTempDirectory(); + String tmpFileName = (Math.random() * 10000 + "").replace(".", ""); + return new File(tmpDir, tmpFileName); + } + + private static State saveTmpFile(File tmpFile, String path) { + State state = null; + File targetFile = new File(path); + + if (targetFile.canWrite()) { + return new BaseState(false, AppInfo.PERMISSION_DENIED); + } + try { + FileUtils.moveFile(tmpFile, targetFile); + } catch (IOException e) { + return new BaseState(false, AppInfo.IO_ERROR); + } + + state = new BaseState(true); + state.putInfo( "size", targetFile.length() ); + state.putInfo( "title", targetFile.getName() ); + + return state; + } + + private static State valid(File file) { + File parentPath = file.getParentFile(); + + if ((!parentPath.exists()) && (!parentPath.mkdirs())) { + return new BaseState(false, AppInfo.FAILED_CREATE_FILE); + } + + if (!parentPath.canWrite()) { + return new BaseState(false, AppInfo.PERMISSION_DENIED); + } + + return new BaseState(true); + } +} diff --git a/src/main/java/com/baidu/ueditor/upload/Uploader.java b/src/main/java/com/baidu/ueditor/upload/Uploader.java new file mode 100644 index 00000000..2312d1bc --- /dev/null +++ b/src/main/java/com/baidu/ueditor/upload/Uploader.java @@ -0,0 +1,29 @@ +package com.baidu.ueditor.upload; + +import com.baidu.ueditor.define.State; +import java.util.Map; +import javax.servlet.http.HttpServletRequest; + +public class Uploader { + private HttpServletRequest request = null; + private Map conf = null; + + public Uploader(HttpServletRequest request, Map conf) { + this.request = request; + this.conf = conf; + } + + public final State doExec() { + String filedName = (String) this.conf.get("fieldName"); + State state = null; + + if ("true".equals(this.conf.get("isBase64"))) { + state = Base64Uploader.save(this.request.getParameter(filedName), + this.conf); + } else { + state = BinaryUploader.save(this.request, this.conf); + } + + return state; + } +} diff --git a/src/main/java/com/intera/util/web/servlet/filter/FilterServletOutputStream.java b/src/main/java/com/intera/util/web/servlet/filter/FilterServletOutputStream.java new file mode 100644 index 00000000..351ddcec --- /dev/null +++ b/src/main/java/com/intera/util/web/servlet/filter/FilterServletOutputStream.java @@ -0,0 +1,40 @@ +package com.intera.util.web.servlet.filter; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.ServletOutputStream; +import javax.servlet.WriteListener; + +public class FilterServletOutputStream extends ServletOutputStream { + + private DataOutputStream stream; + + public FilterServletOutputStream(OutputStream output) { + stream = new DataOutputStream(output); + } + + public void write(int b) throws IOException { + stream.write(b); + } + + public void write(byte[] b) throws IOException { + stream.write(b); + } + + public void write(byte[] b, int off, int len) throws IOException { + stream.write(b, off, len); + } + + @Override + public boolean isReady() { + return false; + } + + @Override + public void setWriteListener(WriteListener writeListener) { + + } + +} \ No newline at end of file diff --git a/src/main/java/com/intera/util/web/servlet/filter/GenericResponseWrapper.java b/src/main/java/com/intera/util/web/servlet/filter/GenericResponseWrapper.java new file mode 100644 index 00000000..33c883d6 --- /dev/null +++ b/src/main/java/com/intera/util/web/servlet/filter/GenericResponseWrapper.java @@ -0,0 +1,51 @@ +package com.intera.util.web.servlet.filter; + +import java.io.ByteArrayOutputStream; +import java.io.PrintWriter; + +import javax.servlet.ServletOutputStream; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpServletResponseWrapper; + +public class GenericResponseWrapper extends HttpServletResponseWrapper { + + private ByteArrayOutputStream output; + private int contentLength; + private String contentType; + + public GenericResponseWrapper(HttpServletResponse response) { + super(response); + + output = new ByteArrayOutputStream(); + } + + public byte[] getData() { + return output.toByteArray(); + } + + public ServletOutputStream getOutputStream() { + return new FilterServletOutputStream(output); + } + + public PrintWriter getWriter() { + return new PrintWriter(getOutputStream(), true); + } + + public void setContentLength(int length) { + this.contentLength = length; + super.setContentLength(length); + } + + public int getContentLength() { + return contentLength; + } + + public void setContentType(String type) { + this.contentType = type; + super.setContentType(type); + } + + public String getContentType() { + return contentType; + } +} \ No newline at end of file diff --git a/src/main/java/com/intera/util/web/servlet/filter/JsonpCallbackFilter.java b/src/main/java/com/intera/util/web/servlet/filter/JsonpCallbackFilter.java new file mode 100644 index 00000000..a52b9218 --- /dev/null +++ b/src/main/java/com/intera/util/web/servlet/filter/JsonpCallbackFilter.java @@ -0,0 +1,61 @@ +package com.intera.util.web.servlet.filter; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Map; +import javax.servlet.Filter; +import javax.servlet.FilterChain; +import javax.servlet.FilterConfig; +import javax.servlet.ServletException; +import javax.servlet.ServletRequest; +import javax.servlet.ServletResponse; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class JsonpCallbackFilter implements Filter { + + private static Logger log = LoggerFactory.getLogger(JsonpCallbackFilter.class); + + public void init(FilterConfig fConfig) throws ServletException {} + + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + + @SuppressWarnings("unchecked") + Map parms = httpRequest.getParameterMap(); + + if(parms.containsKey("callback")) { + if(log.isDebugEnabled()) + log.debug("Wrapping response with JSONP callback '" + parms.get("callback")[0] + "'"); + + OutputStream out = httpResponse.getOutputStream(); + + GenericResponseWrapper wrapper = new GenericResponseWrapper(httpResponse); + + chain.doFilter(request, wrapper); + + //handles the content-size truncation + ByteArrayOutputStream outputStream = new ByteArrayOutputStream( ); + outputStream.write( new String(parms.get("callback")[0] + "(").getBytes() ); + outputStream.write(wrapper.getData()); + outputStream.write(new String(");").getBytes()); + byte jsonpResponse[] = outputStream.toByteArray( ); + + wrapper.setContentType("text/javascript;charset=UTF-8"); + wrapper.setContentLength(jsonpResponse.length); + + out.write(jsonpResponse); + + out.close(); + + } else { + chain.doFilter(request, response); + } + } + + public void destroy() {} +} \ No newline at end of file diff --git a/src/main/java/com/other/controller/IndexController.java b/src/main/java/com/other/controller/IndexController.java new file mode 100644 index 00000000..48bf3e44 --- /dev/null +++ b/src/main/java/com/other/controller/IndexController.java @@ -0,0 +1,26 @@ +package com.other.controller; + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.servlet.ModelAndView; + +/** + * 同名bean指定别名 + */ +@Controller(value="otherindex") +@RequestMapping("/other") +public class IndexController { + + private Logger logger = LoggerFactory.getLogger(this.getClass()); + + @RequestMapping("index") + public ModelAndView index(){ + logger.debug("index..."); + ModelAndView mav=new ModelAndView("test"); + mav.addObject("test", "test"); + return mav; + } + +} \ No newline at end of file diff --git a/src/main/java/org/springside/modules/utils/Encodes.java b/src/main/java/org/springside/modules/utils/Encodes.java new file mode 100644 index 00000000..db1a3d01 --- /dev/null +++ b/src/main/java/org/springside/modules/utils/Encodes.java @@ -0,0 +1,132 @@ +/******************************************************************************* + * Copyright (c) 2005, 2014 springside.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + *******************************************************************************/ +package org.springside.modules.utils; + +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; +import java.net.URLEncoder; + +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base64; +import org.apache.commons.codec.binary.Hex; +import org.apache.commons.lang3.StringEscapeUtils; + +/** + * 封装各种格式的编码解码工具类. + * + * 1.Commons-Codec的 hex/base64 编码 + * 2.自制的base62 编码 + * 3.Commons-Lang的xml/html escape + * 4.JDK提供的URLEncoder + * + * @author calvin + */ +public class Encodes { + + private static final String DEFAULT_URL_ENCODING = "UTF-8"; + private static final char[] BASE62 = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz".toCharArray(); + + /** + * Hex编码. + */ + public static String encodeHex(byte[] input) { + return Hex.encodeHexString(input); + } + + /** + * Hex解码. + */ + public static byte[] decodeHex(String input) { + try { + return Hex.decodeHex(input.toCharArray()); + } catch (DecoderException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * Base64编码. + */ + public static String encodeBase64(byte[] input) { + return Base64.encodeBase64String(input); + } + + /** + * Base64编码, URL安全(将Base64中的URL非法字符'+'和'/'转为'-'和'_', 见RFC3548). + */ + public static String encodeUrlSafeBase64(byte[] input) { + return Base64.encodeBase64URLSafeString(input); + } + + /** + * Base64解码. + */ + public static byte[] decodeBase64(String input) { + return Base64.decodeBase64(input); + } + + /** + * Base62编码。 + */ + public static String encodeBase62(byte[] input) { + char[] chars = new char[input.length]; + for (int i = 0; i < input.length; i++) { + chars[i] = BASE62[(input[i] & 0xFF) % BASE62.length]; + } + return new String(chars); + } + + /** + * Html 转码. + */ + public static String escapeHtml(String html) { + return StringEscapeUtils.escapeHtml4(html); + } + + /** + * Html 解码. + */ + public static String unescapeHtml(String htmlEscaped) { + return StringEscapeUtils.unescapeHtml4(htmlEscaped); + } + + /** + * Xml 转码. + */ + public static String escapeXml(String xml) { + return StringEscapeUtils.escapeXml(xml); + } + + /** + * Xml 解码. + */ + public static String unescapeXml(String xmlEscaped) { + return StringEscapeUtils.unescapeXml(xmlEscaped); + } + + /** + * URL 编码, Encode默认为UTF-8. + */ + public static String urlEncode(String part) { + try { + return URLEncoder.encode(part, DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + throw Exceptions.unchecked(e); + } + } + + /** + * URL 解码, Encode默认为UTF-8. + */ + public static String urlDecode(String part) { + + try { + return URLDecoder.decode(part, DEFAULT_URL_ENCODING); + } catch (UnsupportedEncodingException e) { + throw Exceptions.unchecked(e); + } + } +} diff --git a/src/main/java/org/springside/modules/utils/Exceptions.java b/src/main/java/org/springside/modules/utils/Exceptions.java new file mode 100644 index 00000000..63978c59 --- /dev/null +++ b/src/main/java/org/springside/modules/utils/Exceptions.java @@ -0,0 +1,76 @@ +/******************************************************************************* + * Copyright (c) 2005, 2014 springside.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + *******************************************************************************/ +package org.springside.modules.utils; + +import java.io.PrintWriter; +import java.io.StringWriter; + +/** + * 关于异常的工具类. + * + * 参考了guava的Throwables。 + * + * @author calvin + */ +public class Exceptions { + + /** + * 将CheckedException转换为UncheckedException. + */ + public static RuntimeException unchecked(Throwable ex) { + if (ex instanceof RuntimeException) { + return (RuntimeException) ex; + } else { + return new RuntimeException(ex); + } + } + + /** + * 将ErrorStack转化为String. + */ + public static String getStackTraceAsString(Throwable ex) { + StringWriter stringWriter = new StringWriter(); + ex.printStackTrace(new PrintWriter(stringWriter)); + return stringWriter.toString(); + } + + /** + * 获取组合本异常信息与底层异常信息的异常描述, 适用于本异常为统一包装异常类,底层异常才是根本原因的情况。 + */ + public static String getErrorMessageWithNestedException(Throwable ex) { + Throwable nestedException = ex.getCause(); + return new StringBuilder().append(ex.getMessage()).append(" nested exception is ") + .append(nestedException.getClass().getName()).append(":").append(nestedException.getMessage()) + .toString(); + } + + /** + * 获取异常的Root Cause. + */ + public static Throwable getRootCause(Throwable ex) { + Throwable cause; + while ((cause = ex.getCause()) != null) { + ex = cause; + } + return ex; + } + + /** + * 判断异常是否由某些底层的异常引起. + */ + public static boolean isCausedBy(Exception ex, Class... causeExceptionClasses) { + Throwable cause = ex; + while (cause != null) { + for (Class causeClass : causeExceptionClasses) { + if (causeClass.isInstance(cause)) { + return true; + } + } + cause = cause.getCause(); + } + return false; + } +} diff --git a/src/main/java/org/springside/modules/utils/Ids.java b/src/main/java/org/springside/modules/utils/Ids.java new file mode 100644 index 00000000..5ef07829 --- /dev/null +++ b/src/main/java/org/springside/modules/utils/Ids.java @@ -0,0 +1,49 @@ +/******************************************************************************* + * Copyright (c) 2005, 2014 springside.github.io + * + * Licensed under the Apache License, Version 2.0 (the "License"); + *******************************************************************************/ +package org.springside.modules.utils; + +import java.security.SecureRandom; +import java.util.UUID; + +/** + * 封装各种生成唯一性ID算法的工具类. + * + * @author calvin + */ +public class Ids { + + private static SecureRandom random = new SecureRandom(); + + /** + * 封装JDK自带的UUID, 通过Random数字生成, 中间有-分割. + */ + public static String uuid() { + return UUID.randomUUID().toString(); + } + + /** + * 封装JDK自带的UUID, 通过Random数字生成, 中间无-分割. + */ + public static String uuid2() { + return UUID.randomUUID().toString().replaceAll("-", ""); + } + + /** + * 使用SecureRandom随机生成Long. + */ + public static long randomLong() { + return Math.abs(random.nextLong()); + } + + /** + * 基于Base62编码的SecureRandom随机生成bytes. + */ + public static String randomBase62(int length) { + byte[] randomBytes = new byte[length]; + random.nextBytes(randomBytes); + return Encodes.encodeBase62(randomBytes); + } +} diff --git a/src/main/java/user.sql b/src/main/java/user.sql deleted file mode 100644 index 7d74d472..00000000 --- a/src/main/java/user.sql +++ /dev/null @@ -1,10 +0,0 @@ -CREATE TABLE `user` ( - `id` bigint(11) NOT NULL AUTO_INCREMENT, - `name` varchar(50) NOT NULL COMMENT '姓名', - `sex` varchar(2) NOT NULL COMMENT '性别', - `age` int(3) NOT NULL COMMENT '年龄', - `phone` varchar(11) NOT NULL DEFAULT '0' COMMENT '手机', - `deliveryaddress` varchar(200) DEFAULT NULL COMMENT '收货地址', - `adddate` int(11) NOT NULL COMMENT '添加时间', - PRIMARY KEY (`id`) -) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8; diff --git a/src/main/resources/ValidationMessages.properties b/src/main/resources/ValidationMessages.properties new file mode 100644 index 00000000..432c8606 --- /dev/null +++ b/src/main/resources/ValidationMessages.properties @@ -0,0 +1,2 @@ +Size.u.name.len=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A +Range.user.age = \u5E74\u9F84\u5FC5\u987B\u57281\u5230150\u4E4B\u95F4 \ No newline at end of file diff --git a/src/main/resources/app.properties b/src/main/resources/app.properties new file mode 100644 index 00000000..646dbad1 --- /dev/null +++ b/src/main/resources/app.properties @@ -0,0 +1,2 @@ +key1=test1 +key2=http://www.baidu.com \ No newline at end of file diff --git a/src/main/resources/ehcache.xml b/src/main/resources/ehcache.xml new file mode 100644 index 00000000..9f105386 --- /dev/null +++ b/src/main/resources/ehcache.xml @@ -0,0 +1,61 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/i18n/messages.properties b/src/main/resources/i18n/messages.properties new file mode 100644 index 00000000..9bea3036 --- /dev/null +++ b/src/main/resources/i18n/messages.properties @@ -0,0 +1 @@ +header.language=test \ No newline at end of file diff --git a/src/main/resources/i18n/messages_en.properties b/src/main/resources/i18n/messages_en.properties new file mode 100644 index 00000000..b839bbc5 --- /dev/null +++ b/src/main/resources/i18n/messages_en.properties @@ -0,0 +1,2 @@ +#Header +header.language=Language diff --git a/src/main/resources/i18n/messages_zh_CN.properties b/src/main/resources/i18n/messages_zh_CN.properties new file mode 100644 index 00000000..8ea754a0 --- /dev/null +++ b/src/main/resources/i18n/messages_zh_CN.properties @@ -0,0 +1,2 @@ +#配置中文显示 +header.language=中文a \ No newline at end of file diff --git a/src/main/resources/jdbc.properties b/src/main/resources/jdbc.properties index 9cc0d107..a4da7703 100644 --- a/src/main/resources/jdbc.properties +++ b/src/main/resources/jdbc.properties @@ -1,14 +1,21 @@ -driver=com.mysql.jdbc.Driver -url=jdbc:mysql://127.0.0.1:3306/u -username=root -password=root -#定义初始连接数 -initialSize=1 -#定义最大连接数 -maxActive=2 -#定义最大空闲 -maxIdle=2 -#定义最小空闲 -minIdle=1 -#定义最长等待时间 -maxWait=6000 \ No newline at end of file +jdbc.driver=com.mysql.jdbc.Driver +jdbc.url=jdbc:mysql://127.0.0.1:3306/u +jdbc.username=root +jdbc.password=root +#\u5b9a\u4e49\u521d\u59cb\u8fde\u63a5\u6570 +jdbc.initialSize=1 +#\u5b9a\u4e49\u6700\u5927\u8fde\u63a5\u6570 +jdbc.maxActive=2 +#\u5b9a\u4e49\u6700\u5c0f\u7a7a\u95f2 +jdbc.minIdle=1 +#\u5b9a\u4e49\u6700\u957f\u7b49\u5f85\u65f6\u95f4 +jdbc.maxWait=6000 +jdbc.validationQuery=select 0 +#-------------------- +jdbc.driver2=com.mysql.jdbc.Driver +jdbc.url2=jdbc:mysql://127.0.0.1:3306/u2 +jdbc.username2=root +jdbc.password2=root +jdbc.mysql.connectTime=86400 +#程序使用的端口 +appport=8080 \ No newline at end of file diff --git a/src/main/resources/jmx.properties b/src/main/resources/jmx.properties new file mode 100644 index 00000000..ba0c98de --- /dev/null +++ b/src/main/resources/jmx.properties @@ -0,0 +1,6 @@ +#jmx\u8FDC\u7A0B\u76D1\u63A7\u7AEF\u53E3\u53F7 +jmx.port=1099 +#jmx\u8FDC\u7A0B\u76D1\u63A7\u8FDE\u63A5\u89C4\u8303\u540D\uFF0C\u524D\u7F00\u4E3Aconnector:name=* +jmx.objectName=connector:name=rmi +#\u8FDC\u7A0B\u8FDE\u63A5url +jmx.serviceUrl=service:jmx:rmi://localhost/jndi/rmi://localhost:1099/jmxrmi \ No newline at end of file diff --git a/src/main/resources/log4jdbc.log4j2.properties b/src/main/resources/log4jdbc.log4j2.properties new file mode 100644 index 00000000..a04e6352 --- /dev/null +++ b/src/main/resources/log4jdbc.log4j2.properties @@ -0,0 +1,20 @@ +#use slf4j way +log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator +log4jdbc.debug.stack.prefix= +log4jdbc.sqltiming.warn.threshold= +log4jdbc.sqltiming.error.threshold= +log4jdbc.dump.booleanastruefalse= +log4jdbc.dump.sql.maxlinelength= +log4jdbc.dump.fulldebugstacktrace= +log4jdbc.statement.warn= +log4jdbc.dump.sql.select= +log4jdbc.dump.sql.insert= +log4jdbc.dump.sql.update= +log4jdbc.dump.sql.delete= +log4jdbc.dump.sql.create= +log4jdbc.dump.sql.addsemicolon= +log4jdbc.auto.load.popular.drivers= +log4jdbc.trim.sql= +log4jdbc.trim.sql.extrablanklines= +log4jdbc.suppress.generated.keys.exception= +log4jdbc.drivers= \ No newline at end of file diff --git a/src/main/resources/logback.xml b/src/main/resources/logback.xml index a8470385..611b9654 100644 --- a/src/main/resources/logback.xml +++ b/src/main/resources/logback.xml @@ -1,13 +1,15 @@ - + + - - - %date [%thread] %-5level %logger{80} - %msg%n - + true + + %highlight(%date{yyyy-MM-dd HH:mm:ss.SSS}) %cyan([%thread]) %yellow(%-5level) %green(%logger{36}) - %blue(%msg%n) - - - - - - - - - - - - + + + + + + ${logbase}${logname}-access-%d{yyyy-MM-dd}.html + + 60 + + + %d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/messages.properties b/src/main/resources/messages.properties new file mode 100644 index 00000000..385383a3 --- /dev/null +++ b/src/main/resources/messages.properties @@ -0,0 +1,2 @@ +size.u.name.len=\u59D3\u540D\u4E0D\u80FD\u4E3A\u7A7A +Range.user.age = \u5E74\u9F84\u5FC5\u987B\u57281\u5230150\u4E4B\u95F4 \ No newline at end of file diff --git a/src/main/resources/spring-mvc.xml b/src/main/resources/spring-mvc.xml deleted file mode 100644 index feba5d61..00000000 --- a/src/main/resources/spring-mvc.xml +++ /dev/null @@ -1,78 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - cn.com.ttblog.ssmbootstrap_table.model.User - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/main/resources/spring-mybatis.xml b/src/main/resources/spring-mybatis.xml deleted file mode 100644 index 45bcede7..00000000 --- a/src/main/resources/spring-mybatis.xml +++ /dev/null @@ -1,65 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - log4jdbcInterceptor - - - - - dataSource - - - - - \ No newline at end of file diff --git a/src/main/resources/spring/mybatis-global-config.xml b/src/main/resources/spring/mybatis-global-config.xml new file mode 100644 index 00000000..c796d106 --- /dev/null +++ b/src/main/resources/spring/mybatis-global-config.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring/spring-context.xml b/src/main/resources/spring/spring-context.xml new file mode 100644 index 00000000..facc3720 --- /dev/null +++ b/src/main/resources/spring/spring-context.xml @@ -0,0 +1,87 @@ + + + + spring主配置文件 + + + + + + + + + + + + classpath*:app.properties + classpath*:jdbc.properties + classpath*:jmx.properties + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/spring/spring-ehcache.xml b/src/main/resources/spring/spring-ehcache.xml new file mode 100644 index 00000000..164d43ce --- /dev/null +++ b/src/main/resources/spring/spring-ehcache.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring/spring-jmx.xml b/src/main/resources/spring/spring-jmx.xml new file mode 100644 index 00000000..1ab6299e --- /dev/null +++ b/src/main/resources/spring/spring-jmx.xml @@ -0,0 +1,27 @@ + + + + + + + + ${jmx.objectName} + + + + ${jmx.serviceUrl} + + + + + ${jmx.port} + + + + \ No newline at end of file diff --git a/src/main/resources/spring/spring-metrics.xml b/src/main/resources/spring/spring-metrics.xml new file mode 100644 index 00000000..6db20637 --- /dev/null +++ b/src/main/resources/spring/spring-metrics.xml @@ -0,0 +1,16 @@ + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring/spring-mvc.xml b/src/main/resources/spring/spring-mvc.xml new file mode 100644 index 00000000..3f74388a --- /dev/null +++ b/src/main/resources/spring/spring-mvc.xml @@ -0,0 +1,239 @@ + + + + + + + + + + + + + + + + + + + + + + BrowserCompatible + WriteMapNullValue + WriteNullListAsEmpty + WriteNullStringAsEmpty + WriteNullNumberAsZero + WriteNullBooleanAsFalse + WriteNonStringKeyAsString + WriteNonStringValueAsString + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cn.netbuffer.ssmbootstrap_table.model.User + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + application/json + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + messages + i18n/messages + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/resources/spring/spring-mybatis.xml b/src/main/resources/spring/spring-mybatis.xml new file mode 100644 index 00000000..b42fdd8c --- /dev/null +++ b/src/main/resources/spring/spring-mybatis.xml @@ -0,0 +1,129 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + cn.netbuffer.ssmbootstrap_table.service.* + cn.netbuffer.ssmbootstrap_table.dao.* + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/resources/spring/spring-websocket.xml b/src/main/resources/spring/spring-websocket.xml new file mode 100644 index 00000000..53013402 --- /dev/null +++ b/src/main/resources/spring/spring-websocket.xml @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/404.html b/src/main/webapp/404.html index ca608a47..c99da275 100644 --- a/src/main/webapp/404.html +++ b/src/main/webapp/404.html @@ -3,6 +3,7 @@ + 404 +<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%-- <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> --%> + + + + + + +500 + + + + + +
+ 发生错误啦: + +

校验信息错误

+
+

错误数量:${result.errorCount}

+

错误对象名:${result.objectName}

+ + ${error.code }/${error.defaultMessage }
+
+
+ +
错误信息:${errMsg } +
+ ${exception} +
+ + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/LongToDateTag.tld b/src/main/webapp/WEB-INF/LongToDateTag.tld new file mode 100644 index 00000000..659b97fe --- /dev/null +++ b/src/main/webapp/WEB-INF/LongToDateTag.tld @@ -0,0 +1,24 @@ + + 1.0 + 2.0 + Example TLD with Body + + l2d + convert long to date + cn.netbuffer.ssmbootstrap_table.util.LongToDateTag + + empty + + value + true + java.lang.Object + true + + + format + true + java.lang.String + true + + + \ No newline at end of file diff --git a/src/main/webapp/WEB-INF/tags/func.tag b/src/main/webapp/WEB-INF/tags/func.tag new file mode 100644 index 00000000..e0c296f3 --- /dev/null +++ b/src/main/webapp/WEB-INF/tags/func.tag @@ -0,0 +1,4 @@ +<%@tag pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ attribute name="name" type="java.lang.String" required="true"%> +

func param:${name}

\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/tags/hello.tag b/src/main/webapp/WEB-INF/tags/hello.tag new file mode 100644 index 00000000..3787a49f --- /dev/null +++ b/src/main/webapp/WEB-INF/tags/hello.tag @@ -0,0 +1,4 @@ +<%@tag pageEncoding="UTF-8"%> +<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> +<%@ attribute name="name" type="java.lang.String" required="true"%> +

hello:${name}

\ No newline at end of file diff --git a/src/main/webapp/WEB-INF/web.xml b/src/main/webapp/WEB-INF/web.xml index ef918da9..ed4523ae 100644 --- a/src/main/webapp/WEB-INF/web.xml +++ b/src/main/webapp/WEB-INF/web.xml @@ -1,132 +1,380 @@ - - - ssmbootstrap-table - - contextConfigLocation - classpath:spring-mybatis.xml - - - encodingFilter - org.springframework.web.filter.CharacterEncodingFilter - true - - encoding - UTF-8 - - - forceEncoding - true - - - - encodingFilter - /* - - - LoginFilter - cn.com.ttblog.ssmbootstrap_table.filter.LoginFilter - - noFilterTags - index.html;login;register;captcha;.css;.js;.jpg - - - enable - true - - - - LoginFilter - /* - - - - injectionAttackFilter - cn.com.ttblog.ssmbootstrap_table.filter.InjectionAttackFilter - - - filter_xss - true - - - filter_sql_injection - true - - - - click_jacking_header - true - - - - - injectionAttackFilter - /* - - - timerFilter - cn.com.ttblog.ssmbootstrap_table.filter.TimerFilter - - enable - true - - - - timerFilter - /* - - - - trimFilter - cn.com.ttblog.ssmbootstrap_table.filter.TrimFilter - - enable - true - - - - trimFilter - /* - - - - org.springframework.web.util.IntrospectorCleanupListener - - - org.springframework.web.context.ContextLoaderListener - - - - SpringMVC - org.springframework.web.servlet.DispatcherServlet - - contextConfigLocation - classpath:spring-mvc.xml - - - debug - 0 - - 0 - true - - - SpringMVC - - - / - - - 404 - /404.html - - - index.html - index.jsp - - + + + + ssmbootstrap-table + + + 关于Spring profile:在确定哪个profile处于激活状态时,需要依赖两个独立的属性:spring.profiles.active和spring.profiles.default。如果设置了spring.profiles.active属性的话, + 那么它的值就会用来确定哪个profile是激活的。但如果没有设置spring.profiles.active属性的话,那Spring将会查找spring.profiles.default的值。如果spring.profiles.active和spring.profiles.default均没有设置的话, + 那就没有激活的profile,因此只会创建那些没有定义在profile中的bean;当应用程序部署到QA、生产或其他环境之中时,负责部署的人根据情况使用系统属性、环境变量或JNDI设置spring.profiles.active即可。 + 当设置spring.profiles.active以后,至于spring.profiles.default置成什么值就已经无所谓了;系统会优先使用spring.profiles.active中所设置的profile + + spring.profiles.default + develop + + + webAppRootKey + webapp.root + + + contextConfigLocation + + classpath:spring/spring-context.xml + + + + + encodingFilter + org.springframework.web.filter.CharacterEncodingFilter + true + + encoding + UTF-8 + + + forceEncoding + true + + + + encodingFilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + domainFilter + cn.netbuffer.ssmbootstrap_table.filter.DomainFilter + true + + enable + false + + + + domainFilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + injectionAttackFilter + cn.netbuffer.ssmbootstrap_table.filter.InjectionAttackFilter + true + + + filter_xss + true + + + filter_sql_injection + true + + + + click_jacking_header + true + + + + injectionAttackFilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + + LoginFilter + org.springframework.web.filter.DelegatingFilterProxy + true + + targetBeanName + loginFilter + + + targetFilterLifecycle + true + + + enable + true + + + noFilterTags + + /*/index.html* + /*/login/** + /*/register/** + /*/captcha/** + /*/static/** + /*/css/** + /*/js/** + /*/image/** + /*/jsonp/** + /*/cxf/** + /testservlet + + + + + LoginFilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + druidfilter + com.alibaba.druid.support.http.WebStatFilter + true + + exclusions + *.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/* + + + + druidfilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + + jsonpReferFilter + cn.netbuffer.ssmbootstrap_table.filter.JsonpReferFilter + true + + enable + false + + + refers + www.abc.com;www.bcd.com + + + + + jsonpReferFilter + *.json + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + + jsonpCallbackFilter + org.springframework.web.filter.DelegatingFilterProxy + true + + + + jsonpCallbackFilter + *.json + + + + timerFilter + cn.netbuffer.ssmbootstrap_table.filter.TimerFilter + true + + enable + true + + + + timerFilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + trimFilter + cn.netbuffer.ssmbootstrap_table.filter.TrimFilter + true + + enable + true + + + + trimFilter + /* + ASYNC + ERROR + FORWARD + INCLUDE + REQUEST + + + + + CORS + com.thetransactioncompany.cors.CORSFilter + true + + cors.allowOrigin + * + + + + CORS + /* + + + + + + + org.springframework.web.util.IntrospectorCleanupListener + + + org.springframework.web.context.ContextLoaderListener + + + cn.netbuffer.ssmbootstrap_table.listener.ApplicationListener + + + cn.netbuffer.ssmbootstrap_table.listener.HealthCheckServletContextListener + + + cn.netbuffer.ssmbootstrap_table.listener.MetricsServletContextListener + + + + + druidstat + com.alibaba.druid.support.http.StatViewServlet + + + loginUsername + admin + + + + loginPassword + admin + + + allow + 127.0.0.1 + + + + + druidstat + /druid/* + + + + SpringMVC + org.springframework.web.servlet.DispatcherServlet + + contextConfigLocation + classpath:spring/spring-mvc.xml + + + debug + 0 + + 0 + + true + + + SpringMVC + + + / + + + + CXF Servlet + CXFServlet + org.apache.cxf.transport.servlet.CXFServlet + 1 + + + CXFServlet + /cxf/* + + + + metrics + com.codahale.metrics.servlets.AdminServlet + + + metrics + /metrics/* + + + + + + + + + + 30 + + + false + + false + + + COOKIE + + + + 404 + /404.html + + + index.html + index.jsp + + \ No newline at end of file diff --git a/src/main/webapp/coda.jspf b/src/main/webapp/coda.jspf new file mode 100644 index 00000000..2c7a7242 --- /dev/null +++ b/src/main/webapp/coda.jspf @@ -0,0 +1,3 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +

这是结尾部分-可以做公共的footer处理

\ No newline at end of file diff --git a/src/main/webapp/css/css.css b/src/main/webapp/css/css.css index 5a6fcf1f..ab18e671 100644 --- a/src/main/webapp/css/css.css +++ b/src/main/webapp/css/css.css @@ -22,3 +22,6 @@ font-weight: 500; src: local('Roboto Medium'), local('Roboto-Medium'), url(http://fonts.gstatic.com/s/roboto/v15/RxZJdnzeo3R5zSexge8UUVtXRa8TVwTICgirnJhmVJw.woff2) format('woff2'); } +.formError .formErrorContent { + background-color: #c0c0c0; +} \ No newline at end of file diff --git a/src/main/webapp/css/jquery-weui.css b/src/main/webapp/css/jquery-weui.css new file mode 100644 index 00000000..84de63e9 --- /dev/null +++ b/src/main/webapp/css/jquery-weui.css @@ -0,0 +1,2007 @@ +.preloader { + width: 20px; + height: 20px; + -webkit-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: preloader-spin 1s steps(12, end) infinite; + animation: preloader-spin 1s steps(12, end) infinite; +} +.preloader:after { + display: block; + width: 100%; + height: 100%; + content: ""; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; +} +@-webkit-keyframes preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +@keyframes preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +/* +.hairline(@position, @color) when (@position = top) { + border-top: 1px solid @color; +} +.hairline(@position, @color) when (@position = left) { + border-left: 1px solid @color; +} +.hairline(@position, @color) when (@position = bottom) { + border-bottom: 1px solid @color; +} +.hairline(@position, @color) when (@position = right) { + border-right: 1px solid @color; +} +// For right and bottom +.hairline-remove(@position) when not (@position = left) and not (@position = top) { + border-left: 0; + border-bottom: 0; +} +// For left and top +.hairline-remove(@position) when not (@position = right) and not (@position = bottom) { + border-right: 0; + border-top: 0; +} +// For right and bottom +.hairline-color(@position, @color) when not (@position = left) and not (@position = top) { + border-right-color: @color; + border-bottom-color: @color; +} +// For left and top +.hairline-color(@position, @color) when not (@position = right) and not (@position = bottom) { + border-left-color: @color; + border-top-color: @color; +} +*/ +html { + font-size: 20px; +} +body { + font-size: 16px; +} +@media only screen and (min-width: 400px) { + html { + font-size: 21.33333333px !important; + } +} +@media only screen and (min-width: 414px) { + html { + font-size: 22.08px !important; + } +} +@media only screen and (min-width: 480px) { + html { + font-size: 25.6px !important; + } +} +/* === Grid === */ +.weui-row { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -webkit-flex-wrap: wrap; + -ms-flex-wrap: wrap; + flex-wrap: wrap; + -webkit-box-align: start; + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start; +} +.weui-row > [class*="col-"] { + box-sizing: border-box; +} +.weui-row .col-auto { + width: 100%; +} +.weui-row .weui-col-100 { + width: 100%; + width: calc((100% - 15px*0) / 1); +} +.weui-row.weui-no-gutter .weui-col-100 { + width: 100%; +} +.weui-row .weui-col-95 { + width: 95%; + width: calc((100% - 15px*0.05263157894736836) / 1.0526315789473684); +} +.weui-row.weui-no-gutter .weui-col-95 { + width: 95%; +} +.weui-row .weui-col-90 { + width: 90%; + width: calc((100% - 15px*0.11111111111111116) / 1.1111111111111112); +} +.weui-row.weui-no-gutter .weui-col-90 { + width: 90%; +} +.weui-row .weui-col-85 { + width: 85%; + width: calc((100% - 15px*0.17647058823529416) / 1.1764705882352942); +} +.weui-row.weui-no-gutter .weui-col-85 { + width: 85%; +} +.weui-row .weui-col-80 { + width: 80%; + width: calc((100% - 15px*0.25) / 1.25); +} +.weui-row.weui-no-gutter .weui-col-80 { + width: 80%; +} +.weui-row .weui-col-75 { + width: 75%; + width: calc((100% - 15px*0.33333333333333326) / 1.3333333333333333); +} +.weui-row.weui-no-gutter .weui-col-75 { + width: 75%; +} +.weui-row .weui-col-66 { + width: 66.66666666666666%; + width: calc((100% - 15px*0.5000000000000002) / 1.5000000000000002); +} +.weui-row.weui-no-gutter .weui-col-66 { + width: 66.66666666666666%; +} +.weui-row .weui-col-60 { + width: 60%; + width: calc((100% - 15px*0.6666666666666667) / 1.6666666666666667); +} +.weui-row.weui-no-gutter .weui-col-60 { + width: 60%; +} +.weui-row .weui-col-50 { + width: 50%; + width: calc((100% - 15px*1) / 2); +} +.weui-row.weui-no-gutter .weui-col-50 { + width: 50%; +} +.weui-row .weui-col-40 { + width: 40%; + width: calc((100% - 15px*1.5) / 2.5); +} +.weui-row.weui-no-gutter .weui-col-40 { + width: 40%; +} +.weui-row .weui-col-33 { + width: 33.333333333333336%; + width: calc((100% - 15px*2) / 3); +} +.weui-row.weui-no-gutter .weui-col-33 { + width: 33.333333333333336%; +} +.weui-row .weui-col-25 { + width: 25%; + width: calc((100% - 15px*3) / 4); +} +.weui-row.weui-no-gutter .weui-col-25 { + width: 25%; +} +.weui-row .weui-col-20 { + width: 20%; + width: calc((100% - 15px*4) / 5); +} +.weui-row.weui-no-gutter .weui-col-20 { + width: 20%; +} +.weui-row .weui-col-15 { + width: 15%; + width: calc((100% - 15px*5.666666666666667) / 6.666666666666667); +} +.weui-row.weui-no-gutter .weui-col-15 { + width: 15%; +} +.weui-row .weui-col-10 { + width: 10%; + width: calc((100% - 15px*9) / 10); +} +.weui-row.weui-no-gutter .weui-col-10 { + width: 10%; +} +.weui-row .weui-col-5 { + width: 5%; + width: calc((100% - 15px*19) / 20); +} +.weui-row.weui-no-gutter .weui-col-5 { + width: 5%; +} +.weui-row .weui-col-auto:nth-last-child(1), +.weui-row .weui-col-auto:nth-last-child(1) ~ .weui-col-auto { + width: 100%; + width: calc((100% - 15px*0) / 1); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(1), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(1) ~ .weui-col-auto { + width: 100%; +} +.weui-row .weui-col-auto:nth-last-child(2), +.weui-row .weui-col-auto:nth-last-child(2) ~ .weui-col-auto { + width: 50%; + width: calc((100% - 15px*1) / 2); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(2), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(2) ~ .weui-col-auto { + width: 50%; +} +.weui-row .weui-col-auto:nth-last-child(3), +.weui-row .weui-col-auto:nth-last-child(3) ~ .weui-col-auto { + width: 33.33333333%; + width: calc((100% - 15px*2) / 3); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(3), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(3) ~ .weui-col-auto { + width: 33.33333333%; +} +.weui-row .weui-col-auto:nth-last-child(4), +.weui-row .weui-col-auto:nth-last-child(4) ~ .weui-col-auto { + width: 25%; + width: calc((100% - 15px*3) / 4); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(4), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(4) ~ .weui-col-auto { + width: 25%; +} +.weui-row .weui-col-auto:nth-last-child(5), +.weui-row .weui-col-auto:nth-last-child(5) ~ .weui-col-auto { + width: 20%; + width: calc((100% - 15px*4) / 5); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(5), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(5) ~ .weui-col-auto { + width: 20%; +} +.weui-row .weui-col-auto:nth-last-child(6), +.weui-row .weui-col-auto:nth-last-child(6) ~ .weui-col-auto { + width: 16.66666667%; + width: calc((100% - 15px*5) / 6); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(6), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(6) ~ .weui-col-auto { + width: 16.66666667%; +} +.weui-row .weui-col-auto:nth-last-child(7), +.weui-row .weui-col-auto:nth-last-child(7) ~ .weui-col-auto { + width: 14.28571429%; + width: calc((100% - 15px*6) / 7); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(7), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(7) ~ .weui-col-auto { + width: 14.28571429%; +} +.weui-row .weui-col-auto:nth-last-child(8), +.weui-row .weui-col-auto:nth-last-child(8) ~ .weui-col-auto { + width: 12.5%; + width: calc((100% - 15px*7) / 8); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(8), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(8) ~ .weui-col-auto { + width: 12.5%; +} +.weui-row .weui-col-auto:nth-last-child(9), +.weui-row .weui-col-auto:nth-last-child(9) ~ .weui-col-auto { + width: 11.11111111%; + width: calc((100% - 15px*8) / 9); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(9), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(9) ~ .weui-col-auto { + width: 11.11111111%; +} +.weui-row .weui-col-auto:nth-last-child(10), +.weui-row .weui-col-auto:nth-last-child(10) ~ .weui-col-auto { + width: 10%; + width: calc((100% - 15px*9) / 10); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(10), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(10) ~ .weui-col-auto { + width: 10%; +} +.weui-row .weui-col-auto:nth-last-child(11), +.weui-row .weui-col-auto:nth-last-child(11) ~ .weui-col-auto { + width: 9.09090909%; + width: calc((100% - 15px*10) / 11); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(11), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(11) ~ .weui-col-auto { + width: 9.09090909%; +} +.weui-row .weui-col-auto:nth-last-child(12), +.weui-row .weui-col-auto:nth-last-child(12) ~ .weui-col-auto { + width: 8.33333333%; + width: calc((100% - 15px*11) / 12); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(12), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(12) ~ .weui-col-auto { + width: 8.33333333%; +} +.weui-row .weui-col-auto:nth-last-child(13), +.weui-row .weui-col-auto:nth-last-child(13) ~ .weui-col-auto { + width: 7.69230769%; + width: calc((100% - 15px*12) / 13); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(13), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(13) ~ .weui-col-auto { + width: 7.69230769%; +} +.weui-row .weui-col-auto:nth-last-child(14), +.weui-row .weui-col-auto:nth-last-child(14) ~ .weui-col-auto { + width: 7.14285714%; + width: calc((100% - 15px*13) / 14); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(14), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(14) ~ .weui-col-auto { + width: 7.14285714%; +} +.weui-row .weui-col-auto:nth-last-child(15), +.weui-row .weui-col-auto:nth-last-child(15) ~ .weui-col-auto { + width: 6.66666667%; + width: calc((100% - 15px*14) / 15); +} +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(15), +.weui-row.weui-no-gutter .weui-col-auto:nth-last-child(15) ~ .weui-col-auto { + width: 6.66666667%; +} +@media all and (min-width: 768px) { + .row .tablet-100 { + width: 100%; + width: calc((100% - 15px*0) / 1); + } + .row.no-gutter .tablet-100 { + width: 100%; + } + .row .tablet-95 { + width: 95%; + width: calc((100% - 15px*0.05263157894736836) / 1.0526315789473684); + } + .row.no-gutter .tablet-95 { + width: 95%; + } + .row .tablet-90 { + width: 90%; + width: calc((100% - 15px*0.11111111111111116) / 1.1111111111111112); + } + .row.no-gutter .tablet-90 { + width: 90%; + } + .row .tablet-85 { + width: 85%; + width: calc((100% - 15px*0.17647058823529416) / 1.1764705882352942); + } + .row.no-gutter .tablet-85 { + width: 85%; + } + .row .tablet-80 { + width: 80%; + width: calc((100% - 15px*0.25) / 1.25); + } + .row.no-gutter .tablet-80 { + width: 80%; + } + .row .tablet-75 { + width: 75%; + width: calc((100% - 15px*0.33333333333333326) / 1.3333333333333333); + } + .row.no-gutter .tablet-75 { + width: 75%; + } + .row .tablet-66 { + width: 66.66666666666666%; + width: calc((100% - 15px*0.5000000000000002) / 1.5000000000000002); + } + .row.no-gutter .tablet-66 { + width: 66.66666666666666%; + } + .row .tablet-60 { + width: 60%; + width: calc((100% - 15px*0.6666666666666667) / 1.6666666666666667); + } + .row.no-gutter .tablet-60 { + width: 60%; + } + .row .tablet-50 { + width: 50%; + width: calc((100% - 15px*1) / 2); + } + .row.no-gutter .tablet-50 { + width: 50%; + } + .row .tablet-40 { + width: 40%; + width: calc((100% - 15px*1.5) / 2.5); + } + .row.no-gutter .tablet-40 { + width: 40%; + } + .row .tablet-33 { + width: 33.333333333333336%; + width: calc((100% - 15px*2) / 3); + } + .row.no-gutter .tablet-33 { + width: 33.333333333333336%; + } + .row .tablet-25 { + width: 25%; + width: calc((100% - 15px*3) / 4); + } + .row.no-gutter .tablet-25 { + width: 25%; + } + .row .tablet-20 { + width: 20%; + width: calc((100% - 15px*4) / 5); + } + .row.no-gutter .tablet-20 { + width: 20%; + } + .row .tablet-15 { + width: 15%; + width: calc((100% - 15px*5.666666666666667) / 6.666666666666667); + } + .row.no-gutter .tablet-15 { + width: 15%; + } + .row .tablet-10 { + width: 10%; + width: calc((100% - 15px*9) / 10); + } + .row.no-gutter .tablet-10 { + width: 10%; + } + .row .tablet-5 { + width: 5%; + width: calc((100% - 15px*19) / 20); + } + .row.no-gutter .tablet-5 { + width: 5%; + } + .row .tablet-auto:nth-last-child(1), + .row .tablet-auto:nth-last-child(1) ~ .col-auto { + width: 100%; + width: calc((100% - 15px*0) / 1); + } + .row.no-gutter .tablet-auto:nth-last-child(1), + .row.no-gutter .tablet-auto:nth-last-child(1) ~ .tablet-auto { + width: 100%; + } + .row .tablet-auto:nth-last-child(2), + .row .tablet-auto:nth-last-child(2) ~ .col-auto { + width: 50%; + width: calc((100% - 15px*1) / 2); + } + .row.no-gutter .tablet-auto:nth-last-child(2), + .row.no-gutter .tablet-auto:nth-last-child(2) ~ .tablet-auto { + width: 50%; + } + .row .tablet-auto:nth-last-child(3), + .row .tablet-auto:nth-last-child(3) ~ .col-auto { + width: 33.33333333%; + width: calc((100% - 15px*2) / 3); + } + .row.no-gutter .tablet-auto:nth-last-child(3), + .row.no-gutter .tablet-auto:nth-last-child(3) ~ .tablet-auto { + width: 33.33333333%; + } + .row .tablet-auto:nth-last-child(4), + .row .tablet-auto:nth-last-child(4) ~ .col-auto { + width: 25%; + width: calc((100% - 15px*3) / 4); + } + .row.no-gutter .tablet-auto:nth-last-child(4), + .row.no-gutter .tablet-auto:nth-last-child(4) ~ .tablet-auto { + width: 25%; + } + .row .tablet-auto:nth-last-child(5), + .row .tablet-auto:nth-last-child(5) ~ .col-auto { + width: 20%; + width: calc((100% - 15px*4) / 5); + } + .row.no-gutter .tablet-auto:nth-last-child(5), + .row.no-gutter .tablet-auto:nth-last-child(5) ~ .tablet-auto { + width: 20%; + } + .row .tablet-auto:nth-last-child(6), + .row .tablet-auto:nth-last-child(6) ~ .col-auto { + width: 16.66666667%; + width: calc((100% - 15px*5) / 6); + } + .row.no-gutter .tablet-auto:nth-last-child(6), + .row.no-gutter .tablet-auto:nth-last-child(6) ~ .tablet-auto { + width: 16.66666667%; + } + .row .tablet-auto:nth-last-child(7), + .row .tablet-auto:nth-last-child(7) ~ .col-auto { + width: 14.28571429%; + width: calc((100% - 15px*6) / 7); + } + .row.no-gutter .tablet-auto:nth-last-child(7), + .row.no-gutter .tablet-auto:nth-last-child(7) ~ .tablet-auto { + width: 14.28571429%; + } + .row .tablet-auto:nth-last-child(8), + .row .tablet-auto:nth-last-child(8) ~ .col-auto { + width: 12.5%; + width: calc((100% - 15px*7) / 8); + } + .row.no-gutter .tablet-auto:nth-last-child(8), + .row.no-gutter .tablet-auto:nth-last-child(8) ~ .tablet-auto { + width: 12.5%; + } + .row .tablet-auto:nth-last-child(9), + .row .tablet-auto:nth-last-child(9) ~ .col-auto { + width: 11.11111111%; + width: calc((100% - 15px*8) / 9); + } + .row.no-gutter .tablet-auto:nth-last-child(9), + .row.no-gutter .tablet-auto:nth-last-child(9) ~ .tablet-auto { + width: 11.11111111%; + } + .row .tablet-auto:nth-last-child(10), + .row .tablet-auto:nth-last-child(10) ~ .col-auto { + width: 10%; + width: calc((100% - 15px*9) / 10); + } + .row.no-gutter .tablet-auto:nth-last-child(10), + .row.no-gutter .tablet-auto:nth-last-child(10) ~ .tablet-auto { + width: 10%; + } + .row .tablet-auto:nth-last-child(11), + .row .tablet-auto:nth-last-child(11) ~ .col-auto { + width: 9.09090909%; + width: calc((100% - 15px*10) / 11); + } + .row.no-gutter .tablet-auto:nth-last-child(11), + .row.no-gutter .tablet-auto:nth-last-child(11) ~ .tablet-auto { + width: 9.09090909%; + } + .row .tablet-auto:nth-last-child(12), + .row .tablet-auto:nth-last-child(12) ~ .col-auto { + width: 8.33333333%; + width: calc((100% - 15px*11) / 12); + } + .row.no-gutter .tablet-auto:nth-last-child(12), + .row.no-gutter .tablet-auto:nth-last-child(12) ~ .tablet-auto { + width: 8.33333333%; + } + .row .tablet-auto:nth-last-child(13), + .row .tablet-auto:nth-last-child(13) ~ .col-auto { + width: 7.69230769%; + width: calc((100% - 15px*12) / 13); + } + .row.no-gutter .tablet-auto:nth-last-child(13), + .row.no-gutter .tablet-auto:nth-last-child(13) ~ .tablet-auto { + width: 7.69230769%; + } + .row .tablet-auto:nth-last-child(14), + .row .tablet-auto:nth-last-child(14) ~ .col-auto { + width: 7.14285714%; + width: calc((100% - 15px*13) / 14); + } + .row.no-gutter .tablet-auto:nth-last-child(14), + .row.no-gutter .tablet-auto:nth-last-child(14) ~ .tablet-auto { + width: 7.14285714%; + } + .row .tablet-auto:nth-last-child(15), + .row .tablet-auto:nth-last-child(15) ~ .col-auto { + width: 6.66666667%; + width: calc((100% - 15px*14) / 15); + } + .row.no-gutter .tablet-auto:nth-last-child(15), + .row.no-gutter .tablet-auto:nth-last-child(15) ~ .tablet-auto { + width: 6.66666667%; + } +} +.weui_dialog, +.weui_toast { + -webkit-transition-duration: .2s; + transition-duration: .2s; + opacity: 0; + -webkit-transform: scale(0.9); + transform: scale(0.9); + visibility: hidden; + margin: 0; + left: 7.5%; + top: 30%; + z-index:10000; +} +.weui_dialog .weui_btn_dialog + .weui_btn_dialog, +.weui_toast .weui_btn_dialog + .weui_btn_dialog { + position: relative; +} +.weui_dialog .weui_btn_dialog + .weui_btn_dialog:after, +.weui_toast .weui_btn_dialog + .weui_btn_dialog:after { + content: " "; + position: absolute; + left: 0; + top: 0; + width: 1px; + height: 100%; + border-left: 1px solid #D5D5D6; + color: #D5D5D6; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + -webkit-transform: scaleX(0.5); + transform: scaleX(0.5); +} +.weui_dialog.weui_dialog_visible, +.weui_toast.weui_dialog_visible, +.weui_dialog.weui_toast_visible, +.weui_toast.weui_toast_visible { + opacity: 1; + visibility: visible; + -webkit-transform: scale(1); + transform: scale(1); +} +.weui_toast { + left: 50%; + top: 35%; + margin-left: -3.8em; +} +.weui_toast_forbidden { + color: #F76260; +} +.weui_toast_cancel .weui_icon_toast:before { + content: "\EA0D"; +} +.weui_toast_forbidden .weui_icon_toast:before { + content: "\EA0B"; + color: #F76260; +} +.weui_mask { + opacity: 0; + -webkit-transition-duration: .3s; + transition-duration: .3s; + visibility: hidden; + z-index: 10; +} +.weui_mask.weui_mask_visible { + opacity: 1; + visibility: visible; +} +.weui-prompt-input { + padding: 4px 6px; + border: 1px solid #ccc; + box-sizing: border-box; + height: 2em; + width: 80%; + margin-top: 10px; +} +.weui-pull-to-refresh { + margin-top: -50px; + -webkit-transition: -webkit-transform .4s; + transition: -webkit-transform .4s; + transition: transform .4s; + transition: transform .4s, -webkit-transform .4s; +} +.weui-pull-to-refresh.refreshing { + -webkit-transform: translate3d(0, 50px, 0); + transform: translate3d(0, 50px, 0); +} +.weui-pull-to-refresh.touching { + -webkit-transition-duration: 0s; + transition-duration: 0s; +} +.weui-pull-to-refresh-layer { + height: 30px; + line-height: 30px; + padding: 10px; + text-align: center; +} +.weui-pull-to-refresh-layer .down { + display: inline-block; +} +.weui-pull-to-refresh-layer .up, +.weui-pull-to-refresh-layer .refresh { + display: none; +} +.weui-pull-to-refresh-layer .pull-to-refresh-arrow { + display: inline-block; + z-index: 10; + width: 20px; + height: 20px; + margin-right: 4px; + vertical-align: -4px; + background: no-repeat center; + background-size: 13px 20px; + -webkit-transition-duration: 300ms; + transition-duration: 300ms; + -webkit-transform: rotate(0deg) translate3d(0, 0, 0); + transform: rotate(0deg) translate3d(0, 0, 0); + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2026%2040'%3E%3Cpolygon%20points%3D'9%2C22%209%2C0%2017%2C0%2017%2C22%2026%2C22%2013.5%2C40%200%2C22'%20fill%3D'%238c8c8c'%2F%3E%3C%2Fsvg%3E"); +} +.weui-pull-to-refresh-layer .pull-to-refresh-preloader { + display: none; + vertical-align: -4px; + margin-right: 4px; + width: 20px; + height: 20px; + -webkit-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: preloader-spin 1s steps(12, end) infinite; + animation: preloader-spin 1s steps(12, end) infinite; +} +.weui-pull-to-refresh-layer .pull-to-refresh-preloader:after { + display: block; + width: 100%; + height: 100%; + content: ""; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; +} +.pull-up .weui-pull-to-refresh-layer .down, +.refreshing .weui-pull-to-refresh-layer .down { + display: none; +} +.pull-up .weui-pull-to-refresh-layer .pull-to-refresh-arrow { + display: inline-block; + -webkit-transform: rotate(180deg) translate3d(0, 0, 0); + transform: rotate(180deg) translate3d(0, 0, 0); +} +.pull-up .weui-pull-to-refresh-layer .up { + display: inline-block; +} +.pull-down .weui-pull-to-refresh-layer .pull-to-refresh-arrow { + display: inline-block; +} +.pull-down .weui-pull-to-refresh-layer .down { + display: inline-block; +} +.refreshing .weui-pull-to-refresh-layer .pull-to-refresh-arrow { + display: none; +} +.refreshing .weui-pull-to-refresh-layer .pull-to-refresh-preloader { + display: inline-block; +} +.refreshing .weui-pull-to-refresh-layer .refresh { + display: inline-block; +} +@keyframes preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +.weui_tab_bd_item.weui-pull-to-refresh { + position: absolute; + top: 50px; +} +.weui-infinite-scroll { + height: 24px; + line-height: 24px; + padding: 10px; + text-align: center; +} +.weui-infinite-scroll .infinite-preloader { + display: inline-block; + margin-right: 4px; + vertical-align: -4px; + width: 20px; + height: 20px; + -webkit-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: preloader-spin 1s steps(12, end) infinite; + animation: preloader-spin 1s steps(12, end) infinite; +} +.weui-infinite-scroll .infinite-preloader:after { + display: block; + width: 100%; + height: 100%; + content: ""; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); + background-repeat: no-repeat; + background-position: 50%; + background-size: 100%; +} +.weui_tab { + overflow: hidden; +} +.weui_navbar_item { + color: #888; +} +.weui_navbar_item.weui_bar_item_on { + color: #666; +} +.weui_tab_bd .weui_tab_bd_item { + display: none; + height: 100%; + overflow: auto; +} +.weui_tab_bd .weui_tab_bd_item.weui_tab_bd_item_active { + display: block; +} +.weui_navbar { + z-index: 100; +} +/* === Columns Picker === */ +.weui-picker-modal { + width: 100%; + position: absolute; + z-index: 100; + bottom: 0; + text-align: center; + border-radius: 0; + opacity: 0.6; + -webkit-transform: translate3d(0, 100%, 0); + transform: translate3d(0, 100%, 0); + -webkit-transition-property: opacity, -webkit-transform; + transition-property: opacity, -webkit-transform; + transition-property: transform, opacity; + transition-property: transform, opacity, -webkit-transform; + color: #3d4145; + -webkit-transition-duration: .3s; + transition-duration: .3s; + height: 13rem; + background: #EFEFF4; +} +.weui-picker-modal.weui-picker-modal-visible { + opacity: 1; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.weui-picker-modal .picker-modal-inner { + position: relative; + height: calc(100% - 2.2rem); +} +.weui-picker-modal .toolbar { + position: relative; + width: 100%; + font-size: .85rem; + line-height: 1.5; + color: #3d4145; + background: #f7f7f8; +} +.weui-picker-modal .toolbar:before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: auto; + right: auto; + height: 1px; + width: 100%; + background-color: #d9d9d9; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .weui-picker-modal .toolbar:before { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .weui-picker-modal .toolbar:before { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.weui-picker-modal .picker-columns { + width: 100%; + height: 13rem; + z-index: 11500; +} +.weui-picker-modal .picker-columns.picker-modal-inline, +.popover .weui-picker-modal .picker-columns { + height: 10rem; +} +@media (orientation: landscape) and (max-height: 415px) { + .weui-picker-modal .picker-columns:not(.picker-modal-inline) { + height: 10rem; + } +} +.weui-picker-modal .popover.popover-picker-columns { + width: 14rem; +} +.weui-picker-modal .picker-items { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + width: 100%; + padding: 0; + text-align: right; + font-size: 1rem; + font-weight: normal; + -webkit-mask-box-image: -webkit-linear-gradient(bottom, transparent, transparent 5%, white 20%, white 80%, transparent 95%, transparent); + -webkit-mask-box-image: linear-gradient(to top, transparent, transparent 5%, white 20%, white 80%, transparent 95%, transparent); +} +.weui-picker-modal .bar + .picker-items { + height: 10.8rem; +} +.weui-picker-modal .picker-items-col { + overflow: hidden; + position: relative; + max-height: 100%; +} +.weui-picker-modal .picker-items-col.picker-items-col-left { + text-align: left; +} +.weui-picker-modal .picker-items-col.picker-items-col-center { + text-align: center; +} +.weui-picker-modal .picker-items-col.picker-items-col-right { + text-align: right; +} +.weui-picker-modal .picker-items-col.picker-items-col-divider { + color: #3d4145; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; +} +.weui-picker-modal .picker-items-col-wrapper { + -webkit-transition: 300ms; + transition: 300ms; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} +.weui-picker-modal .picker-item { + height: 32px; + line-height: 32px; + padding: 0 10px; + white-space: nowrap; + position: relative; + overflow: hidden; + text-overflow: ellipsis; + color: #9b9b9b; + left: 0; + top: 0; + width: 100%; + box-sizing: border-box; + -webkit-transition: 300ms; + transition: 300ms; +} +.picker-items-col-absolute .weui-picker-modal .picker-item { + position: absolute; +} +.weui-picker-modal .picker-item.picker-item-far { + pointer-events: none; +} +.weui-picker-modal .picker-item.picker-selected { + color: #3d4145; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + -webkit-transform: rotateX(0deg); + transform: rotateX(0deg); +} +.weui-picker-modal .picker-center-highlight { + height: 32px; + box-sizing: border-box; + position: absolute; + left: 0; + width: 100%; + top: 50%; + margin-top: -18px; + pointer-events: none; +} +.weui-picker-modal .picker-center-highlight:before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: auto; + right: auto; + height: 1px; + width: 100%; + background-color: #D9D9D9; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .weui-picker-modal .picker-center-highlight:before { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .weui-picker-modal .picker-center-highlight:before { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.weui-picker-modal .picker-center-highlight:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: auto; + top: auto; + height: 1px; + width: 100%; + background-color: #D9D9D9; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .weui-picker-modal .picker-center-highlight:after { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .weui-picker-modal .picker-center-highlight:after { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.weui-picker-modal .picker-3d .picker-items { + overflow: hidden; + -webkit-perspective: 1200px; + perspective: 1200px; +} +.weui-picker-modal .picker-3d .picker-items-col, +.weui-picker-modal .picker-3d .picker-items-col-wrapper, +.weui-picker-modal .picker-3d .picker-item { + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.weui-picker-modal .picker-3d .picker-items-col { + overflow: visible; +} +.weui-picker-modal .picker-3d .picker-item { + -webkit-transform-origin: center center -110px; + transform-origin: center center -110px; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} +.weui-picker-modal .title { + position: absolute; + display: block; + width: 100%; + padding: 0; + font-size: .85rem; + font-weight: normal; + line-height: 2.2rem; + color: #3d4145; + text-align: center; + white-space: nowrap; +} +.weui-picker-modal .picker-button { + position: absolute; + right: 0; + box-sizing: border-box; + height: 2.2rem; + line-height: 2.2rem; + color: #04BE02; + z-index: 1; + padding: 0 .5rem; +} +.weui-picker-overlay, +.weui-picker-container { + position: fixed; + bottom: 0; + left: 0; + right: 0; + height: 0; + width: 100%; + height: 15rem; +} +.city-picker .col-province { + width: 5rem; +} +.city-picker .col-city { + width: 6rem; +} +.city-picker .col-district { + width: 5rem; +} +/* === Calendar === */ +.weui-picker-calendar { + background: #fff; + height: 15rem; + width: 100%; + overflow: hidden; +} +@media (orientation: landscape) and (max-height: 415px) { + .weui-picker-calendar:not(.picker-modal-inline) { + height: 11rem; + } +} +.weui-picker-calendar .picker-modal-inner { + overflow: hidden; +} +.picker-calendar-week-days { + height: 18px; + background: #f7f7f8; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + font-size: 11px; + box-sizing: border-box; + position: relative; +} +.picker-calendar-week-days:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: auto; + top: auto; + height: 1px; + width: 100%; + background-color: #c4c4c4; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .picker-calendar-week-days:after { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .picker-calendar-week-days:after { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.picker-calendar-week-days .picker-calendar-week-day { + -webkit-flex-shrink: 1; + -ms-flex: 0 1 auto; + -webkit-flex-shrink: 1; + -ms-flex-negative: 1; + flex-shrink: 1; + width: 14.28571429%; + width: calc(100% / 7); + line-height: 17px; + text-align: center; +} +.picker-calendar-week-days + .picker-calendar-months { + height: calc(100% - 18px); +} +.picker-calendar-months { + width: 100%; + height: 100%; + overflow: hidden; + position: relative; +} +.picker-calendar-months-wrapper { + position: relative; + width: 100%; + height: 100%; + -webkit-transition: 300ms; + transition: 300ms; +} +.picker-calendar-month { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-orient: vertical; + -ms-flex-direction: column; + -webkit-flex-direction: column; + flex-direction: column; + width: 100%; + height: 100%; + position: absolute; + left: 0; + top: 0; +} +.picker-calendar-row { + height: 16.66666667%; + height: calc(100% / 6); + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-flex-shrink: 1; + -ms-flex: 0 1 auto; + -webkit-flex-shrink: 1; + -ms-flex-negative: 1; + flex-shrink: 1; + width: 100%; + position: relative; +} +.picker-calendar-row:after { + content: ''; + position: absolute; + left: 0; + bottom: 0; + right: auto; + top: auto; + height: 1px; + width: 100%; + background-color: #ccc; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 100%; + transform-origin: 50% 100%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .picker-calendar-row:after { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .picker-calendar-row:after { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.picker-calendar-row:last-child:after { + display: none; +} +.picker-calendar-day { + -webkit-flex-shrink: 1; + -ms-flex: 0 1 auto; + -webkit-flex-shrink: 1; + -ms-flex-negative: 1; + flex-shrink: 1; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-pack: center; + -ms-flex-pack: center; + -webkit-justify-content: center; + justify-content: center; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + box-sizing: border-box; + width: 14.28571429%; + width: calc(100% / 7); + text-align: center; + color: #3d4145; + font-size: 15px; + cursor: pointer; +} +.picker-calendar-day.picker-calendar-day-prev, +.picker-calendar-day.picker-calendar-day-next { + color: #ccc; +} +.picker-calendar-day.picker-calendar-day-disabled { + color: #d4d4d4; + cursor: auto; +} +.picker-calendar-day.picker-calendar-day-today span { + background: #e3e3e3; +} +.picker-calendar-day.picker-calendar-day-selected span { + background: #04BE02; + color: #fff; +} +.picker-calendar-day span { + display: inline-block; + border-radius: 100%; + width: 30px; + height: 30px; + line-height: 30px; +} +.picker-calendar-month-picker, +.picker-calendar-year-picker { + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-align: center; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + -webkit-box-pack: justify; + -ms-flex-pack: justify; + -webkit-justify-content: space-between; + justify-content: space-between; + width: 50%; + max-width: 200px; + -webkit-flex-shrink: 10; + -ms-flex: 0 10 auto; + -webkit-flex-shrink: 10; + -ms-flex-negative: 10; + flex-shrink: 10; +} +.picker-calendar-month-picker a.icon-only, +.picker-calendar-year-picker a.icon-only { + min-width: 36px; +} +.picker-calendar-month-picker span, +.picker-calendar-year-picker span { + -webkit-flex-shrink: 1; + -ms-flex: 0 1 auto; + -webkit-flex-shrink: 1; + -ms-flex-negative: 1; + flex-shrink: 1; + position: relative; + overflow: hidden; + text-overflow: ellipsis; +} +.popover .picker-calendar .picker-calendar-week-days, +.picker-calendar.picker-modal-inline .picker-calendar-week-days { + background: none; +} +.popover .picker-calendar .toolbar:before, +.picker-calendar.picker-modal-inline .toolbar:before, +.popover .picker-calendar .picker-calendar-week-days:before, +.picker-calendar.picker-modal-inline .picker-calendar-week-days:before { + display: none; +} +.popover .picker-calendar .toolbar:after, +.picker-calendar.picker-modal-inline .toolbar:after, +.popover .picker-calendar .picker-calendar-week-days:after, +.picker-calendar.picker-modal-inline .picker-calendar-week-days:after { + display: none; +} +.popover .picker-calendar .toolbar ~ .picker-modal-inner .picker-calendar-months:before, +.picker-calendar.picker-modal-inline .toolbar ~ .picker-modal-inner .picker-calendar-months:before, +.popover .picker-calendar .picker-calendar-week-days ~ .picker-calendar-months:before, +.picker-calendar.picker-modal-inline .picker-calendar-week-days ~ .picker-calendar-months:before { + content: ''; + position: absolute; + left: 0; + top: 0; + bottom: auto; + right: auto; + height: 1px; + width: 100%; + background-color: #c4c4c4; + display: block; + z-index: 15; + -webkit-transform-origin: 50% 0%; + transform-origin: 50% 0%; +} +@media only screen and (-webkit-min-device-pixel-ratio: 2) { + .popover .picker-calendar .toolbar ~ .picker-modal-inner .picker-calendar-months:before, + .picker-calendar.picker-modal-inline .toolbar ~ .picker-modal-inner .picker-calendar-months:before, + .popover .picker-calendar .picker-calendar-week-days ~ .picker-calendar-months:before, + .picker-calendar.picker-modal-inline .picker-calendar-week-days ~ .picker-calendar-months:before { + -webkit-transform: scaleY(0.5); + transform: scaleY(0.5); + } +} +@media only screen and (-webkit-min-device-pixel-ratio: 3) { + .popover .picker-calendar .toolbar ~ .picker-modal-inner .picker-calendar-months:before, + .picker-calendar.picker-modal-inline .toolbar ~ .picker-modal-inner .picker-calendar-months:before, + .popover .picker-calendar .picker-calendar-week-days ~ .picker-calendar-months:before, + .picker-calendar.picker-modal-inline .picker-calendar-week-days ~ .picker-calendar-months:before { + -webkit-transform: scaleY(0.33); + transform: scaleY(0.33); + } +} +.weui-picker-modal .toolbar-inner { + height: 2.2rem; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + text-align: center; +} +.picker-calendar-month-picker, +.picker-calendar-year-picker { + display: block; + line-height: 2.2rem; +} +.picker-calendar-month-picker a.icon-only, +.picker-calendar-year-picker a.icon-only { + float: left; + width: 25%; + height: 2.2rem; + line-height: 2rem; +} +.picker-calendar-month-picker .current-month-value, +.picker-calendar-year-picker .current-month-value, +.picker-calendar-month-picker .current-year-value, +.picker-calendar-year-picker .current-year-value { + float: left; + width: 50%; + height: 2.2rem; +} +i.icon { + display: inline-block; + vertical-align: middle; + background-size: 100% auto; + background-position: center; + background-repeat: no-repeat; + font-style: normal; + position: relative; +} +i.icon.icon-next, +i.icon.icon-prev { + width: 0.75rem; + height: 0.75rem; +} +i.icon.icon-next { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2015%2015'%3E%3Cg%3E%3Cpath%20fill%3D'%2304BE02'%20d%3D'M1%2C1.6l11.8%2C5.8L1%2C13.4V1.6%20M0%2C0v15l15-7.6L0%2C0L0%2C0z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +i.icon.icon-prev { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2015%2015'%3E%3Cg%3E%3Cpath%20fill%3D'%2304BE02'%20d%3D'M14%2C1.6v11.8L2.2%2C7.6L14%2C1.6%20M15%2C0L0%2C7.6L15%2C15V0L15%2C0z'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +/** + * Swiper 3.3.1 + * Most modern mobile touch slider and framework with hardware accelerated transitions + * + * http://www.idangero.us/swiper/ + * + * Copyright 2016, Vladimir Kharlampidi + * The iDangero.us + * http://www.idangero.us/ + * + * Licensed under MIT + * + * Released on: February 7, 2016 + */ +.swiper-container { + margin: 0 auto; + position: relative; + overflow: hidden; + /* Fix of Webkit flickering */ + z-index: 1; +} +.swiper-container-no-flexbox .swiper-slide { + float: left; +} +.swiper-container-vertical > .swiper-wrapper { + -webkit-box-orient: vertical; + -ms-flex-direction: column; + -webkit-flex-direction: column; + flex-direction: column; +} +.swiper-wrapper { + position: relative; + width: 100%; + height: 100%; + z-index: 1; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-transition-property: -webkit-transform; + transition-property: -webkit-transform; + transition-property: transform; + transition-property: transform, -webkit-transform; + box-sizing: content-box; +} +.swiper-container-android .swiper-slide, +.swiper-wrapper { + -webkit-transform: translate3d(0px, 0, 0); + transform: translate3d(0px, 0, 0); +} +.swiper-container-multirow > .swiper-wrapper { + -webkit-box-lines: multiple; + -moz-box-lines: multiple; + -ms-flex-wrap: wrap; + -webkit-flex-wrap: wrap; + flex-wrap: wrap; +} +.swiper-container-free-mode > .swiper-wrapper { + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; + margin: 0 auto; +} +.swiper-slide { + -webkit-flex-shrink: 0; + -ms-flex: 0 0 auto; + -webkit-flex-shrink: 0; + -ms-flex-negative: 0; + flex-shrink: 0; + width: 100%; + height: 100%; + position: relative; +} +/* Auto Height */ +.swiper-container-autoheight, +.swiper-container-autoheight .swiper-slide { + height: auto; +} +.swiper-container-autoheight .swiper-wrapper { + -webkit-box-align: start; + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start; + -webkit-transition-property: -webkit-transform, height; + -webkit-transition-property: height, -webkit-transform; + transition-property: height, -webkit-transform; + transition-property: transform, height; + transition-property: transform, height, -webkit-transform; +} +/* a11y */ +.swiper-container .swiper-notification { + position: absolute; + left: 0; + top: 0; + pointer-events: none; + opacity: 0; + z-index: -1000; +} +/* IE10 Windows Phone 8 Fixes */ +.swiper-wp8-horizontal { + -ms-touch-action: pan-y; + touch-action: pan-y; +} +.swiper-wp8-vertical { + -ms-touch-action: pan-x; + touch-action: pan-x; +} +/* Arrows */ +.swiper-button-prev, +.swiper-button-next { + position: absolute; + top: 50%; + width: 27px; + height: 44px; + margin-top: -22px; + z-index: 10; + cursor: pointer; + background-size: 27px 44px; + background-position: center; + background-repeat: no-repeat; +} +.swiper-button-prev.swiper-button-disabled, +.swiper-button-next.swiper-button-disabled { + opacity: 0.35; + cursor: auto; + pointer-events: none; +} +.swiper-button-prev, +.swiper-container-rtl .swiper-button-next { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E"); + left: 10px; + right: auto; +} +.swiper-button-prev.swiper-button-black, +.swiper-container-rtl .swiper-button-next.swiper-button-black { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-prev.swiper-button-white, +.swiper-container-rtl .swiper-button-next.swiper-button-white { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M0%2C22L22%2C0l2.1%2C2.1L4.2%2C22l19.9%2C19.9L22%2C44L0%2C22L0%2C22L0%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-next, +.swiper-container-rtl .swiper-button-prev { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23007aff'%2F%3E%3C%2Fsvg%3E"); + right: 10px; + left: auto; +} +.swiper-button-next.swiper-button-black, +.swiper-container-rtl .swiper-button-prev.swiper-button-black { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23000000'%2F%3E%3C%2Fsvg%3E"); +} +.swiper-button-next.swiper-button-white, +.swiper-container-rtl .swiper-button-prev.swiper-button-white { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20viewBox%3D'0%200%2027%2044'%3E%3Cpath%20d%3D'M27%2C22L27%2C22L5%2C44l-2.1-2.1L22.8%2C22L2.9%2C2.1L5%2C0L27%2C22L27%2C22z'%20fill%3D'%23ffffff'%2F%3E%3C%2Fsvg%3E"); +} +/* Pagination Styles */ +.swiper-pagination { + position: absolute; + text-align: center; + -webkit-transition: 300ms; + transition: 300ms; + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); + z-index: 10; +} +.swiper-pagination.swiper-pagination-hidden { + opacity: 0; +} +/* Common Styles */ +.swiper-pagination-fraction, +.swiper-pagination-custom, +.swiper-container-horizontal > .swiper-pagination-bullets { + bottom: 10px; + left: 0; + width: 100%; +} +/* Bullets */ +.swiper-pagination-bullet { + width: 8px; + height: 8px; + display: inline-block; + border-radius: 100%; + background: #000; + opacity: 0.2; +} +button.swiper-pagination-bullet { + border: none; + margin: 0; + padding: 0; + box-shadow: none; + -moz-appearance: none; + -ms-appearance: none; + -webkit-appearance: none; + appearance: none; +} +.swiper-pagination-clickable .swiper-pagination-bullet { + cursor: pointer; +} +.swiper-pagination-white .swiper-pagination-bullet { + background: #fff; +} +.swiper-pagination-bullet-active { + opacity: 1; + background: #04BE02; +} +.swiper-pagination-white .swiper-pagination-bullet-active { + background: #fff; +} +.swiper-pagination-black .swiper-pagination-bullet-active { + background: #000; +} +.swiper-container-vertical > .swiper-pagination-bullets { + right: 10px; + top: 50%; + -webkit-transform: translate3d(0px, -50%, 0); + transform: translate3d(0px, -50%, 0); +} +.swiper-container-vertical > .swiper-pagination-bullets .swiper-pagination-bullet { + margin: 5px 0; + display: block; +} +.swiper-container-horizontal > .swiper-pagination-bullets .swiper-pagination-bullet { + margin: 0 5px; +} +/* Progress */ +.swiper-pagination-progress { + background: rgba(0, 0, 0, 0.25); + position: absolute; +} +.swiper-pagination-progress .swiper-pagination-progressbar { + background: #007aff; + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + -webkit-transform: scale(0); + transform: scale(0); + -webkit-transform-origin: left top; + transform-origin: left top; +} +.swiper-container-rtl .swiper-pagination-progress .swiper-pagination-progressbar { + -webkit-transform-origin: right top; + transform-origin: right top; +} +.swiper-container-horizontal > .swiper-pagination-progress { + width: 100%; + height: 4px; + left: 0; + top: 0; +} +.swiper-container-vertical > .swiper-pagination-progress { + width: 4px; + height: 100%; + left: 0; + top: 0; +} +.swiper-pagination-progress.swiper-pagination-white { + background: rgba(255, 255, 255, 0.5); +} +.swiper-pagination-progress.swiper-pagination-white .swiper-pagination-progressbar { + background: #fff; +} +.swiper-pagination-progress.swiper-pagination-black .swiper-pagination-progressbar { + background: #000; +} +/* 3D Container */ +.swiper-container-3d { + -webkit-perspective: 1200px; + -o-perspective: 1200px; + perspective: 1200px; +} +.swiper-container-3d .swiper-wrapper, +.swiper-container-3d .swiper-slide, +.swiper-container-3d .swiper-slide-shadow-left, +.swiper-container-3d .swiper-slide-shadow-right, +.swiper-container-3d .swiper-slide-shadow-top, +.swiper-container-3d .swiper-slide-shadow-bottom, +.swiper-container-3d .swiper-cube-shadow { + -webkit-transform-style: preserve-3d; + transform-style: preserve-3d; +} +.swiper-container-3d .swiper-slide-shadow-left, +.swiper-container-3d .swiper-slide-shadow-right, +.swiper-container-3d .swiper-slide-shadow-top, +.swiper-container-3d .swiper-slide-shadow-bottom { + position: absolute; + left: 0; + top: 0; + width: 100%; + height: 100%; + pointer-events: none; + z-index: 10; +} +.swiper-container-3d .swiper-slide-shadow-left { + background-image: -webkit-gradient(linear, left top, right top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + /* Safari 4+, Chrome */ + background-image: -webkit-linear-gradient(right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Chrome 10+, Safari 5.1+, iOS 5+ */ + /* Firefox 3.6-15 */ + /* Opera 11.10-12.00 */ + background-image: linear-gradient(to left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Firefox 16+, IE10, Opera 12.50+ */ +} +.swiper-container-3d .swiper-slide-shadow-right { + background-image: -webkit-gradient(linear, right top, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + /* Safari 4+, Chrome */ + background-image: -webkit-linear-gradient(left, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Chrome 10+, Safari 5.1+, iOS 5+ */ + /* Firefox 3.6-15 */ + /* Opera 11.10-12.00 */ + background-image: linear-gradient(to right, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Firefox 16+, IE10, Opera 12.50+ */ +} +.swiper-container-3d .swiper-slide-shadow-top { + background-image: -webkit-gradient(linear, left top, left bottom, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + /* Safari 4+, Chrome */ + background-image: -webkit-linear-gradient(bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Chrome 10+, Safari 5.1+, iOS 5+ */ + /* Firefox 3.6-15 */ + /* Opera 11.10-12.00 */ + background-image: linear-gradient(to top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Firefox 16+, IE10, Opera 12.50+ */ +} +.swiper-container-3d .swiper-slide-shadow-bottom { + background-image: -webkit-gradient(linear, left bottom, left top, from(rgba(0, 0, 0, 0.5)), to(rgba(0, 0, 0, 0))); + /* Safari 4+, Chrome */ + background-image: -webkit-linear-gradient(top, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Chrome 10+, Safari 5.1+, iOS 5+ */ + /* Firefox 3.6-15 */ + /* Opera 11.10-12.00 */ + background-image: linear-gradient(to bottom, rgba(0, 0, 0, 0.5), rgba(0, 0, 0, 0)); + /* Firefox 16+, IE10, Opera 12.50+ */ +} +/* Coverflow */ +.swiper-container-coverflow .swiper-wrapper, +.swiper-container-flip .swiper-wrapper { + /* Windows 8 IE 10 fix */ + -ms-perspective: 1200px; +} +/* Cube + Flip */ +.swiper-container-cube, +.swiper-container-flip { + overflow: visible; +} +.swiper-container-cube .swiper-slide, +.swiper-container-flip .swiper-slide { + pointer-events: none; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; + z-index: 1; +} +.swiper-container-cube .swiper-slide .swiper-slide, +.swiper-container-flip .swiper-slide .swiper-slide { + pointer-events: none; +} +.swiper-container-cube .swiper-slide-active, +.swiper-container-flip .swiper-slide-active, +.swiper-container-cube .swiper-slide-active .swiper-slide-active, +.swiper-container-flip .swiper-slide-active .swiper-slide-active { + pointer-events: auto; +} +.swiper-container-cube .swiper-slide-shadow-top, +.swiper-container-flip .swiper-slide-shadow-top, +.swiper-container-cube .swiper-slide-shadow-bottom, +.swiper-container-flip .swiper-slide-shadow-bottom, +.swiper-container-cube .swiper-slide-shadow-left, +.swiper-container-flip .swiper-slide-shadow-left, +.swiper-container-cube .swiper-slide-shadow-right, +.swiper-container-flip .swiper-slide-shadow-right { + z-index: 0; + -webkit-backface-visibility: hidden; + backface-visibility: hidden; +} +/* Cube */ +.swiper-container-cube .swiper-slide { + visibility: hidden; + -webkit-transform-origin: 0 0; + transform-origin: 0 0; + width: 100%; + height: 100%; +} +.swiper-container-cube.swiper-container-rtl .swiper-slide { + -webkit-transform-origin: 100% 0; + transform-origin: 100% 0; +} +.swiper-container-cube .swiper-slide-active, +.swiper-container-cube .swiper-slide-next, +.swiper-container-cube .swiper-slide-prev, +.swiper-container-cube .swiper-slide-next + .swiper-slide { + pointer-events: auto; + visibility: visible; +} +.swiper-container-cube .swiper-cube-shadow { + position: absolute; + left: 0; + bottom: 0px; + width: 100%; + height: 100%; + background: #000; + opacity: 0.6; + -webkit-filter: blur(50px); + filter: blur(50px); + z-index: 0; +} +/* Fade */ +.swiper-container-fade.swiper-container-free-mode .swiper-slide { + -webkit-transition-timing-function: ease-out; + transition-timing-function: ease-out; +} +.swiper-container-fade .swiper-slide { + pointer-events: none; + -webkit-transition-property: opacity; + transition-property: opacity; +} +.swiper-container-fade .swiper-slide .swiper-slide { + pointer-events: none; +} +.swiper-container-fade .swiper-slide-active, +.swiper-container-fade .swiper-slide-active .swiper-slide-active { + pointer-events: auto; +} +/* Scrollbar */ +.swiper-scrollbar { + border-radius: 10px; + position: relative; + -ms-touch-action: none; + background: rgba(0, 0, 0, 0.1); +} +.swiper-container-horizontal > .swiper-scrollbar { + position: absolute; + left: 1%; + bottom: 3px; + z-index: 50; + height: 5px; + width: 98%; +} +.swiper-container-vertical > .swiper-scrollbar { + position: absolute; + right: 3px; + top: 1%; + z-index: 50; + width: 5px; + height: 98%; +} +.swiper-scrollbar-drag { + height: 100%; + width: 100%; + position: relative; + background: rgba(0, 0, 0, 0.5); + border-radius: 10px; + left: 0; + top: 0; +} +.swiper-scrollbar-cursor-drag { + cursor: move; +} +/* Preloader */ +.swiper-lazy-preloader { + width: 42px; + height: 42px; + position: absolute; + left: 50%; + top: 50%; + margin-left: -21px; + margin-top: -21px; + z-index: 10; + -webkit-transform-origin: 50%; + transform-origin: 50%; + -webkit-animation: swiper-preloader-spin 1s steps(12, end) infinite; + animation: swiper-preloader-spin 1s steps(12, end) infinite; +} +.swiper-lazy-preloader:after { + display: block; + content: ""; + width: 100%; + height: 100%; + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%236c6c6c'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); + background-position: 50%; + background-size: 100%; + background-repeat: no-repeat; +} +.swiper-lazy-preloader-white:after { + background-image: url("data:image/svg+xml;charset=utf-8,%3Csvg%20viewBox%3D'0%200%20120%20120'%20xmlns%3D'http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg'%20xmlns%3Axlink%3D'http%3A%2F%2Fwww.w3.org%2F1999%2Fxlink'%3E%3Cdefs%3E%3Cline%20id%3D'l'%20x1%3D'60'%20x2%3D'60'%20y1%3D'7'%20y2%3D'27'%20stroke%3D'%23fff'%20stroke-width%3D'11'%20stroke-linecap%3D'round'%2F%3E%3C%2Fdefs%3E%3Cg%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(30%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(60%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(90%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(120%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.27'%20transform%3D'rotate(150%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.37'%20transform%3D'rotate(180%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.46'%20transform%3D'rotate(210%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.56'%20transform%3D'rotate(240%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.66'%20transform%3D'rotate(270%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.75'%20transform%3D'rotate(300%2060%2C60)'%2F%3E%3Cuse%20xlink%3Ahref%3D'%23l'%20opacity%3D'.85'%20transform%3D'rotate(330%2060%2C60)'%2F%3E%3C%2Fg%3E%3C%2Fsvg%3E"); +} +@-webkit-keyframes swiper-preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + } +} +@keyframes swiper-preloader-spin { + 100% { + -webkit-transform: rotate(360deg); + transform: rotate(360deg); + } +} +.weui_actionsheet { + z-index: 100; +} +.notification { + position: fixed; + width: 100%; + min-height: 3.4rem; + top: -2rem; + padding-top: 2rem; + left: 0; + right: 0; + z-index: 9999; + background-color: rgba(0, 0, 0, 0.85); + color: white; + font-size: .65rem; + -webkit-transform: translate3d(0, -100%, 0); + transform: translate3d(0, -100%, 0); + -webkit-transition: .4s; + transition: .4s; +} +.notification.notification-in { + -webkit-transform: translate3d(0, 0, 0); + transform: translate3d(0, 0, 0); +} +.notification.touching { + -webkit-transition-duration: 0s; + transition-duration: 0s; +} +.notification .notification-inner { + padding: .4rem .6rem 1rem .6rem; + display: -webkit-box; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -webkit-box-align: start; + -ms-flex-align: start; + -webkit-align-items: flex-start; + align-items: flex-start; +} +.notification .notification-content { + width: 100%; + margin: 0rem .4rem; +} +.notification .notification-title { + font-weight: bold; +} +.notification .notification-text { + line-height: 1; +} +.notification .notification-media { + height: 1rem; + width: 1rem; +} +.notification .notification-media img { + width: 100%; +} +.notification .notification-handle-bar { + position: absolute; + bottom: .2rem; + left: 50%; + -webkit-transform: translate3d(-50%, 0, 0); + transform: translate3d(-50%, 0, 0); + width: 2rem; + height: .3rem; + border-radius: .15rem; + background: white; + opacity: .5; +} diff --git a/src/main/webapp/decodeqr.jsp b/src/main/webapp/decodeqr.jsp new file mode 100644 index 00000000..30d7309e --- /dev/null +++ b/src/main/webapp/decodeqr.jsp @@ -0,0 +1,62 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" + pageEncoding="UTF-8"%> +<%@ taglib prefix="l2d" uri="/WEB-INF/LongToDateTag.tld"%> +<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%@ taglib prefix='fmt' uri="http://java.sun.com/jsp/jstl/fmt" %> +<%@taglib prefix="spring" uri="http://www.springframework.org/tags" %> + + + + + +<c:if test="${empty test}">解析二维码</c:if> +<c:if test="${not empty test}">${test}</c:if> + + + + + + + + + + + + + + +
+ +
+ +
+
+ +
+ + \ No newline at end of file diff --git a/src/main/webapp/demolist.html b/src/main/webapp/demolist.html new file mode 100644 index 00000000..8556cd9d --- /dev/null +++ b/src/main/webapp/demolist.html @@ -0,0 +1,46 @@ + + + + + demo list + + + + + + + + \ No newline at end of file diff --git a/src/main/webapp/ehcache.jsp b/src/main/webapp/ehcache.jsp new file mode 100644 index 00000000..d9b90441 --- /dev/null +++ b/src/main/webapp/ehcache.jsp @@ -0,0 +1,28 @@ +<%@ page language="java" import="java.util.*" + contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> + +ehcache + + + +
+
+
+

ehcache attributes:

+
+ + + + + + + +
属性名属性值
caches${caches}
getDiskStorePath${getDiskStorePath }
getName${getName }
getStatus${getStatus}
getStatistics${getStatistics }
+
+
+
+ + + + + \ No newline at end of file diff --git a/src/main/webapp/error.jsp b/src/main/webapp/error.jsp new file mode 100644 index 00000000..f9840972 --- /dev/null +++ b/src/main/webapp/error.jsp @@ -0,0 +1,33 @@ +<%@ page language="java" isErrorPage="true" errorPage="500.jsp" + contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> +<%-- <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> --%> + + + + + +error + + + + +
+

发生错误啦:


+ ${ex}
+

错误堆栈


+ ${stackTrace} + +

错误信息

+
+

错误状态码:${errCode}

+

错误详情:${errMsg}

+
+ +
错误信息:${errMsg } +
+
+ + \ No newline at end of file diff --git a/src/main/webapp/export/20160305172907.xls b/src/main/webapp/export/20160305172907.xls deleted file mode 100644 index cbb14bc9..00000000 Binary files a/src/main/webapp/export/20160305172907.xls and /dev/null differ diff --git a/src/main/webapp/export/20160305173241.xls b/src/main/webapp/export/20160305173241.xls deleted file mode 100644 index cbb14bc9..00000000 Binary files a/src/main/webapp/export/20160305173241.xls and /dev/null differ diff --git a/src/main/webapp/favicon.ico b/src/main/webapp/favicon.ico new file mode 100644 index 00000000..b48b3442 Binary files /dev/null and b/src/main/webapp/favicon.ico differ diff --git a/src/main/webapp/image/@Timed.png b/src/main/webapp/image/@Timed.png new file mode 100644 index 00000000..77798e2d Binary files /dev/null and b/src/main/webapp/image/@Timed.png differ diff --git a/src/main/webapp/image/demo.gif b/src/main/webapp/image/demo.gif new file mode 100644 index 00000000..d76a290c Binary files /dev/null and b/src/main/webapp/image/demo.gif differ diff --git a/src/main/webapp/image/jwebunitdemo.png b/src/main/webapp/image/jwebunitdemo.png new file mode 100644 index 00000000..c04b43df Binary files /dev/null and b/src/main/webapp/image/jwebunitdemo.png differ diff --git a/src/main/webapp/image/metrics.png b/src/main/webapp/image/metrics.png new file mode 100644 index 00000000..220f1300 Binary files /dev/null and b/src/main/webapp/image/metrics.png differ diff --git a/src/main/webapp/image/swagger.png b/src/main/webapp/image/swagger.png new file mode 100644 index 00000000..58802a98 Binary files /dev/null and b/src/main/webapp/image/swagger.png differ diff --git a/src/main/webapp/index.html b/src/main/webapp/index.html index 833ab5da..292e3bfa 100644 --- a/src/main/webapp/index.html +++ b/src/main/webapp/index.html @@ -3,15 +3,54 @@ + 登陆系统 - + + + + + + + +
@@ -43,19 +82,20 @@

登陆

@@ -75,11 +115,5 @@

...or login with:

-
- -
\ No newline at end of file diff --git a/src/main/webapp/index.jsp b/src/main/webapp/index.jsp index 49992039..ce9b9226 100644 --- a/src/main/webapp/index.jsp +++ b/src/main/webapp/index.jsp @@ -1,6 +1,81 @@ - - -

Hello World!

- user/showUser - - + +<%-- <%@ page trimDirectiveWhitespaces="true"%> --%> +<%@ page language="java" isErrorPage="true" errorPage="500.jsp" + contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%> + + + Hello World + + + + +

Hello World!

+ user/showUser
+ ${pageContext.request.scheme }
+ ${pageContext.request.serverName }
+ ${pageContext.request.serverPort }
+ ${pageContext.request.contextPath }
+ 通过EL设置basepath + + ${pageContext.request.scheme}://${pageContext.request.serverName}:${pageContext.request.serverPort}${pageContext.request.contextPath } + + ${basepath }
+
+	${pageContext.request.queryString} 取得请求的参数字符串
+	${pageContext.request.requestURL} 取得请求的URL,不包括参数字符串
+	${pageContext.request.contextPath}         服务的web application 的名称
+	${pageContext.request.method}           取得HTTP 的方法(GET、POST)
+	${pageContext.request.protocol}         取得使用的协议(HTTP/1.1、HTTP/1.0)
+	${pageContext.request.remoteUser}         取得用户名称
+	${pageContext.request.remoteAddr }         取得用户的IP 地址
+	${pageContext.session.id}               取得session 的ID
+	${pageContext.servletContext.serverInfo}   取得主机端的服务信息
+	
+ +
+ metrics + + diff --git a/src/main/webapp/locationClient.jsp b/src/main/webapp/locationClient.jsp new file mode 100644 index 00000000..55722f6e --- /dev/null +++ b/src/main/webapp/locationClient.jsp @@ -0,0 +1,213 @@ +<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> +<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> +<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> + + + + + +CXF Rest test application + + + + +

Technologies

+
    +
  • CXF, JAX-RS (REST), JAX-WS (SOAP)
  • +
  • Spring Security
  • +
  • Spring bean validation, JSR 303
  • +
+ +">WSDL / WADL location + + + + + +
+All locations : ">/rest/location/* +

Result

+ + + + + + + + + + + + + + + +
ResultRest URLs
+ +Location ID is : ${locationData.id} +
+Timezone is : ${locationData.timezone} +
+Time is : ${locationData.date} +
+Location is : ${locationData.location} +
+ +
+ ">/cxf/rest/location/${locationData.location} +
+ ">/cxf/rest/location/${locationData.location}.xml +
+ ">/cxf/rest/location/${locationData.location}.json +
+
+
+ +
+ + + + +

Read Location

+
+ + + + +
+ + + + +
+ + +
+ +
+

Read All Location

+
+ + + +
+ + +
+ + +
+

Create Location

+ + + + + +
+ + + + + + + + +
+ + +
+ +
+

Update or create Location

+
+ + + + +
+ + + + + + + +
+ + +
+ +
+

Delete Location

+
+ + + + +
+ + + +
+ + +
+ +
+

Delete All Locations

+
+ + + + +
+ + + +
+ + + \ No newline at end of file diff --git a/src/main/webapp/manage.html b/src/main/webapp/manage.html index 49615e87..07fcf3f1 100644 --- a/src/main/webapp/manage.html +++ b/src/main/webapp/manage.html @@ -2,260 +2,14 @@ + 信息管理页 - - - - - - - - - - - + + + -