在Servlet开发的工程实践中,为了减少过多的业务Servlet编写,会采用构建公共Servlet的方式,通过反射来搭建轻量级的MVC框架,从而加快应用开发。

关于Servlet开发的基础知识,请看:JavaWeb开发之详解Servlet及Servlet容器

前后端交互的基本形式

一般来说,前端提交数据请求有三种基本方式,分别是表单、链接和Ajax

1. 按钮

 <form action="/BaseServlet/ServletDemo02?method=addStu" method="post">
用户<input type="text" name="username"/><br/>
<button>提交</button>
</form>

2. 链接

<a href="/BaseServlet/ServletDemo02?method=delStu">删除学生</a><br/>

3. Ajax

 <button onclick="fn()">按钮</button>
<script>
function fn(){
$.post("/BaseServlet/ServletDemo02",{"method":"checkStu","user":"tom"},function(data){
alert(data);
});
}

在Servlet开发的语境中,它们的共同点都是:指定处理的Servlet类路径(在web.xml中指定)以及附带在请求中的“method”参数

通过调用request参数匹配业务处理逻辑

前端按照以上方法发起请求,Servlet容器就会把请求交给对应的Servlet处理,并且附带上形如 method=delStu 的参数,利用这个原理,就可以构建一个基础Servlet类,用来优化开发:

 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取客户端提交到服务端的method对应的值
String md=request.getParameter("method");
//定义变量,存放功能执行完毕之后要转发的路径
String path=null; //通过判断md中不同的内容来决定本次功能
if("addStu".equals(md)){
path=addStu(request, response);
}else if("delStu".equals(md)){
path=delStu(request, response);
}else if("checkStu".equals(md)){
path=checkStu(request, response);
}else if("".equals(md)){ }
if(null!=path){
//服务端的请求转发
request.getRequestDispatcher(path).forward(request, response);
}
} protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} protected String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("添加学生");
return "/test.html"; }
protected String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("删除学生");
return "/test.html"; }
protected String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("检查学生");
response.getWriter().println("DDDDDD");
return null;
}

以上的Servlet对请求进行了处理,通过获取index.html的请求,最后请求转发至目标页面,其核心思想是:

1. 提取request的method参数的值;

2. 定义变量,存储请求转发的路径;

3. 通过判断method参数中的值的内容,来决定调用哪个业务功能。

4. 完成业务功能后,使用请求转发处理

通过反射匹配业务处理逻辑

当业务量多的时候,以上实践仍是不够,此时比较好的方式就是采用反射。

 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
} public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//获取客户端提交到服务端的method对应的值
String md=request.getParameter("method");
//定义变量,存放功能执行完毕之后要转发的路径
String path=null;
//获取到当前字节码对象(ServletDemo02.class在内存中对象)
Class<? extends ServletDemo02> clazz = this.getClass();
try {
//获取clazz上名称为md, 参数为HttpServletRequest和HttpServletResponse的方法
Method method=clazz.getMethod(md, HttpServletRequest.class,HttpServletResponse.class);
if(null!=method){
//调用找到的方法
path=(String)method.invoke(this, request,response);
}
if(null!=path){
//服务端的转发
request.getRequestDispatcher(path).forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
} } public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("添加学生");
return "/test.html"; }
public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("删除学生");
return "/test.html"; }
public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("检查学生");
response.getWriter().println("DDDDDD");
return null;
}

1. 提取request的method参数的值;

2. 定义变量,存储请求转发的路径;

3. 获取到当前Servlet对象在内存中的Class对象

4. 获取Class对象上名称为md, 参数为HttpServletRequest和HttpServletResponse的方法

5. 根据是否返回方法对象,调用业务功能并使用请求转发处理

Java HttpServlet的父类GenericServlet,就是通过这个方法来调取HttpServlet的doGet或doPost方法的。

最佳实践

在实践开发中,一般会搭建一个BaseServlet,继承了HttpServlet并重写其Service方法,通过反射来找到业务功能子类对应的业务方法。

 public class BaseServlet extends HttpServlet {
private static final long serialVersionUID = 12197442526341123L; @Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("service.....");
//获取客户端提交到服务端的method对应的值
String md=request.getParameter("method");
//定义变量,存放功能执行完毕之后要转发的路径
String path=null;
//获取到当前字节码对象(ServletDemo02.class在内存中对象)
Class<? extends BaseServlet> clazz = this.getClass();
try {
//获取clazz上名称为md方法
Method method=clazz.getMethod(md, HttpServletRequest.class,HttpServletResponse.class);
if(null!=method){
//调用找到的方法
path=(String)method.invoke(this, request,response);
}
if(null!=path){
//服务端的转发
request.getRequestDispatcher(path).forward(request, response);
}
} catch (Exception e) {
e.printStackTrace();
}
} }

而业务功能子类,则继承BaseServlet,专注于业务逻辑的开发

 public class ServletDemo03 extends BaseServlet {

     private static final long serialVersionUID = 11248215356242123L;

     public ServletDemo03() {
System.out.println("没有参数的构造函数");
} public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("添加学生");
return "/test.html"; }
public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("删除学生");
return "/test.html"; }
public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("检查学生");
response.getWriter().println("DDDDDD");
return null;
} }

