how2j.cn


工具版本兼容问题
MVC是一种分层的设计模式,本章节从Servlet和JSP的局限性谈起,慢慢引入MVC的概念。


步骤 1 : 仅仅使用Servlet的短处   
步骤 2 : 仅仅使用JSP的短处   
步骤 3 : 结合Servlet和JSP   
步骤 4 : MVC设计模式   

步骤 1 :

仅仅使用Servlet的短处

edit
在Servlet的章节中,使用了编辑Hero的Servlet
根据浏览器提交的id,通过HeroDAO找到对应的Hero,然后在Servlet中组织html显示出来。

可以看到这个Servlet不仅要准备数据,还要准备html。 尤其是准备html,可读性非常差,维护起来也很麻烦
package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; public class HeroEditServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id")); Hero hero = new HeroDAO().get(id); StringBuffer format = new StringBuffer(); response.setContentType("text/html; charset=UTF-8"); format.append("<!DOCTYPE html>"); format.append("<form action='updateHero' method='post'>"); format.append("名字 : <input type='text' name='name' value='%s' > <br>"); format.append("血量 : <input type='text' name='hp' value='%f' > <br>"); format.append("伤害: <input type='text' name='damage' value='%d' > <br>"); format.append("<input type='hidden' name='id' value='%d'>"); format.append("<input type='submit' value='更新'>"); format.append("</form>"); String html = String.format(format.toString(), hero.getName(), hero.getHp(), hero.getDamage(), hero.getId()); response.getWriter().write(html); } }
步骤 2 :

仅仅使用JSP的短处

edit
因为在Servlet中编写html有这样的短板,所以索性直接在JSP中开发编辑Hero这个功能

这时会发现,虽然编写html方便了,但是写java代码不如在Servlet中那么方便
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*,bean.*,java.sql.*"%> <% int id = Integer.parseInt(request.getParameter("id")); Hero hero = null; try { Class.forName("com.mysql.jdbc.Driver"); Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/how2java?characterEncoding=UTF-8", "root", "admin"); Statement s = c.createStatement(); String sql = "select * from hero where id = " + id; ResultSet rs = s.executeQuery(sql); if (rs.next()) { hero = new Hero(); String name = rs.getString(2); float hp = rs.getFloat("hp"); int damage = rs.getInt(4); hero.name = name; hero.hp = hp; hero.damage = damage; hero.id = id; } s.close(); c.close(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } %> <form action='updateHero' method='post'> 名字 : <input type='text' name='name' value='<%=hero.getName()%>'> <br> 血量 :<input type='text' name='hp' value='<%=hero.getHp()%>'> <br> 伤害: <input type='text' name='damage' value='<%=hero.getDamage()%>'> <br> <input type='hidden' name='id' value='<%=hero.getId()%>'> <input type='submit' value='更新'> </form>
步骤 3 :

结合Servlet和JSP

edit
既然Servlet和JSP都有各自的优势和短板,那么为什么不结合起来扬长避短呢?
HeroEditServlet:只用来从数据库中查询Hero对象,然后跳转到JSP页面

request.setAttribute("hero", hero);

在request中设置hero

request.getRequestDispatcher("editHero.jsp").forward(request, response);

服务端跳转到editHero.jsp,因为是服务端跳转,都属于同一次请求,所以可以在editHero.jsp通过request取出来

editHero.jsp: 不做查询数据库的事情,直接获取从HeroEditServlet传过来的Hero对象,通过EL表达式把request中的hero显示出来
package servlet; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import bean.Hero; import dao.HeroDAO; public class HeroEditServlet extends HttpServlet { protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { int id = Integer.parseInt(request.getParameter("id")); Hero hero = new HeroDAO().get(id); request.setAttribute("hero", hero); request.getRequestDispatcher("editHero.jsp").forward(request, response); } }
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" import="java.util.*,bean.*,java.sql.*"%> <form action='updateHero' method='post'> 名字 : <input type='text' name='name' value='${hero.name}'> <br> 血量 :<input type='text' name='hp' value='${hero.hp}'> <br> 伤害: <input type='text' name='damage' value='${hero.damage}'> <br> <input type='hidden' name='id' value='${hero.id}'> <input type='submit' value='更新'> </form>
上述例子中结合Serlvet和JSP进行数据的显示,就是一种MVC的思想。

