Web开发&创建项目连接数据库

web学习过程中,操作数据库是经常性的,一般只开发小型的项目,用mysql就可以完成功能,如果开发大型项目,一般借助oracle。这里示例myeclipse来连接mysql。首先确保电脑安装了mysql数据库。我用的是mysql5.6版本。
mysql连接web项目使用的jar包
1,新建名为mobile的web项目,下载mysql连接java的jar包,将jar包直接放在web项目lib目录下,或者builder path引入。
这里写图片描述
若没有特别需求,尽量使用稳定的jdk和tomcat版本,避免不必要的麻烦。
2,为使用方便,新建单独的类文件连接数据库,操作数据库使只要使用相应方法就可以了。
这里写图片描述
在src目录下新建一个util包,该包里面放置web开发需要使用的工具类,这里我新建了三个类,Jdbc类操作数据库,Log类用于控制台输出日志或者将日志输出到文件,User类是数据库表中属性对应的类。简单而言,Jdbc类相当于DAO,User相当于VO。
连接数据库代码:

Class.forName("com.mysql.jdbc.Driver");//利用反射实例化驱动类。
Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/mobile", "root","0000");//与本地数据库建立连接,第一个参数是url,表示连接到mysql的名为mobile的database,第二个参数为用户名,默认的情况下为“root”,第三个参数为进入数据库的密码。
Statement stat=conn.createStatement();//新建操作数据库语句的对象,该对象用来完成数据库的增删改查工作。

为了操作数据的安全性,一般都会将一系列的数据操作整体以事务形式提交,这样即便执行过程中有异常,也可以保证数据的同步性。

conn.setAutoCommit(false);//设置事务不自动提交
//******操作数据库
conn.commit();//提交事务
conn.close();//关闭conn
stat.close();// 关闭stat

3,项目jsp与servlet
在src目录下新建的类文件,在项目发布到服务器上时,会在项目web-inf目录下的class文件夹下,生成相应的包和.class文件,但路径仍然可以用/mobile/包名/类名 访问到。
web-inf目录下的class文件具有私有性,客户端通常不可直接访问,一般收费项目等文件可以放在该目录,在myeclipse中,class文件夹默认隐藏。

这里写图片描述
这是新建的src目录下servlet包下的java文件,tomcat会自动生成.class文件并置于class文件夹下。

这里写图片描述
这里写图片描述
jsp文件在经过tomcat处理,也会生成servlet类,生成对应的java文件以及.class文件;jsp文件本身位于项目的目录之下,生成的文件位于tomcat目录的work目录下。可以从图片地址中地址栏找到对应的文件位置。

对于一个简单的jsp文件,可以看一下生成的java类具体代码,以error500.jsp为例
这是error500.jsp代码,是一个标准的jsp文件。

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <base href="<%=basePath%>">
    <title>服务器错误</title> 
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">
    <!--
    <link rel="stylesheet" type="text/css" href="styles.css">
    -->
  </head>
  <body>
    <center><h1>500</h1></center><br>
    <center><h1><b>服务端解析异常</b></h1></center>
  </body>
</html>

查看error500.jsp生成的java文件——error500_jsp.java

package org.apache.jsp;

import javax.servlet.*;
import javax.servlet.http.*;
import javax.servlet.jsp.*;
import java.util.*;

