Skip to content

Commit 49e0c1c

Browse files
author
vison.cao
committed
static and pebble
1 parent 6ffcefd commit 49e0c1c

File tree

15 files changed

+628
-43
lines changed

15 files changed

+628
-43
lines changed

pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,11 @@
5555
<artifactId>reflections</artifactId>
5656
<version>0.9.12</version>
5757
</dependency>
58+
<dependency>
59+
<groupId>io.pebbletemplates</groupId>
60+
<artifactId>pebble</artifactId>
61+
<version>3.1.4</version>
62+
</dependency>
5863
</dependencies>
5964

6065
<build>
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.vison.webmvc.controller;
2+
3+
import com.vison.webmvc.framework.GetMapping;
4+
import com.vison.webmvc.framework.ViewEngine;
5+
import java.io.IOException;
6+
import java.util.HashMap;
7+
import java.util.Map;
8+
9+
/**
10+
*
11+
* @author vison.cao <visonforcoding@gmail.com>
12+
*/
13+
public class HelloController {
14+
15+
@GetMapping(path = "/hello")
16+
public String hello() throws IOException {
17+
Map<String, Object> context = new HashMap<>();
18+
context.put("vison", "visonforcoding");
19+
return ViewEngine.render("/hello.pebble", context);
20+
}
21+
22+
}

src/main/java/com/vison/webmvc/controller/UserController.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,14 @@
99
* @author vison.cao <visonforcoding@gmail.com>
1010
*/
1111
public class UserController {
12-
12+
1313
public UserController() {
1414
}
15-
15+
1616
@GetMapping(path = "/user/profile")
1717
public String profile(HttpServletRequest request, HttpServletResponse response) {
18+
System.out.print(request.getCookies());
1819
return "i am user profile";
1920
}
20-
21+
2122
}
Lines changed: 45 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.vison.webmvc.framework;
22

