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+"/";
%>
<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">
head>
<body>
<center><h1>500h1>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("\r\n");
out.write("\r\n");
out.write(" \r\n");
out.write(" );
out.print(basePath);
out.write("\">\r\n");
out.write(" \r\n");
out.write(" 服务器错误 \r\n");
out.write(" \r\n");
out.write("\t\r\n");
out.write("\t\r\n");
out.write("\t \r\n");
out.write("\t\r\n");
out.write("\t\r\n");
out.write("\t\r\n");
out.write("\r\n");
out.write(" \r\n");
out.write(" \r\n");
out.write(" \r\n");
out.write(" 500
\r\n");
out.write(" 服务端解析异常
\r\n");
out.write(" \r\n");
out.write("\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后跟的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="";
line+="" ;
line+="" +"1111"+"";
line+="" +"2222"+"";
line+="";
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>ReturnUsersservlet-name>
<servlet-class>servlet.ReturnUsersservlet-class>
servlet>
<servlet-mapping>
<servlet-name>ReturnUsersservlet-name>
<url-pattern>/servlet/ReturnUsersurl-pattern>
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>500error-code>
<location>/error500.jsplocation>
error-page>
<error-page>
<error-code>404error-code>
<location>/error404.jsplocation>
error-page>
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中携带信息的变量名字。