public final class error500_jsp extends org.apache.jasper.runtime.HttpJspBase
    implements org.apache.jasper.runtime.JspSourceDependent {

  private static final JspFactory _jspxFactory = JspFactory.getDefaultFactory();

  private static java.util.List _jspx_dependants;

  private javax.el.ExpressionFactory _el_expressionfactory;
  private org.apache.AnnotationProcessor _jsp_annotationprocessor;

  public Object getDependants() {
    return _jspx_dependants;
  }

  public void _jspInit() {
    _el_expressionfactory = _jspxFactory.getJspApplicationContext(getServletConfig().getServletContext()).getExpressionFactory();
    _jsp_annotationprocessor = (org.apache.AnnotationProcessor) getServletConfig().getServletContext().getAttribute(org.apache.AnnotationProcessor.class.getName());
  }

  public void _jspDestroy() {
  }

  public void _jspService(HttpServletRequest request, HttpServletResponse response)
        throws java.io.IOException, ServletException {

    PageContext pageContext = null;
    HttpSession session = null;
    ServletContext application = null;
    ServletConfig config = null;
    JspWriter out = null;
    Object page = this;
    JspWriter _jspx_out = null;
    PageContext _jspx_page_context = null;


    try {
      response.setContentType("text/html;charset=UTF-8");
      pageContext = _jspxFactory.getPageContext(this, request, response,
                null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write('\r');
      out.write('\n');

String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";

      out.write("\r\n");
      out.write("\r\n");
      out.write("<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\">\r\n");
      out.write("<html>\r\n");
      out.write("  <head>\r\n");
      out.write("    <base href=\"");
      out.print(basePath);
      out.write("\">\r\n");
      out.write("    \r\n");
      out.write("    <title>服务器错误</title>\r\n");
      out.write("    \r\n");
      out.write("\t<meta http-equiv=\"pragma\" content=\"no-cache\">\r\n");
      out.write("\t<meta http-equiv=\"cache-control\" content=\"no-cache\">\r\n");
      out.write("\t<meta http-equiv=\"expires\" content=\"0\">    \r\n");
      out.write("\t<meta http-equiv=\"keywords\" content=\"keyword1,keyword2,keyword3\">\r\n");
      out.write("\t<meta http-equiv=\"description\" content=\"This is my page\">\r\n");
      out.write("\t<!--\r\n");
      out.write("\t<link rel=\"stylesheet\" type=\"text/css\" href=\"styles.css\">\r\n");
      out.write("\t-->\r\n");
      out.write("\r\n");
      out.write("  </head>\r\n");
      out.write("  \r\n");
      out.write("  <body>\r\n");
      out.write("    <center><h1>500</h1></center><br>\r\n");
      out.write("    <center><h1><b>服务端解析异常</b></h1></center>\r\n");
      out.write("  </body>\r\n");
      out.write("</html>\r\n");
    } catch (Throwable t) {
      if (!(t instanceof SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
        else log(t.getMessage(), t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
  }
}

代码明显要长的多,可以来分析一下,jsp生成的java源码到底什么意思:
开始第一行,表示将该java类打包到org.apache.jsp包下,我们可以只当作是一个路径映射。
然后可以看到该类继承自org.apache.jasper.runtime.HttpJspBase,这是一个apache自定义的类,而一般的servlet继承自HttpServlet类,该类全路径为javax.servlet.http.HttpServlet。很明显自定义的servlet可以不借助tomcat就能完成一般的功能。
隔过中间部分看_jspService(HttpServletRequest request, HttpServletResponse response)方法,该方法内部定义了八个变量,其中两个重复,在加上requset以及response两个参数,以及没有使用的exception,正好是jsp内置的九个对象,这九个对象可以直接使用,不需要实例化(tomcat会自动添加这些代码)。
jsp内置的九大对象及其对应的类分别为:

javax.servlet.Jsp.JspWriter out;
/*out对象是我们最多的一个,虽然jsp中看不到,但客户端呈现的html的内容,都是该对象‘写’到浏览器的。该对象主要是把信息填充到输出流,在浏览器访问的时候把内容传给浏览器,而浏览器自身负责将获取的信息显示出来。 */
javax.servlet.http.HttpServletRequest request;
/*request对象是浏览器访问某个url时,以参数的形式传入的对象,通过该对象可以读取到客户端浏览器所在主机的网址,进行访问的端口,浏览器的类型,版本,协议等等,也可以通过request.getRequestDispatcher("/mobile/index.jsp").forward(request, response)方式进行页面跳转,此种方式跳转后的两个页面,有相同的request,若request对象本身携带大量的数据,可以使用此种方法。此种方法相当于使用标签<jsp:forward page=""></jsp:forward>,这种方式跳转时,只能访问自身项目下的文件,不能跨域或者其他应用程序,jsp:forward后跟的url,根目录相当于/mobile,即如果需要转到/mobile/jsp/index.jsp,则应写为page="/jsp/index.jsp",而不是page="/mobile/jsp/index.jsp";。另外web开发中如果不明白的话,地址尽量用绝对寻址方式,以/开头,避免出错*/
javax.servlet.http.HttpServletResponse response;
/*response对象与request对象有些相反,request是客户端发起的请求,response是服务器对客户端的相应;response.sendRedirect(String url),利用response可以操作浏览器进行重定向,即要求客户端对一个新的url发起请求,此url是可以跨域的,可以利用response来设置out对象向浏览器输出信息时的编码,可以通过response.setHeader("Refresh","1")设定客户端每秒进行刷新,可以设置网页的一系列基本属性。*/
javax.servlet.http.HttpSession session;
/*session对象使用的很多,一般购物车等功能都需要session来实现。session就没有携带的信息,sesson的使用与application等大致相同,都是借助setAttribute与getAttribute方法*/
javax.servlet.ServletContext application;
/*application相当于服务端的sessoin,只有当服务器关闭时,application对象才会被销毁,可以存储全局的变量,例如统计一个网站的访问量等等*/
java.lang.Throwable exception;
/*exception对象不经常看到,主要是用来用户输入的或者不可预见的错误,只有当页面的isErrorPage属性为true时,该对象才可以被使用,否则报错。另外说明,我们常见的Exception对象是直接继承Throwalbe的*/
javax.servlet.Jsp.PageContext pageContext;
/*pageContext对象可以直接访问其余的几个对象,一般而言,java程序中都会有一个context对象,此对象可以管理所有的资源,例如安卓开发中的application中的context对象,另外借助pageContext对象便可以完成page,request,session,application的数据存储读取的功能*/
javax.servlet.ServletConfig config;
/*config对象是在jsp程序初始化时传递消息使用的,主要是jsp引擎用来向jsp程序传递参数以及服务器的有关信息,不经常见到*/
java.lang.Object page;
/*该对象是只jsp页面本身,即this,利用page对象可以导入包,可以设置编码,设置路径,设置语言等等,就是jsp页面开始的<%@ page *** %>部分,一般每一个jsp页面都会用到*/

session和cookie的区别及实现原理
往下便可以看出,系统是将jsp中<%%>之外的所有代码都以out.write()的方式“写”到了java类中,这也是为什么jsp中java程序可以跨越多个段落的原因。很清楚的发现,客户端浏览器页面源码便是out.write的部分。

现自己编写一个servlet,名字为ReturnUsers,在servlet包下;来处理某些功能

package servlet;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.ws.RespectBindingFeature;

public class ReturnUsers extends HttpServlet {
//servlet都需要在web.xml中注册,否则会有405异常,405异常是指服务器不允许静态文件接受post访问请求。
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        String line;
        line="<?xml version='1.0' encoding='UTF-8'?>";
        line+="<user>";
        line+="<account>"+"1111"+"</account>";
        line+="<password>"+"2222"+"</password>";
        line+="</user>";
        PrintWriter out=resp.getWriter();
        out.print(line);
        //自己拼接xml文件,将字符串传输到客户端。
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp)
            throws ServletException, IOException {
        // TODO Auto-generated method stub
        super.doPost(req, resp);
        doGet(req, resp);
    }

}

一般而言,只要重写doGet以及doPost方法就可以了,访问该servlet时,会将response与request当作参数传入,在servlet中可以采取如下方式获取之前jsp中的内置对象:

PrintWriter out=response.getWriter();//获取out对象,这里的out对象与jsp中out对象虽然功能一样,但却是不同的两个类。
HttpSession session=request.getSession();//获取session对象
ServletContext application=this.getServletContext()//获取application对象,this是指该servlet自身,this即是page对象。
PageContext pageContext=JspFactory.getDefaultFactory().getPageContext(this,request,response,null,false,JspWriter,DEFAULT_BUFFER,true);//获取pageContext对象,可以看到pageContext包含了很多内容
ServletConfig config=this.getServletConfig();

这个servlet中,自动拼接了一个xml格式字符串,利用out输出到浏览器,浏览器获得的源码为

这里写图片描述
可以看到与line字符串相同。
在servlet编写之后编译器会自动的在web.xml中进行注册,该servlet注册代码为:

  <servlet>
    <servlet-name>ReturnUsers</servlet-name>
    <servlet-class>servlet.ReturnUsers</servlet-class>
    <!--该servlet类的全名-->
  </servlet>
  <servlet-mapping>
    <servlet-name>ReturnUsers</servlet-name>
    <!--这里servlet-name和上一个配置的servlet-name必须相同-->
    <url-pattern>/servlet/ReturnUsers</url-pattern>
    <!--该servlet类所处的路径,这路径是相当与web-inf/classes文件夹而言的-->
  </servlet-mapping>

如果需要访问该servlet类,可以使用地址/mobile/servlet/ReturnUsers,很显然如果此时mobile项目如果根目录下同样有一个servlet文件夹,里面放置了一个ReturnUsers文件,那么两个文件会发生冲突,此时系统会默认读取名为ReturnUsers的servlet类,如果该类不存在,才会去读取项目mobile根目录的文件夹servlet下的文件ReturnUsers。
servlet后也可以手工的添加参数信息,在servlet内部可以通过request.getParameter()方法获取,如访问url:/mobile/servlet/ReturnUsers?name=”1111”

另外,web.xml文件可以配置出错页面,加入碰到已经定义的异常代码,会跳转到对应的页面:

  <error-page>
    <error-code>500</error-code>
    <location>/error500.jsp</location>
  </error-page>
  <error-page>
    <error-code>404</error-code>
    <location>/error404.jsp</location>
  </error-page>
  <!-- 当发生404和500错误时,跳转到对应的页面 -->

4,mysql文件存储编码,设置存储中文。
mysql默认是不可以存储中文的,打开mysql控制台,输入show variables like ‘character_set_%’;
可以看到如下页面:
这里写图片描述
其中有一行:character_set_database 的值为latinl,说明数据库编码方式不是utf-8,可以进行修改,输入:set character_set_database=utf8;
然后在输入show variables like ‘character_set_%’可以看到
这里写图片描述
之后就可以存储中文了。
然而大多时候这种修改方式只对当前会话有用,因此想要解决该问题,需要修改底层的配置文件。详细步骤参考文档:
mysql编码支持中文
因数据库版本不同,且网上大多数只是重复的抄袭甚至有些根本无用,我把使用的方法记录下来:
第一:web连接mysql后,当执行新建数据库或表格时设定编码:

create database mobile default charset=utf8;
create table user default charset=utf8;

第二,在jdbc连接数据库时在url中添加编码方式:

DriverManager.getConnection("jdbc:mysql://localhost:3306/mobile?unicode=true&characterEncoding=utf8","XXXX","XXXX");

是utf8而不是utf-8,中间是&号。

如果有时想把传递的汉字放在url里跳转到另外jsp页面或交给servlet处理,则需要在jsp或者servlet中添加如下代码:

String information=new String(request.getParameter("information").getBytes("iso8859-1"),"utf-8");

因为url默认是iso编码,因此需要先以iso编码方式转换成字符流,再以utf-8编码转换为字符串。information是url中携带信息的变量名字。

猜你喜欢

转载自blog.csdn.net/lovingning/article/details/50345351