Java Servlet开发的轻量级MVC框架最佳实践

java

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

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

前后端交互的基本形式

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

1. 按钮

1 <form action="/BaseServlet/ServletDemo02?method=addStu" method="post">

2 用户<input type="text" name="username"/><br/>

3 <button>提交</button>

4 </form>

2. 链接

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

3. Ajax

1 <button onclick="fn()">按钮</button>

2 <script>

3 function fn(){

4 $.post("/BaseServlet/ServletDemo02",{"method":"checkStu","user":"tom"},function(data){

5 alert(data);

6 });

7 }

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

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

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

 1 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

2 //获取客户端提交到服务端的method对应的值

3 String md=request.getParameter("method");

4 //定义变量,存放功能执行完毕之后要转发的路径

5 String path=null;

6

7 //通过判断md中不同的内容来决定本次功能

8 if("addStu".equals(md)){

9 path=addStu(request, response);

10 }else if("delStu".equals(md)){

11 path=delStu(request, response);

12 }else if("checkStu".equals(md)){

13 path=checkStu(request, response);

14 }else if("".equals(md)){

15

16 }

17 if(null!=path){

18 //服务端的请求转发

19 request.getRequestDispatcher(path).forward(request, response);

20 }

21 }

22

23

24 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

25 doGet(request, response);

26 }

27

28 protected String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

29 System.out.println("添加学生");

30 return "/test.html";

31

32 }

33 protected String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

34 System.out.println("删除学生");

35 return "/test.html";

36

37 }

38 protected String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

39 System.out.println("检查学生");

40 response.getWriter().println("DDDDDD");

41 return null;

42 }

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

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

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

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

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

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

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

 1 public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

2 doGet(request, response);

3 }

4

5 public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

6 //获取客户端提交到服务端的method对应的值

7 String md=request.getParameter("method");

8 //定义变量,存放功能执行完毕之后要转发的路径

9 String path=null;

10 //获取到当前字节码对象(ServletDemo02.class在内存中对象)

11 Class<? extends ServletDemo02> clazz = this.getClass();

12 try {

13 //获取clazz上名称为md, 参数为HttpServletRequest和HttpServletResponse的方法

14 Method method=clazz.getMethod(md, HttpServletRequest.class,HttpServletResponse.class);

15 if(null!=method){

16 //调用找到的方法

17 path=(String)method.invoke(this, request,response);

18 }

19 if(null!=path){

20 //服务端的转发

21 request.getRequestDispatcher(path).forward(request, response);

22 }

23 } catch (Exception e) {

24 e.printStackTrace();

25 }

26

27 }

28

29 public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

30 System.out.println("添加学生");

31 return "/test.html";

32

33 }

34 public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

35 System.out.println("删除学生");

36 return "/test.html";

37

38 }

39 public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

40 System.out.println("检查学生");

41 response.getWriter().println("DDDDDD");

42 return null;

43 }

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

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

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

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

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

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

最佳实践

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

 1 public class BaseServlet extends HttpServlet {

2 private static final long serialVersionUID = 12197442526341123L;

3

4 @Override

5 protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

6 System.out.println("service.....");

7 //获取客户端提交到服务端的method对应的值

8 String md=request.getParameter("method");

9 //定义变量,存放功能执行完毕之后要转发的路径

10 String path=null;

11 //获取到当前字节码对象(ServletDemo02.class在内存中对象)

12 Class<? extends BaseServlet> clazz = this.getClass();

13 try {

14 //获取clazz上名称为md方法

15 Method method=clazz.getMethod(md, HttpServletRequest.class,HttpServletResponse.class);

16 if(null!=method){

17 //调用找到的方法

18 path=(String)method.invoke(this, request,response);

19 }

20 if(null!=path){

21 //服务端的转发

22 request.getRequestDispatcher(path).forward(request, response);

23 }

24 } catch (Exception e) {

25 e.printStackTrace();

26 }

27 }

28

29 }

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

 1 public class ServletDemo03 extends BaseServlet {

2

3 private static final long serialVersionUID = 11248215356242123L;

4

5 public ServletDemo03() {

6 System.out.println("没有参数的构造函数");

7 }

8

9 public String addStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

10 System.out.println("添加学生");

11 return "/test.html";

12

13 }

14 public String delStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

15 System.out.println("删除学生");

16 return "/test.html";

17

18 }

19 public String checkStu(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

20 System.out.println("检查学生");

21 response.getWriter().println("DDDDDD");

22 return null;

23 }

24

25 }

以上是 Java Servlet开发的轻量级MVC框架最佳实践 的全部内容, 来源链接: utcz.com/z/391331.html

回到顶部