Spark开发简单示例
一个Spark的简单示例
涉及的内容有:
设置端口、设置线程池、设置静态资源目录、拦截器、捕获异常、模板的使用等一些简单展示
主要流程为:
用户没有登录就不能访问登录以外的页面(可直接访问的静态资源除外),登录后可以访问所有的用户列表(并没有做其他功能)
关于环境的搭建可以参考:“Spark开发环境搭建”
所有的java代码如下
UserService.java(并没有使用数据库等,直接写死的数据)
package me.ooi.testSpark; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; /** * <p>用户service</p> * <p>Author: jun.zhao</p> * <p>Date: 2016年10月24日</p> */ public class UserService { //这里就用一个map保存一下用户信息了 public Map<String, User> users = new HashMap<>() ; public UserService(){ users.put("1", new User("1","小明",17)) ; users.put("2", new User("2","小红",18)) ; users.put("3", new User("3","小刚",19)) ; } //根据用户名查询用户 public User getUserByName(String name){ Optional<User> user = users.values().stream().filter(u->u.getName().equals(name)).findFirst() ; if( user.isPresent() ){ return user.get() ; }else { return null ; } } //获取所有的用户 public List<User> findUser(){ return users.values().stream().collect(Collectors.toList()) ; } }
User.java
package me.ooi.testSpark; /** * <p>用户</p> * <p>Author: jun.zhao</p> * <p>Date: 2016年10月24日</p> */ public class User { private String id ; private String name ; private Integer age ; public User() { super(); } public User(String id, String name, Integer age) { super(); this.id = id; this.name = name; this.age = age; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }
UserMgr.java(这里是示例的主要内容,一些需要注意的都写了注释)
package me.ooi.testSpark; import static spark.Spark.*; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import freemarker.template.Configuration; import freemarker.template.TemplateExceptionHandler; import spark.ModelAndView; import spark.Session; import spark.template.freemarker.FreeMarkerEngine; /** * <p>一个用户管理的例子</p> * <p>Author: jun.zhao</p> * <p>Date: 2016年10月24日</p> */ public class UserMgr { public static final Logger LOG = LoggerFactory.getLogger(HelloSpark.class) ; private static final Configuration FREEMARKER_CFG = new Configuration() ; public static final String SESSION_USER = "session_user" ; private UserService userService = new UserService() ; static{ String templateDir = getWebContentDir()+"template" ; try { if( LOG.isInfoEnabled() ){ LOG.info("模板目录为:"+templateDir) ; } FREEMARKER_CFG.setDirectoryForTemplateLoading(new File(templateDir)); } catch (IOException e) { e.printStackTrace(); } FREEMARKER_CFG.setDefaultEncoding("UTF-8"); FREEMARKER_CFG.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER); } public void init(){ configServer(); configStaticFile(); configFilter(); configRequest(); } //设置服务器的一些参数 public void configServer(){ //设置端口 //This has to be done before using routes and filters port(8080) ; //设置线程池 int maxThreads = 1000; int minThreads = 10; int timeOutMillis = 30*1000; threadPool(maxThreads, minThreads, timeOutMillis); } public static String getWebContentDir(){ //webcontent下的文件 String root = System.getProperty("user.dir") ; String webContentDir = root + File.separator + "WebContent" + File.separator ; return webContentDir ; } //静态文件设置 public void configStaticFile(){ //测试html等静态资源,这些资源可以直接访问 //classpath下文件 staticFiles.location("/publicres") ; //webcontent下的文件 String publicDir = getWebContentDir() + "public" ; ; if( LOG.isInfoEnabled() ){ LOG.info("public目录为:"+publicDir) ; } staticFiles.externalLocation(publicDir) ; } //用户权限拦截器 public void configFilter(){ //不需要登录的地址 List<String> dontNeedLoginPathList = new ArrayList<>() ; dontNeedLoginPathList.add("/login") ; dontNeedLoginPathList.add("/login.html") ; //假设session中有用户,则可以访问所有内容,否则提示登录 before((request, response) -> { if( LOG.isInfoEnabled() ){ LOG.info("拦截器拦截请求:"+request.pathInfo()) ; } if( !dontNeedLoginPathList.contains(request.pathInfo()) ){ Session session = request.session() ; User u = session.attribute(SESSION_USER) ; if( u == null ){ response.redirect("/login.html") ; //终止请求继续走下去(不终止的话拦截器就没有意义了) halt() ; } } }) ; } //所有的流程 public void configRequest(){ //异常处理,不处理异常就不知道报了什么异常 exception(RuntimeException.class, (exception, request, response) -> { //... exception.printStackTrace() ; halt(500) ; }); exception(Exception.class, (exception, request, response) -> { //... exception.printStackTrace() ; halt(500) ; }); //登录 post("/login", (request, response) -> { if( LOG.isInfoEnabled() ){ LOG.info("进入请求:"+request.pathInfo()) ; } //这里就用name来验证用户了 String name = request.queryParams("name") ; User u = userService.getUserByName(name) ; if( u == null ){ response.redirect("/login.html") ; }else { request.session().attribute(SESSION_USER, u) ; response.redirect("/user/list"); } return null ; }); //登出 get("/logout", (request, response)->{ if( LOG.isInfoEnabled() ){ LOG.info("进入请求:"+request.pathInfo()) ; } request.session().removeAttribute(SESSION_USER) ; response.redirect("/login.html") ; return null ; }) ; //用户列表 get("/user/list", (request, response)->{ if( LOG.isInfoEnabled() ){ LOG.info("进入请求:"+request.pathInfo()) ; } Map<String, Object> data = new HashMap<>() ; List<User> userList = userService.findUser() ; data.put("userList", userList) ; return new ModelAndView(data, "user/list.html") ; }, new FreeMarkerEngine(FREEMARKER_CFG)) ; } }
HelloSpark.java(Main方法)
package me.ooi.testSpark; public class HelloSpark { public static void main(String[] args) { new UserMgr().init(); } }
在pom.xml中加入spark的freemarker插件
<dependency> <groupId>com.sparkjava</groupId> <artifactId>spark-template-freemarker</artifactId> <version>2.3</version> </dependency>
需要新建的目录如下
1,在资源目录“src/main/resources”下新建“publicres(注意:文件名不能为java package不能使用的名字)”文件夹作为可以直接访问的文件
如:文件“publicres/test.html”,则可以直接通过“http://locahost:8080/test.html”的方式访问
2,在WebContent下分别新建“public(存放一些可以直接访问的文件)”和“template(存放一些模板)”文件夹
这个例子需要的页面如下
1,WebContent/public/login.html(可直接访问到)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>登录</title> </head> <body> <form action="/login" method="post"> 用户名:<input type="text" name="name"> </form> </body> </html>
2,WebContent/template/user/list.html(作为模板使用,模板引擎为freemarker)
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>用户列表</title> </head> <body> <table> <thead> <tr> <th>id</th> <th>名字</th> <th>年龄</th> </tr> </thead> <tbody> <#list userList as u> <tr> <td>${u.id}</td> <td>${u.name}</td> <td>${u.age}</td> </tr> </#list> </tbody> </table> </body> </html>
发布
导出为jar包后,将WebContent整个拷贝("WEB-INF"和"META-INF"两个目录不需要拷贝)到和jar包同一目录下(如下图所示),使用java -jar命令启动即可,这样就可以动态修改WebContent里面的页面和模板了。