zoukankan      html  css  js  c++  java
  • Servlet开发(1)基础及MVC设计模式


    一、Servlet介绍


    Servlet本身只是普通的Java类,只有当容器为他创建了ServletConfig和ServletContext时才成为了一个Servlet;

    Servlet简单的说就是一个Java程序,目的和Javabean差不多,为了使得JSP页面中代码简洁、清晰;

    JavaBean不需要配置,只需要放在WEB-INF/classes中即可;

    Servlet也是放在 WEB-INF/classes/中,并在web.xml中配置如下形式:


    <servlet>
    <servlet-name></servlet-name>
    <servlet-class></servlet-class>
    </servlet>
    <servlet-mapping>
    <servlet-name></servlet-name>
    <url-pattern></url-pattern>
    </servlet-mapping>

    如果需要设置配置信息,则需要形式如下:

    <servlet>
    <servlet-name></servlet-name>
    <servlet-class></servlet-class>
    <init-param>
    <param-name></param-name>
    <param-value></param-value>
    </init-param>
    
    </servlet>
    <servlet-mapping>
    <servlet-name></servlet-name>
    <url-pattern></url-pattern>
    </servlet-mapping>


    注意:在url-pattern中,主目录为:"/",而不是"\"!

    Servlet可以处理客户端传来的请求,即request,并且可以返回给客户端回应,即response,这个操作通过

    (1)public void service(ServletRequest req,ServletResponse resp)throws ServletExeption,IOException{}

    (2)public void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletExeption,IOException{}

    (3)public void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletExeption,IOException{}

    完成;

    这里需要注意的是service的参数只是ServletRequest,而其他两个函数的参数是HttpServletRequest;

    一般如果我们要自定义Servlet,则需要继承HttpServlet类,并覆盖相应的方法即可;


    二、Servlet的结构

     
    注意:
    (1)一个Servlet类只有一个实例;
    (2)一个Servlet类只会调用一次init()方法;
    (3)Servlet的一生都是由Web容器所控制,即Web容器调用Servlet类的方法;
    (4)Servlet如果没有Web容器,就是一个普通的Java类;

    Servlet生命周期为:加载-->初始化--->服务--->销毁--->卸载;

    加载:web容器加载Servlet,即创建一个Servlet实例;

    初始化:调用servlet的init方法,为了完成一些预备动作;

    当请求到来时,

    服务:创建一个request、response对象,并创建一个线程,调用类service方法;

    销毁:调用destroy()方法;当一个Servlet对象长时间不使用或web容器(tomcat)关闭时调用;

    卸载:即退出;

    继承HttpServlet后,可以覆写以下方法:

    1.public void init(ServletConfig config)throws ServletException{}     //初始化Servlet,(1)当需要使用Servlet时调用;(2)如果在web.xml中配置,则可以web容器启动时自动加载;配置如下:

    <serlvet>
    	<serlvet-name></servlet-name>
    	<servlet-class></servlet-class>
    	<load-on-startup>1</load-on-startup>
    </servlet>
    

    2.public void init(ServletConfig config)throws ServletExeption{} //初始化Servlet,可以得到配置信息

    3.public void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletExeption,IOException{} 当get方式传递,则调用此方法

    4.public void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletExeption,IOException{}当post方法传递,则调用此方法

    5.public void service(HttpServletRequest req,HttpServletResponse resp)throws ServletExeption,IOException{}

    6.public void destroy(){}   //销毁时调用

    注意:

    1.   当1,2同时出现时,2有较高优先级;

    2.   当3或4和5同时出现时,5具有较高优先级;

    3   .PrintWriter writer = resp.getWriter();可以获得输出流;

    注意:writer输出时需要输出HTML结构;


    三、Servlet常见问题


    1.在init方法中,通过config.getInitParameter()方法取得配置信息;

    2.req.getSession():取得Session对象;

    3.super.getServletContext();取得application对象;因为GenericServlet中有getServletContext方法;

    4.resp.getWriter()返回一个PrintWriter用以输出文本数据、resp.getOutputStream()输出二进制数据,并且两者不能同时调用;

    5.在init(ServletConfig config)方法中需要调用super.init(config);

    6. 在service()方法中getServletConfig()返回 ServletConfig;



    四、Servlet跳转


    1.客户端跳转:resp.sendRedirect("1.jsp") ;    //类似于内置对象中的跳转;

    2.服务器跳转:req.getRequestDispatcher("/hello.jsp").forward(req,resp);能够跳转到hello.jsp中;     

    注意:客户端跳转和服务器端跳转的区别;

    注意:这里的getRequestDispatcher中的网页一定要加“  /    ”   


    五、MVC设计模式

    JAVA WEB中,有两种设计模式:
    (1)MODE 1: DAO;
    (2)MODE 2: MVC;

    在之前我们讲过JSP+JAVABEAN的DAO开发模式,这个适用于小型开发;

    MVC最早是由SmallTalk提出的;

    Controller: Servlet 负责接收客户请求并转发给Model;

    Model :JavaBean  负责真正处理业务逻辑;

    View:JSP 负责输出结果;


    EJB(Enterprise JavaBean);

    MVC(Model View Control)是一种以Servlet为核心的开发模式,流程如下:


     

    步骤如下:

    1.客户端发送请求给Servlet;

    2.Servlet接收请求后处理,并可以调用JavaBean(即进行数据库操作,并返回结果);

    3.Servlet返回结果给JSP显示;(通过设置request属性后调用RequestDispatcher方法跳转,并在JSP页面中接收request属性);

    因此JSP只是用于显示,而JavaBean只和Servlet通信;

    注意:在MVC中,使用requestDispatcher的机会很多,我们都是通过这个类进行服务器跳转的;


    六、MVC实例


    功能:登录功能

    1.JavaBean部分

    User.java

    package org.vo;
    public class User{
    	private String id;
    	private String name;
    	private String password;
    	public String getId(){
    		return id;
    	}
    	public void setId(String id){
    		this.id = id;
    	}
    	public String getName(){
    		return name;
    	}
    	public void setName(String name){
    		this.name = name;
    	}
    	public void setPassword(String password){
    		this.password = password;
    	}
    	public String getPassword(){
    		return password;
    	}
    }

    IUserDAO.java

    package org.dao;
    import org.vo.*;
    public interface IUserDAO{
    	public boolean findLogin(User user)throws Exception;
    }


    UserDAOImpl.java
    package org.dao.impl;
    import java.sql.*;
    import org.vo.*;
    import org.dao.*;
    public class UserDAOImpl implements IUserDAO{
    	private Connection con;
    	public UserDAOImpl(Connection con){
    		this.con = con;
    	}
    	public boolean findLogin(User user)throws Exception{
    		boolean flag = false;
    		String sql = "SELECT name FROM user WHERE id=? AND password=?";
    		PreparedStatement stat = con.prepareStatement(sql);
    		stat.setString(1,user.getId());
    		stat.setString(2,user.getPassword());
    		ResultSet rs = stat.executeQuery();
    		if(rs.next()){
    			user.setName(rs.getString(1));
    			flag = true;
    		}
    		return flag;
    	}
    }

    UserDAOProxy.java

    package org.dao.proxy;
    import org.dao.*;
    import org.vo.*;
    import org.dao.impl.*;
    import org.dbc.*;
    public class UserDAOProxy implements IUserDAO{
    	private DatabaseConnection dbc;
    	private IUserDAO idao;
    	public UserDAOProxy(){
    		dbc = new DatabaseConnection();
    		idao = new UserDAOImpl(dbc.getConnection());
    	}
    	public boolean findLogin(User user)throws Exception{
    		if(user==null){
    			return false;
    		}
    		boolean flag = idao.findLogin(user);
    		dbc.close();
    		return flag;
    	}
    }

    DatabaseConnection.java

    package org.dbc;
    import java.sql.*;
    public class DatabaseConnection{
    	public static final String DRIVER = "com.mysql.jdbc.Driver";
    	public static final String URL = "jdbc:mysql://localhost:3306/mldn";
    	public static final String USER = "root";
    	public static final String PASS = "123456";
    	private Connection con;
    	public DatabaseConnection(){
    		try{
    			Class.forName(DRIVER);
    			con = DriverManager.getConnection(URL,USER,PASS);
    		}
    		catch(Exception e){}
    	}
    	public Connection getConnection(){
    		return con;
    	}
    	public void close(){
    		try{
    			if(con!=null){
    				con.close();
    			}
    		}
    		catch(Exception e){}
    	}
    }

    DAOFactory.java

    package org.factory;
    import org.dao.*;
    import org.dao.proxy.*;
    public class DAOFactory{
    	public static IUserDAO getInstance(){
    		return new UserDAOProxy();
    	}
    }

    以上代码是JavaBean部分;MVC的特点是用Servlet调用JavaBean,而不是JSP调用JavaBean;


    2.Servlet部分


    以下是Servlet部分:Servlet是接收客户端请求,并调用JavaBean进行数据库操作;并把结果通过设置request属性传给JSP进行显示;(贯穿核心)

    LoginServlet.java

    package org.servlet;
    import java.util.*;
    import javax.servlet.*;
    import javax.servlet.http.*;
    import org.factory.*;
    import org.vo.*;
    import java.io.*;
    public class LoginServlet extends HttpServlet{
    	public void doGet(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
    		String path = "login.jsp";
    		String id = req.getParameter("id");
    		String pass = req.getParameter("pass");
    		List<String> info = new ArrayList<String>();
    		if(id==null||"".equals(id)){
    			info.add("id不能为空");
    		}
    		if(pass==null||"".equals(pass)){
    			info.add("密码不能为空");
    		}
    		if(info.size()==0){
    			User user = new User();
    			user.setId(id);
    			user.setPassword(pass);
    			try{
    				if(DAOFactory.getInstance().findLogin(user)==true){
    					info.add("欢迎光临");
    				}
    				else{
    					info.add("错误的用户名和密码");
    				}
    			}
    			catch(Exception e){}
    		}
    		req.setAttribute("info",info);
    		req.getRequestDispatcher(path).forward(req,resp);
    	}
    	public void doPost(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{
    		this.doGet(req,resp);
    	}
    }

    Login.jsp

    <%@page contentType="text/html" pageEncoding="GBK" import="java.util.*"%>
    <html>
    	<head>
    		<title>A</title>
    	</head>
    	<script language="Javascript">
    		function validate(f){
    			if(!(/^\w{5,15}$/.test(f.id.value))){
    				alert("id长度不对");
    				f.id.focus();
    				return false;
    			}
    			if(!(/^\w{5,15}$/.test(f.pass.value))){
    				alert("密码长度不对");
    				f.pass.focus();
    				return false;
    			}
    			return true;
    		}
    	</script>
    	<body>
    		<h2>用户登录程序</h2>
    		<%
    			request.setCharacterEncoding("GBK");
    			List<String> info = (List<String>)request.getAttribute("info");
    			if(info!=null){
    				Iterator<String>iter = info.iterator();
    				while(iter.hasNext()){
    		%>
    					<h4><%=iter.next()%></h4>
    		<%
    				}
    			}
    		%>
    		<form action="LoginServlet" method="post" onSubmit="return validate(this)">
    		用户ID:<input type="text" name="id"/><br />
    		密码:<input type="password" name="pass"/><br />
    		<input type="submit" value="提交"/>
    		</form>
    	</body>
    </html>

    数据库脚本:

    CREATE TABLE user(
    	id		varchar(30)	PRIMARY KEY,
    	name		varchar(30)	,
    	password	varchar(30)
    );
    INSERT INTO user VALUES('XIAZDONG','xiazdong','12345');


    因此最后再强调一下Mode1和Mode2的区别:

    Mode1是通过JSP调用JavaBean;Mode2是通过Servlet调用JavaBean;

    Mode1在JSP中仍然有处理的部分,而Mode2中JSP只负责显示;


    补充:Servlet调用过程顺序图 




     

    ServletContext介绍

    ServletContext对象在web服务器启动时创建,即在服务器启动时,为每个web应用创建一个ServletContext;

    1.获得途径: this.getServletContext() 可以取得 ServletContext 对象;
    2.获得web应用的初始化参数: context.getInitParameter("...");
    在web.xml中通过类似:
    <context-param>
      	<param-name></param-name>
      	<param-value></param-value>
      </context-param>
    配置;
    3.转发
    context.getRequestDispatcher("/1.html").forward(request,response);

    4.获取资源文件数据: 
    InputStream in = context.getResourceAsStream("*.properties");
    Properties props = new Properties();
    props.load(in);


     

    补充:web开发中地址书写问题

     

    地址书写时常用到“/”开头,而“/”有两个宗旨:

    1.面向浏览器,则"/"表示http://localhost:8080/

    2.面向服务器,则"/"表示当前web应用;

    面向浏览器的意思是:是否会让浏览器地址栏改变;其余的都是面向服务器;

    在Servlet开发中会在以下几种情况下存在地址书写问题:
    1. request.getRequestDispatcher("地址A");
    2.response.sendRedirect("地址B");
    3.this.getServletContext().getRealPath("地址C");
    4.this.getServletContext().getResourceAsStream("地址D");
    5.<a href="地址E">
    6.<form action="地址F">
     
    地址A:转发不会使浏览器地址栏改变,因此是面向服务器的,“/”表示当前web应用;
    地址B:重定向会使浏览器地址栏改变,因此是面向浏览器的;
    同样分析,得出结果:
    A、C、D属于面向服务器;
    B、E、F属于面向浏览器;

     

    补充:在提供客户发出请求之前的过程

    1.从web.xml中读出Servlet初始化参数和上下文初始化参数;

    2.创建一个ServletConfig对象和ServletContext对象;

    3.将Servlet初始化参数的引用赋给ServletConfig对象,把上下文初始化参数赋值给ServletContext对象;

    4.创建ServletContextListener监听器实例;

    5.调用contextInitialized()方法;

    6.创建这个Servlet实例;

    7.调用init方法;

    注意:

    (1)在Servlet构造函数中还没有ServletConfig对象,虽然能够调用getServletConfig()方法;

    (2)ServletConfig对象在Servlet实例创建之前就已经创建;

    (3)web.xml的初始化参数只会读一次,如果需要更新,则需要重新部署;

    上下文初始化参数:整个web应用都能够访问的初始化参数;

    <context-param>

        <param-name>name</param-name>

        <param-value>value</param-value>

    </context-param>

    getServletContext().getInitParameter("name")即可;

    每个Servlet有一个ServletConfig,每个web应用有一个ServletContext;

    如果web应用时分布式的,则每个JVM都有一个ServletContext;

    注意:getAttribute()返回的是Object;

    Person  p = getServletContext().getAttribute("person");是错误的!!!!!!!!!!!!!!!!!!!!!

    Person  p = (Person)getServletContext().getAttribute("person");是正确的;






    作者:xiazdong
    出处:http://blog.xiazdong.info
    本文版权归作者所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。
  • 相关阅读:
    KMP算法
    Java中的字段和属性
    Java的垃圾回收机制
    一个初学所了解的jquery事件
    jQuery选择器
    hide(1000)跟show(1000)
    show/hide
    点击消失功能
    Java中集合Set的用法
    oracle的nvl和sql server的isnull
  • 原文地址:https://www.cnblogs.com/xiazdong/p/3058140.html
Copyright © 2011-2022 走看看