3.自己动手写Java Web框架-MVC初体验
来源:互联网 发布:python library api 编辑:程序博客网 时间:2024/05/22 23:36
jw的github地址是https://github.com/menyouping/jw
第一次看到这篇文章时非常惊讶,介绍FastPHP如何实现一个简易的MVC。我的大脑中总是将Servlet与Spring MVC割裂开来,总认为是两个事物,看到这篇文章后茅塞顿开!Java版的MVC,我也可以玩了!
理一下思路:当外界发送一个请求,被jw-web拦截,请求跳转到一个自定义的HttpServlet中,Servlet解析请求地址再将请求转到相应的Controller类中,Controller类的相应函数进行逻辑处理后返回响应内容,这样MVC逻辑就走完了,是不是感觉有点简单,用Java反射功能就能实现。
下面我们一步步去完成这个MVC。
添加依赖
修改jw-parent/pom.xml
在modules节点下面添加兄弟节点,统一管理整个项目依赖的外部资源版本信息
<dependencyManagement> <dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <version>2.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.2</version> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.16</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> </dependencies></dependencyManagement>
修改jw-core/pom.xml
添加依赖
<dependencies> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency></dependencies>
修改jw-web/pom.xml
添加依赖
<dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId></dependency><dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId></dependency><dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId></dependency>
修改web.xml
修改jw-web/src/main/webapp/WEB-INF/web.xml,在其中注册servlet, 拦截jw-web应用下的所有请求
<servlet> <servlet-name>appServlet</servlet-name> <servlet-class>com.jw.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup></servlet><servlet-mapping> <servlet-name>appServlet</servlet-name> <url-pattern>/</url-pattern></servlet-mapping>
创建Servlet
新建文件jw-core/src/main/java/com/jw/web/servlet/DispatcherServlet.java
package com.jw.web.servlet;import java.io.IOException;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import javax.servlet.ServletException;import javax.servlet.http.HttpServlet;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.slf4j.Logger;import org.slf4j.LoggerFactory;import com.alibaba.fastjson.JSON;import com.jw.util.ConfigUtils;import com.jw.util.StringUtils;public class DispatcherServlet extends HttpServlet { private static final Logger LOGGER = LoggerFactory.getLogger(DispatcherServlet.class); private static final long serialVersionUID = -3874308705324703315L; public DispatcherServlet() { } public void init() { } public void service(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { String appName = request.getSession().getServletContext().getContextPath(); String path = request.getRequestURI().substring(appName.length()); LOGGER.info("Request path is {}", path); // /index/index/ => /index/index if (path.length() > 1 && path.endsWith("/")) { path = path.substring(0, path.length() - 1); } else if (path.startsWith("/")) {// /index/index => index/index path = path.replaceFirst("/", ""); } if (path.isEmpty()) { path = "index/index"; } else if (!path.contains("/")) { path += "/index";// index => index/index } String[] paths = path.split("/", 2); String controllerClazeName = ConfigUtils.getProperty("package.scan") + "." + StringUtils.upperFirst(paths[0]) + "Controller"; String methodName = paths[1]; try { Class<?> controllerClaze = Class.forName(controllerClazeName); Method method = controllerClaze.getMethod(methodName, new Class<?>[] { HttpServletRequest.class, HttpServletResponse.class }); Object controller = controllerClaze.newInstance(); Object result = method.invoke(controller, new Object[] { request, response }); response.setHeader("Content-type", "application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(result)); } catch (Exception e) { LOGGER.error("Error raised in DispatcherServlet.", e); Map<String, Object> result = new HashMap<String, Object>(); result.put("status", 500); result.put("message", e.getMessage()); response.setHeader("Content-type", "application/json;charset=UTF-8"); response.getWriter().write(JSON.toJSONString(result)); } }}
controllerClazeName由两部分组成,第一部分ConfigUtils.getProperty(“package.scan”)是package的路径,第二部分是Controller的类名StringUtils.upperFirst(paths[0]) + “Controller”, StringUtils.upperFirst()使首字母大写。
添加配置文件jw-web/src/main/resources/application.properties
package.scan=com.jay.mvc
package.scan配置了Controller类所在的package地址。
新增类jw-core/src/main/java/com/jw/util/StringUtils.java
package com.jw.util;public class StringUtils { public static boolean isEmpty(String str) { return str == null || str.isEmpty(); } /** * 首字母大写 * * @param str * @return */ public static String upperFirst(String str) { if (StringUtils.isEmpty(str)) return str; char ch = str.charAt(0); if (ch < 'a' || ch > 'z') return str; char[] cs = str.toCharArray(); cs[0] = Character.toUpperCase(ch); return String.valueOf(cs); }}
测试
添加测试Controller
新增类jw-web/src/main/java/com/jay/mvc/IndexController.java
package com.jay.mvc;import java.util.HashMap;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class IndexController { public Object index(HttpServletRequest request, HttpServletResponse response) { Map<String, Object> result = new HashMap<String, Object>(); result.put("status", 200); result.put("message", "index method is invorked!"); return result; } public Object welcome(HttpServletRequest request, HttpServletResponse response) { Map<String, Object> result = new HashMap<String, Object>(); result.put("status", 200); result.put("message", "Welcome to jw's world!"); return result; }}
添加Tomcat7 server
这一步不介绍了
修改Project Facets
检查一下Project Facets设置,Dynamic Web Module必须是2.5。若当前设置是2.3,打开文件jw-web/.settings/org.eclipse.wst.common.project.facet.core.xml
,修改jst.web和java的jdk版本,可参考此文。
<?xml version="1.0" encoding="UTF-8"?><faceted-project> <fixed facet="wst.jsdt.web"/> <installed facet="jst.web" version="2.5"/> <installed facet="wst.jsdt.web" version="1.0"/> <installed facet="java" version="1.7"/></faceted-project>
消除错误
如果在Problem面板中看到xx/target/classes/META-INF/MANIFES no such file or directory的错误,依次点击菜单Window/Preference/Maven/Java EE Intergration, 不勾选Maven Archiver generates files under the build directory。
启动jw-web
选中jw-web,右键Debug As -> Debug on Server
服务器启动,打开了http://localhost:8080/jw-web/ ,显示如下
Hello World!
显示内容来自于jw-web/src/main/webapp/index.jsp
测试jsp
修改网址,http://localhost:8080/jw-web/index.jsp,回车。
页面仍显示:
Hello World!
测试MVC
MVC的地址规则是http://localhost:8080/jw-web/{{controller}}//{{method}}
,{{method}}不填时默认为index方法。
修改网址,http://localhost:8080/jw-web/index ,回车。
调试时可以看到controllerClazeName的运行时值是”com.jay.mvc.IndexController”,成功找到目标Controller.
method的值是”com.jay.mvc.IndexController.index(HttpServletRequest,HttpServletResponse)”, 目标方法也找到。
最后看到页面显示:
{"message":"index method is invorked!","status":200}
修改网址,http://localhost:8080/jw-web/welcome,回车。
页面显示:
{"message":"com.jay.mvc.WelcomeController","status":500}
出错了,因为没有找到WelcomeController。
修改网址,http://localhost:8080/jw-web/index/welcome,回车。
页面显示:
{"message":"Welcome to jw's world!","status":200}
至此简单的MVC完成。
本节资源地址: https://github.com/menyouping/jw-example/blob/master/3/jw-parent.zip
- 3.自己动手写Java Web框架-MVC初体验
- 4.自己动手写Java Web框架-MVC++
- 自己动手写MVC框架
- 0.自己动手写Java Web框架-首页
- 5.自己动手写Java Web框架-上下文
- 6.自己动手写Java Web框架-Model
- 自己动手写一个web框架(一):实现IOC与MVC
- 自己动手写PHP MVC框架
- 自己动手写PHP MVC框架
- 自己动手写PHP MVC框架
- 自己动手写PHP MVC框架
- 自己动手写web框架----1
- 自己动手写web框架----2
- 1.自己动手写Java Web框架-创建项目
- 2.自己动手写Java Web框架-读取配置
- 自己动手模仿 springmvc 写一个 mvc框架
- 自己动手模仿 springmvc 写一个 mvc框架
- 自己动手写ORM框架-java
- [LeetCode]258. Add Digits&202. Happy Number
- Leetcode: 372.Super Pow
- 【Java并发编程】之二十二:并发新特性—障碍器CyclicBarrier(含代码)
- 给程序员的健康小建议
- Elasticsearch(5)实践一-数据添加
- 3.自己动手写Java Web框架-MVC初体验
- 【Lua】LuaStudio写Hello World入门
- 第二章 java基础(操作符续一)
- 【Java并发编程】之二十三:并发新特性—信号量Semaphore(含代码)
- (Java)LeetCode-43. Multiply Strings
- 【Java并发编程】并发编程大合集
- Android中activity触摸操作dispatchTouchEvent
- The 36th ACM/ICPC Asia Regional Dalian Site 1006 Dave
- day14 Python Css对话框