M 代表 模型(Model
V 代表 视图(View
C 代表 控制器(controller)

模型是什么呢? 模型就是数据,就是dao,bean

视图是什么呢? 就是网页, JSP,用来展示模型中的数据

控制器是什么? 控制器用来把不同的数据,显示在不同的视图上。 在这个例子的,Servlet就是充当控制器的角色,把Hero对象,显示在JSP上。

控制器的作用就是把不同的数据(Model),显示在不同的视图(View)上。
MVC设计模式


HOW2J公众号,关注后实时获知最新的教程和优惠活动,谢谢。


问答区域    
2023-12-15 关于站长想要表达中缺少的部分。想要明白站长说的意思必须要看的地方。
Shu_Enryu

关于 J2EE-MVC-Hello MVC 的提问



如题 这节课需要看站长在之前的Servlet课里的CRUD里面的内容。 那里面有HeroListServlet, HeroEditServlet, HeroUpdateServlet。把这三个Servlet做完,并且配置好 web.xml文件。 然后站长写的HeroDAO里的get()方法里有个小错误,导致永远都取不出来hero的属性。把站长写的 Hero hero = null; 换成 Hero hero = new Hero(); 后把从DAO中取到的值一个一个赋值给这个Hero对象就好。代码贴上了 然后再把这节课里的,HeroEditServlet改成这节课的。再写一个editHero.jsp。就完事了。
//站长写的    
    public Hero get(int id) {
        Hero hero = null;
        try (Connection c = getConnection(); Statement s = c.createStatement();) {
            String sql = "select * from hero where id = " + id;
            ResultSet rs = s.executeQuery(sql);
            if (rs.next()) {
                hero = new Hero();
                String name = rs.getString(2);
                float hp = rs.getFloat("hp");
                int damage = rs.getInt(4);
                hero.name = name;
                hero.hp = hp;
                hero.damage = damage;
                hero.id = id;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return hero;
    }
//可以用的(即改良后的)
	public Hero get(int id) {
		Hero h = new Hero();
		String sql = "select id, name, hp, damage from hero where id=?";
		try(Connection c = getConnection(); PreparedStatement ps = c.prepareStatement(sql)) {
			ps.setInt(1, id);
			ResultSet rs = ps.executeQuery();
			if(rs.next()) {
				int aid = rs.getInt(1);
				String name = rs.getString(2);
				float hp = rs.getFloat(3);
				int damage = rs.getInt(4);
				
				h.setName(name);
				h.setHp(hp);
				h.setDamage(damage);
				h.setId(aid);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		}
		
		return h;
	}

							





回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到





2020-10-04 hello MVC这里editHero.jsp是不是单纯为了使用el表达式取值?
CJJJ

关于 J2EE-MVC-Hello MVC 的提问
使用HTML的话有没有办法获取hero的值呢?




3 个答案

VOID1
答案时间:2021-04-07
获得hero还是用jsp的request吧,servlet转发的request是同一个

492554146
答案时间:2020-10-25
@弦断花落丿 表示怀疑,请问html哪里来的request???

弦断花落丿
答案时间:2020-10-23
兄弟html不具备动态网页的能力,除非用JavaScript,你把数据转成JSON就行,之后用JavaScript遍历,好沙雕
var data = <%=JSON.toJSONString(request.getAttribute("名字"))%>;



回答已经提交成功,正在审核。 请于 我的回答 处查看回答记录,谢谢
答案 或者 代码至少填写一项, 如果是自己有问题,请重新提问,否则站长有可能看不到




2020-07-12 无法显示数据
2020-02-02 流程不懂
2019-07-01 楼主,最后一个例子是否有个提交ID的页面没放上来?edithero.jsp是用来显示结果的会盖掉提交ID页面呢?


提问太多,页面渲染太慢,为了加快渲染速度,本页最多只显示几条提问。还有 4 条以前的提问,请 点击查看

提问之前请登陆
提问已经提交成功,正在审核。 请于 我的提问 处查看提问记录,谢谢
关于 J2EE-MVC-Hello MVC 的提问

尽量提供截图代码异常信息,有助于分析和解决问题。 也可进本站QQ群交流: 578362961
提问尽量提供完整的代码,环境描述,越是有利于问题的重现,您的问题越能更快得到解答。
对教程中代码有疑问,请提供是哪个步骤,哪一行有疑问,这样便于快速定位问题,提高问题得到解答的速度
在已经存在的几千个提问里,有相当大的比例,是因为使用了和站长不同版本的开发环境导致的,比如 jdk, eclpise, idea, mysql,tomcat 等等软件的版本不一致。
请使用和站长一样的版本,可以节约自己大量的学习时间。 站长把教学中用的软件版本整理了,都统一放在了这里, 方便大家下载: https://how2j.cn/k/helloworld/helloworld-version/1718.html

上传截图