Java Servlet开发的轻量级MVC框架最佳实践的更多相关文章

  1. 开发自己PHP MVC框架(一)

    本教程翻译自John Squibb 的Build a PHP MVC Framework in an Hour,但有所改动,原文地址:http://johnsquibb.com/tutorials 这 ...

  2. 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并把请求分发到不同的控制器去处理,根据控制器处理后的结果,生成相应的响应发送到客户端。前端控制器既可以使用Filter实现(Struts2采用这种方式),也可以使用Servlet来实现(spring MVC框架)。

    本文转自http://www.cnblogs.com/davidwang456/p/4090058.html 感谢作者 前端控制器是整个MVC框架中最为核心的一块,它主要用来拦截符合要求的外部请求,并 ...

  3. .NET轻量级MVC框架:Nancy入门教程(二)——Nancy和MVC的简单对比

    在上一篇的.NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy中,简单介绍了Nancy,并写了一个Hello,world.看到大家的评论,都在问Nancy的优势在哪里?和微软的MVC比 ...

  4. 《深入理解Java虚拟机:JVM高级特性与最佳实践》【PDF】下载

    <深入理解Java虚拟机:JVM高级特性与最佳实践>[PDF]下载链接: https://u253469.pipipan.com/fs/253469-230062566 内容简介 作为一位 ...

  5. 读书笔记-《深入理解Java虚拟机:JVM高级特性与最佳实践》

    目录 概述 第一章: 走进Java 第二章: Java内存区域与内存溢出异常 第三章: 垃圾收集器与内存分配策略 第四章: 虚拟机性能监控与故障处理 第五章: 调优案例分析与实战 第六章: 类文件结构 ...

  6. openresty 前端开发轻量级MVC框架封装一(控制器篇)

    通过前面几章,我们已经掌握了一些基本的开发知识,但是代码结构比较简单,缺乏统一的标准,模块化,也缺乏统一的异常处理,这一章我们主要来学习如何封装一个轻量级的MVC框架,规范以及简化开发,并且提供类似p ...

  7. [Java] 使用 Spring 2 Portlet MVC 框架构建 Portlet 应用

    转自:http://www.ibm.com/developerworks/cn/java/j-lo-spring2-portal/ Spring 除了支持传统的基于 Servlet 的 Web 开发之 ...

  8. .NET轻量级MVC框架:Nancy入门教程(一)——初识Nancy

    当我们要接到一个新的项目的时候,我们第一时间想到的是用微软的MVC框架,但是你是否想过微软的MVC是不是有点笨重?我们这个项目用MVC是不是有点大材小用?有没有可以替代MVC的东西呢?看到这里也许你会 ...

  9. web开发中的MVC框架与django框架的MTV模式

    1.MVC 有一种程序设计模式叫MVC,核心思想:分层,解耦,分离了 数据处理 和 界面显示 的代码,使得一方代码修改了不会影响到另外一方,提高了程序的可扩展性和可维护性. MVC的全拼为Model- ...

随机推荐

  1. asdm不能登录问题;浏览器必须是ie,不能是chrome或者firefox;java的版本,尤其是安全等级和例外需要调整

    asdm不能登录问题:浏览器必须是ie,不能是chrome或者firefox;java的版本,尤其是安全等级和例外需要调整

  2. Git同时使用不同平台代码仓库

    问题描述 公司项目使用代码仓库为gitinn/gitlab等,个人项目使用github进行托管,而公司项目和个人项目设置的邮箱和用户名是不同的,而ssh的密钥对又是基于这两个信息生成的,所以此时想要同 ...

  3. Leetcode——64. 最小路径和

    题目描述:题目链接 同样对于这个问题,我们可以考虑用动态规划来解决. 解决动态规划常见的三个步骤: 1:问题的归纳.对于 i,j 位置上的最短路径可以用d[ i ][ j ]表示. 2:归纳递推式:d ...

  4. cloudstack secondary vm starting

    等1个小时,差不多可以进入虚拟机,看日志/var/log/cloud.log

  5. 提高SQL查询效率的30种方法

    转载:提高SQL查询效率的30种方法 内容摘录如下: 1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中 ...

  6. array_multisort函数,以及多维数组下排序的应用,并与usort函数对比

    以前比较少用这个函数,大部分自己接触的业务里,处理稍微大一些的数组的时候几乎都是从db里取出来的,在db里就order by了. 最近倒是用了次,这个函数用来排序很强大,有点类似于sql中的order ...

  7. Vivado中xilinx_courdic IP核(求exp指数函数)使用

    由于Verilog/Vhdl没有计算exp指数函数的库函数,所以在开发过程中可利用cordic IP核做exp函数即e^x值: 但前提要保证输入范围在(-pi/4—pi/4) 在cordic核中e^x ...

  8. 网络对抗技术 2017-2018-2 20152515 Exp2 后门原理与实践

    1.实验内容 (1)使用netcat获取主机操作Shell,cron启动 (0.5分) 关于netcat:是一个底层工具,进行基本的TCP UDP数据收发.常被与其他工具结合使用,起到后门的作用. 相 ...

  9. python装饰器 练习

    用类作为装饰器 练习一 最初代码 class bol(object): def __init__(self, func): self.func = func def __call__(self): r ...

  10. CS229笔记:分类与逻辑回归

    逻辑回归 对于一个二分类(binary classification)问题,\(y \in \left\{0, 1\right\}\),如果直接用线性回归去预测,结果显然是非常不准确的,所以我们采用一 ...