3+
import com.vison.webmvc.framework.exception.NullRouteException;
34
import java.io.IOException;
45
import java.lang.reflect.Method;
56
import java.lang.reflect.Parameter;
@@ -29,59 +30,62 @@ public class DispatchServlet extends HttpServlet {
2930

3031
@Override
3132
public void init() throws ServletException {
32-
33+
ViewEngine.load(this.getServletContext());
3334
}
3435

3536
@Override
36-
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
37+
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
38+
throws ServletException, IOException {
3739
resp.setContentType("text/html");
3840
resp.setCharacterEncoding("UTF-8");
3941
String path = req.getRequestURI().substring(req.getContextPath().length());
40-
Object res = dispatch(path, req, resp);
42+
Object res;
43+
try {
44+
res = dispatch(path, req, resp);
45+
} catch (NullRouteException ex) {
46+
res = "404 Not Found";
47+
}
4148
String responseBody = this.handInvokeRes(res);
4249
resp.getWriter().write(responseBody);
4350
resp.getWriter().flush();
4451
}
4552

46-
private Object dispatch(String path, HttpServletRequest request, HttpServletResponse response) {
53+
private Object dispatch(String path, HttpServletRequest request, HttpServletResponse response)
54+
throws NullRouteException {
4755
Method method = this.getMaps(path);
48-
log.info(method);
4956
Object res = null;
50-
if (method != null);
51-
{
52-
Parameter[] parameters = method.getParameters();
53-
Object[] arguments = new Object[parameters.length];
54-
for (int i = 0; i < parameters.length; i++) {
55-
Parameter parameter = parameters[i];
56-
log.info(parameter.getType());
57-
Class<?> parameterClass = parameter.getType();
58-
String parameterName = parameter.getName();
59-
if (parameterClass == HttpServletRequest.class) {
60-
arguments[i] = request;
61-
} else if (parameterClass == HttpServletResponse.class) {
62-
arguments[i] = response;
63-
} else if (parameterClass == HttpSession.class) {
64-
arguments[i] = request.getSession();
65-
} else if (parameterClass == int.class) {
66-
arguments[i] = Integer.valueOf(getOrDefault(request, parameterName, "0"));
67-
} else if (parameterClass == long.class) {
68-
arguments[i] = Long.valueOf(getOrDefault(request, parameterName, "0"));
69-
} else if (parameterClass == boolean.class) {
70-
arguments[i] = Boolean.valueOf(getOrDefault(request, parameterName, "false"));
71-
} else if (parameterClass == String.class) {
72-
arguments[i] = getOrDefault(request, parameterName, "");
73-
} else {
74-
throw new RuntimeException("Missing handler for type: " + parameterClass);
75-
}
76-
}
77-
Object obj;
78-
try {
79-
obj = method.getDeclaringClass().getDeclaredConstructor().newInstance();
80-
res = method.invoke(obj, arguments);
81-
} catch (Exception e) {
82-
log.error("方法invoke失败", e);
57+
Parameter[] parameters = method.getParameters();
58+
Object[] arguments = new Object[parameters.length];
59+
for (int i = 0; i < parameters.length; i++) {
60+
Parameter parameter = parameters[i];
61+
log.info(parameter.getType());
62+
Class<?> parameterClass = parameter.getType();
63+
String parameterName = parameter.getName();
64+
if (parameterClass == HttpServletRequest.class) {
65+
arguments[i] = request;
66+
} else if (parameterClass == HttpServletResponse.class) {
67+
arguments[i] = response;
68+
} else if (parameterClass == HttpSession.class) {
69+
arguments[i] = request.getSession();
70+
} else if (parameterClass == int.class) {
71+
arguments[i] = Integer.valueOf(getOrDefault(request, parameterName, "0"));
72+
} else if (parameterClass == long.class) {
73+
arguments[i] = Long.valueOf(getOrDefault(request, parameterName, "0"));
74+
} else if (parameterClass == boolean.class) {
75+
arguments[i] = Boolean.valueOf(getOrDefault(request, parameterName, "false"));
76+
} else if (parameterClass == String.class) {
77+
arguments[i] = getOrDefault(request, parameterName, "");
78+
} else {
79+
throw new RuntimeException("Missing handler for type: " + parameterClass);
8380
}
8481
}
82+
Object obj;
83+
try {
84+
obj = method.getDeclaringClass().getDeclaredConstructor().newInstance();
85+
res = method.invoke(obj, arguments);
86+
} catch (Exception e) {
87+
log.error("方法invoke失败", e);
88+
}
8589
return res;
8690
}
8791

@@ -97,7 +101,8 @@ private String handInvokeRes(Object obj) {
97101
return "";
98102
}
99103

100-
private Method getMaps(String path) {
104+
private Method getMaps(String path) throws NullRouteException {
105+
101106
String packageName = "com.vison.webmvc.controller";
102107
ConfigurationBuilder config = new ConfigurationBuilder();
103108
config.filterInputsBy(new FilterBuilder().includePackage(packageName));
@@ -112,6 +117,6 @@ private Method getMaps(String path) {
112117
return method;
113118
}
114119
}
115-
return null;
120+
throw new NullRouteException();
116121
}
117122
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package com.vison.webmvc.framework;
2+
3+
import java.io.BufferedInputStream;
4+
import java.io.FileInputStream;
5+
import java.io.IOException;
6+
import java.io.InputStream;
7+
import java.io.OutputStream;
8+
import java.nio.file.Files;
9+
import java.nio.file.Path;
10+
import java.nio.file.Paths;
11+
import javax.servlet.ServletContext;
12+
import javax.servlet.ServletException;
13+
import javax.servlet.annotation.WebServlet;
14+
import javax.servlet.http.HttpServlet;
15+
import javax.servlet.http.HttpServletRequest;
16+
import javax.servlet.http.HttpServletResponse;
17+
18+
/**
19+
*
20+
* @author vison.cao <visonforcoding@gmail.com>
21+
*/
22+
@WebServlet(urlPatterns = {"/favicon.ico", "/static/*"})
23+
public class FileServlet extends HttpServlet {
24+
25+
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
26+
throws ServletException, IOException {
27+
// 读取当前请求路径:
28+
ServletContext ctx = req.getServletContext();
29+
// RequestURI包含ContextPath,需要去掉:
30+
String urlPath = req.getRequestURI().substring(ctx.getContextPath().length());
31+
// 获取真实文件路径:
32+
String filepath = ctx.getRealPath(urlPath);
33+
if (filepath == null) {
34+
// 无法获取到路径:
35+
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
36+
return;
37+
}
38+
Path path = Paths.get(filepath);
39+
if (!path.toFile().isFile()) {
40+
// 文件不存在:
41+
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
42+
return;
43+
}
44+
// 根据文件名猜测Content-Type:
45+
String mime = Files.probeContentType(path);
46+
if (mime == null) {
47+
mime = "application/octet-stream";
48+
}
49+
resp.setContentType(mime);
50+
// 读取文件并写入Response:
51+
OutputStream output = resp.getOutputStream();
52+
try (InputStream input = new BufferedInputStream(new FileInputStream(filepath))) {
53+
input.transferTo(output);
54+
}
55+
output.flush();
56+
}
57+
58+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package com.vison.webmvc.framework;
2+
3+
import com.mitchellbosecke.pebble.PebbleEngine;
4+
import com.mitchellbosecke.pebble.loader.ServletLoader;
5+
import com.mitchellbosecke.pebble.template.PebbleTemplate;
6+
import java.io.IOException;
7+
import java.io.StringWriter;
8+
import java.io.Writer;
9+
import java.util.Map;
10+
import javax.servlet.ServletContext;
11+
12+
/**
13+
*
14+
* @author vison.cao <visonforcoding@gmail.com>
15+
*/
16+
public class ViewEngine {
17+
18+
private static PebbleEngine engine;
19+
20+
public static void load(ServletContext servletContext) {
21+
// 定义一个ServletLoader用于加载模板:
22+
ServletLoader loader = new ServletLoader(servletContext);
23+
// 模板编码:
24+
loader.setCharset("UTF-8");
25+
// 模板前缀,这里默认模板必须放在`/WEB-INF/templates`目录:
26+
loader.setPrefix("/WEB-INF/templates");
27+
// 模板后缀:
28+
loader.setSuffix("");
29+
// 创建Pebble实例:
30+
engine = new PebbleEngine.Builder()
31+
.autoEscaping(true) // 默认打开HTML字符转义,防止XSS攻击
32+
.cacheActive(false) // 禁用缓存使得每次修改模板可以立刻看到效果
33+
.loader(loader).build();
34+
}
35+
36+
public static String render(String template, Map<String, Object> context) throws IOException {
37+
Writer writer = new StringWriter();
38+
39+
PebbleTemplate compiledTemplate = engine.getTemplate(template);
40+
compiledTemplate.evaluate(writer, context);
41+
String output = writer.toString();
42+
return output;
43+
44+
}
45+
46+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package com.vison.webmvc.framework.exception;
2+
3+
/**
4+
*
5+
* @author vison.cao <visonforcoding@gmail.com>
6+
*/
7+
public class NullRouteException extends Exception {
8+
9+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<html>
2+
<head>
3+
<!-- ZUI 标准版压缩后的 CSS 文件 -->
4+
<link rel="stylesheet" href="/static/css/zui.min.css">
5+
6+
<!-- ZUI Javascript 依赖 jQuery -->
7+
<script src="/static/js/jquery.min.js"></script>
8+
<!-- ZUI 标准版压缩后的 JavaScript 文件 -->
9+
<script src="/static/js/zui.min.js"></script>
10+
</head>
11+
<body>
12+
<article class="article">
13+
<!-- 文章头部 -->
14+
<header>
15+
<h1> hello,{{ vison }}
16+
</h1>
17+
<!-- 文章属性列表 -->
18+
<dl class="dl-inline">
19+
<dt>属性</dt>
20+
<dd>值</dd>
21+
...
22+
</dl>
23+
<div class="abstract">
24+
<p>摘要信息</p>
25+
</div>
26+
</header>
27+
<!-- 文章正文部分 -->
28+
<section class="content">
29+
...
30+
</section>
31+
<!-- 文章底部 -->
32+
<footer>
33+
<ul class="pager pager-justify">
34+
<li class="previous"><a href="#"><i class="icon-arrow-left"></i> 上一篇</a></li>
35+
<li><a href="#"><i class="icon-list-ul"></i> 目录</a></li>
36+
<li class="next disabled"><a href="#">没有下一篇 <i class="icon-arrow-right"></i></a></li>
37+
</ul>
38+
</footer>
39+
</article>
40+
</body>
41+
</html>

src/main/webapp/static/css/zui.min.css

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
82.8 KB
Binary file not shown.

0 commit comments

Comments
 (0)