Java Web

笔记来源

Maven配置

官网

配置环境变量

%MAVEN_HOME%\bin MAVEN_HOME为maven的目录

镜像

maven目录下的conf/settings.xml 大约147行


    nexus-aliyun  
    *,!jeecg,!jeecg-snapshots  
    Nexus aliyun  
    http://maven.aliyun.com/nexus/content/groups/public 

本地仓库

maven目录下的conf/settings.xm 大约55行

maven目录\maven-repo

配置文件,无法被导出或者生效的问题


<build>
    <resources>
        <resource>
            <directory>src/main/resourcesdirectory>
            <includes>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>truefiltering>
        resource>
        <resource>
            <directory>src/main/javadirectory>
            <includes>
                <include>**/*.propertiesinclude>
                <include>**/*.xmlinclude>
            includes>
            <filtering>truefiltering>
        resource>
    resources>
build>

将web.xml版本配置成和tomcat一致


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">



web-app>

Maven仓库的使用

地址

Servelet

Hello Servelet

public class HelloServlet extends HttpServlet {  
    //由于get或者post只是请求实现的不同的方式,可以相互调用,业务逻辑都一样;
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //ServletOutputStream outputStream = resp.getOutputStream();
        PrintWriter writer = resp.getWriter(); //响应流
        writer.print("Hello,Serlvet");
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}
    
    <servlet>
        <servlet-name>helloservlet-name>
        <servlet-class>com.kuang.servlet.HelloServletservlet-class>
    servlet>
    
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>/hellourl-pattern>
    servlet-mapping>

Mapping问题

  1. 一个Servlet可以指定一个映射路径
  2. 一个Servlet可以指定多个映射路径
  3. 一个Servlet可以指定通用映射路径
<servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>/hello/*url-pattern>
servlet-mapping>
  1. 设置Servelet为默认请求路径

<servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>/*url-pattern>
servlet-mapping>
  1. 指定一些后缀或者前缀等等….

    
    <servlet-mapping>
        <servlet-name>helloservlet-name>
        <url-pattern>*.qinjiangurl-pattern>
    servlet-mapping>
    
  2. 优先级问题
    指定了固有的映射路径优先级最高,如果找不到就会走默认的处理请求;

ServletContext

web容器在启动的时候,它会为每个web程序都创建一个对应的ServletContext对象,它代表了当前的web应用;

共享数据

我在这个Servlet中保存的数据,可以在另外一个servlet中拿到;

public class HelloServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //this.getInitParameter()   初始化参数
        //this.getServletConfig()   Servlet配置
        //this.getServletContext()  Servlet上下文
        ServletContext context = this.getServletContext();

        String username = "zz"; //数据
        context.setAttribute("username",username); //将一个数据保存在了ServletContext中
    }
}
public class GetServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        ServletContext context = this.getServletContext();
        String username = (String) context.getAttribute("username");

        resp.setContentType("text/html");  //设置响应的页面类型
        resp.setCharacterEncoding("utf-8");
        resp.getWriter().print("名字"+username);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

<servlet>
    <servlet-name>helloservlet-name>
    <servlet-class>com.zz.servlet.HelloServletservlet-class>
servlet>
<servlet-mapping>
    <servlet-name>helloservlet-name>
    <url-pattern>/hellourl-pattern>  
servlet-mapping>

<servlet>
    <servlet-name>getcservlet-name>
    <servlet-class>com.zz.servlet.GetServletservlet-class>
servlet>
<servlet-mapping>
    <servlet-name>getcservlet-name>
    <url-pattern>/getcurl-pattern>
servlet-mapping>

获取初始化参数


<context-param>
    <param-name>urlparam-name>
    <param-value>jdbc:mysql://localhost:3306/mybatisparam-value>
context-param>
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    String url = context.getInitParameter("url");
    resp.getWriter().print(url);
}

请求转发

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    ServletContext context = this.getServletContext();
    //RequestDispatcher requestDispatcher = context.getRequestDispatcher("/gp"); //转发的请求路径
    //requestDispatcher.forward(req,resp); //调用forward实现请求转发;
    context.getRequestDispatcher("/gp").forward(req,resp);   //相当于商人
}
<%--前端方式--%>
<% pageContext.forward("xx.jsp") %>
对比HttpServletResponse实现重定向(指路人)
```java
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    /*
        resp.setHeader("Location","/r/img");
        resp.setStatus(302);
         */
    resp.sendRedirect("/r/img");//重定向
}

读取资源文件

public class ServletDemo05 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse response) throws ServletException, IOException {

        InputStream resourceAsStream = this.getServletContext().getResourceAsStream("/WEB-INF/classes/db.properties");
        Properties properties = new Properties();
        properties.load(resourceAsStream);
        String name = properties.getProperty("name");
        response.getWriter().print(name);

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

HttpServletResponse

下载文件

@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    // 1. 要获取下载文件的路径
    String realPath = "我的路径\servlet-01\src\main\resources\1.png";
    // 2. 下载的文件名是啥?
    String fileName = realPath.substring(realPath.lastIndexOf("\\") + 1);
    // 3. 设置想办法让浏览器能够支持(Content-Disposition)下载我们需要的东西,中文文件名URLEncoder.encode编码,否则有可能乱码
    resp.setHeader("Content-Disposition","attachment;filename="+URLEncoder.encode(fileName,"UTF-8"));
    // 4. 获取下载文件的输入流
    FileInputStream in = new FileInputStream(realPath);
    // 5. 创建缓冲区
    int len = 0;
    byte[] buffer = new byte[1024];
    // 6. 获取OutputStream对象
    ServletOutputStream out = resp.getOutputStream();
    // 7. 将FileOutputStream流写入到buffer缓冲区,使用OutputStream将缓冲区中的数据输出到客户端!
    while ((len=in.read(buffer))>0){  //	如果in从缓冲区读取数据大于0  继续执行
        out.write(buffer,0,len);
    }
    in.close();
    out.close();
}

简单实现登录重定向

<%--这里提交的路径,需要寻找到项目的路径--%>
<%--${pageContext.request.contextPath}代表当前的项目--%>
<form action="${pageContext.request.contextPath}/login" method="get">
    用户名:<input type="text" name="username"> <br>
    密码:<input type="password" name="password"> <br>
    <input type="submit">
form>
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //处理请求
        String username = req.getParameter("username");
        String password = req.getParameter("password");

        System.out.println(username+":"+password);

        //重定向时候一定要注意,路径问题,否则404;
        resp.sendRedirect("/r/success.jsp");   //跳转到成功页面
    }

HttpServletRequest

获取参数,请求转发

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Titletitle>
head>
<body>
    <h1>loginh1>
    <div>
        <form action="${pageContext.request.contextPath}/login" method="post">
            用户名:<input type="text" name="username"> <br>
            密码:<input type="password" name="password">  <br>
            爱好
            <input type="checkbox" name="hobbys" value="girls">girls
            <input type="checkbox" name="hobbys" value="code">code
            <input type="checkbox" name="hobbys" value="book">book
            <input type="checkbox" name="hobbys" value="movie">movie
            <input type="submit">
            <br>
        form>
    div>
body>
html>
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    req.setCharacterEncoding("utf-8");
    resp.setCharacterEncoding("utf-8");

    String username = req.getParameter("username");
    String password = req.getParameter("password");
    String[] hobbys = req.getParameterValues("hobbys");
    System.out.println("=============================");
    //后台接收中文乱码问题
    System.out.println(username);
    System.out.println(password);
    System.out.println(Arrays.toString(hobbys));
    System.out.println("=============================");


    System.out.println(req.getContextPath());
    //通过请求转发
    //这里的 / 代表当前的web应用
    req.getRequestDispatcher("/success.jsp").forward(req,resp);

}

Session

使用Session:

public class SessionDemo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        
        //解决乱码问题
        req.setCharacterEncoding("UTF-8");
        resp.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html;charset=utf-8");
        
        HttpSession session = req.getSession();					    //得到Session
        
        session.setAttribute("name",new Person("zhangyan",20));		//给Session中存东西
        
        String id = session.getId();								//获取Session的ID

        //Session创建的时候做了什么事情;
//        Cookie cookie = new Cookie("JSESSIONID",id);
//        resp.addCookie(cookie);

        Person me = (Person) session.getAttribute("name");		//得到Session		
        if(session.isNew()){		//判断Session是不是新创建
            resp.getWriter().print("session create sucess:"+id);		
            resp.getWriter().print("
"
); resp.getWriter().print("
"
); resp.getWriter().print(me.toString()); }else { resp.getWriter().print("session have been exist:"+id); resp.getWriter().print("
"
); resp.getWriter().print("
"
); resp.getWriter().print(me.toString()); } } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { doGet(req, resp); } }
public class SessionDemo02 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        HttpSession session = req.getSession();		
        session.removeAttribute("name");		//移除属性
        session.invalidate();					//手动注销Session
    }
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        doGet(req, resp);
    }
}

会话自动过期:web.xml配置


<session-config>
    
    <session-timeout>15session-timeout>
session-config>

JSP

<% 代码片段	代码在方法里面 %>
<%= 变量或者表达式%>
<%! 声明 代码在方法之外%>    

<%--注释--%>

JSP指令

定制错误页面

<%@page errorPage="	" %>

第二种方法

<error-page>
    <error-code>500error-code>
    <location>/error/error.jsplocation>
error-page>

引用页面

<%@page args.... %>
<%@include file=""%>

<%--@include会将两个页面合二为一--%>

<%@include file="common/header.jsp"%>
<h1>total</h1>
<%@include file="common/footer.jsp"%>

<hr>

<%--本质上是这个
    out.write("

l am head

\r\n"
); out.write("\r\n"); int i = 10 ; out.write('\r'); out.write('\n'); out.print(i); out.write("\n"); out.write("

total

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

l am footer

"
); --%>
<%--jSP标签
    jsp:include:拼接页面,本质还是三个   page代表页面   页面是要当前web下的页面  所以前面需要加个/
    --%>
<jsp:include page="/common/header.jsp"/>
<h1>网页主体</h1>
<jsp:include page="/common/footer.jsp"/>

<%--本质上是这个
  org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/common/header.jsp", out, false);
  out.write("\n");
  out.write("

total2

\n"
); out.write('\n'); out.print(i); out.write('\n'); org.apache.jasper.runtime.JspRuntimeLibrary.include(request, response, "/common/footer.jsp", out, false); --%>

内置对象

pageContext.setAttribute("name1","zz"); //保存的数据只在一个页面中有效
request.setAttribute("name2","zz"); //保存的数据只在一次请求中有效,请求转发会携带这个数据
session.setAttribute("name3","zz"); //保存的数据只在一次会话中有效,从打开浏览器到关闭浏览器
application.setAttribute("name4","zz");  //保存的数据只在服务器中有效,从打开服务器到关闭服务器

request:客户端向服务器发送请求,产生的数据,用户看完就没用了,比如:新闻,用户看完没用的!
session:客户端向服务器发送请求,产生的数据,用户用完一会还有用,比如:购物车;
application:客户端向服务器发送请求,产生的数据,一个用户用完了,其他用户还可能使用,比如:聊天数据;

JavaBean

JavaBean有特定的写法:

  • 必须要有一个无参构造
  • 属性必须私有化
  • 必须有对应的get/set方法;
class People{
    private int id;
    private String name;
    private int id;
    private String address;
}

class A{
    new People(1,"zz",3"shanghai");
    new People(2,"zz",3"shanghai");
    new People(3,"zz",3"shanghai");
}

操作数据库里的东西

<%
    People people = new People();
    people.setId(1);
    people.setName("zy");
    people.setAge(20);
    people.setAddress("shanghai");
%>
name       <%=people.getId()%>
id         <%=people.getName()%>
age        <%=people.getAge()%>
address    <%=people.getAddress()%>

等价于

<jsp:useBean id="people" class="zhang.People" scope="page"/>
<jsp:setProperty name="people" property="id" value="1"/>
<jsp:setProperty name="people" property="name" value="zy"/>
<jsp:setProperty name="people" property="age" value="20"/>
<jsp:setProperty name="people" property="address" value="shanghai"/>

name      <jsp:getProperty name="people" property="name"/>
id        <jsp:getProperty name="people" property="id"/>
age       <jsp:getProperty name="people" property="age"/>
address   <jsp:getProperty name="people" property="address"/>

Filter

public class CharacterEncodingFilter implements Filter {

    //初始化:web服务器启动,就以及初始化了,随时等待过滤对象出现!
    public void init(FilterConfig filterConfig) throws ServletException {
        System.out.println("CharacterEncodingFilter初始化");
    }

    //Chain : 链
    /*
    1. 过滤中的所有代码,在过滤特定请求的时候都会执行
    2. 必须要让过滤器继续同行
        chain.doFilter(request,response);
     */
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        request.setCharacterEncoding("utf-8");
        response.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=UTF-8");

        System.out.println("CharacterEncodingFilter执行前....");
        chain.doFilter(request,response); //让我们的请求继续走,如果不写,程序到这里就被拦截停止!相当于转接人
        System.out.println("CharacterEncodingFilter执行后....");
    }

    //销毁:web服务器关闭的时候,过滤会销毁
public void destroy() {
        System.out.println("CharacterEncodingFilter销毁");
    }
}

在web.xml中配置 Filter

<filter>
    <filter-name>CharaterEncodingFilterfilter-name>
    <filter-class>com.zhang.filter.CharaterEncodingFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>CharaterEncodingFilterfilter-name>
    
    <url-pattern>/servelet/*url-pattern>
filter-mapping>

监听器

<h1>当前在线人数
<span>
<%=
  this.getServletConfig().getServletContext().getAttribute("Online")
%>
span>
h1>
//统计网站在线人数 : 统计session
public class OnlineCountListener implements HttpSessionListener {

    //创建session监听: 看你的一举一动
    //一旦创建Session就会触发一次这个事件!
    public void sessionCreated(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        System.out.println(se.getSession().getId());

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount = new Integer(1);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count+1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);

    }

    //销毁session监听
    //一旦销毁Session就会触发一次这个事件!
    public void sessionDestroyed(HttpSessionEvent se) {
        ServletContext ctx = se.getSession().getServletContext();

        Integer onlineCount = (Integer) ctx.getAttribute("OnlineCount");

        if (onlineCount==null){
            onlineCount = new Integer(0);
        }else {
            int count = onlineCount.intValue();
            onlineCount = new Integer(count-1);
        }

        ctx.setAttribute("OnlineCount",onlineCount);

    }


    /*
    Session销毁:
    1. 手动销毁  getSession().invalidate();
    2. 自动销毁
     */
}
   

<listener>
    <listener-class>com.zhang.listener.OnlineCountListenerlistener-class>
listener>

<session-config>
    <session-timeout>1session-timeout>
session-config>

简单登录

登录页面

<form action="/login" method="post">       
    name:
    <input type="text" name="username">
    <input type="submit" value="submit">
form>

Sucess and Error

<%--Sucess --%>
    
<%--可以但不应该交给jsp来做、交给过滤器--%>
<%--
<%
    Object userSession = request.getSession().getAttribute("user_session");
    if(userSession==null){			<%--userSession为空重定向到login.jsp页面 --%>
        response.sendRedirect("/login.jsp");
    }
%>
--%>
    
<h1>congratulation sucess</h1>
<a href="/loginout">loginout</a>

    
    
<%--error--%>
<h1>you are wrong</h1>
<a href="/login.jsp">back</a>

LoginServlet

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

    String username = req.getParameter("username");
    if(username.equals("zz")){
        req.getSession().setAttribute("user_session",req.getSession().getId());
        resp.sendRedirect("/Sucess/sucess.jsp");
    }else {
        resp.sendRedirect("/error.jsp");
    }
}

Loginout

protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    Object user_session = req.getSession().getAttribute("user_session");
    if(user_session!=null){
        req.getSession().removeAttribute("user_session");   //移除user_session
        resp.sendRedirect("/login.jsp");
    }else {
        resp.sendRedirect("/login.jsp");
    }
}

SysFilter

public void doFilter(ServletRequest req, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
    HttpServletRequest request = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) resp;
    if(request.getSession().getAttribute("user_session")==null){
        response.sendRedirect("/error.jsp");
    }
    filterChain.doFilter(req,resp);
}

xml


<servlet>
    <servlet-name>loginservlet-name>
    <servlet-class>com.zhang.login.LoginServletservlet-class>
servlet>
<servlet-mapping>
    <servlet-name>loginservlet-name>
    <url-pattern>/loginurl-pattern>       
servlet-mapping>


<servlet>
    <servlet-name>loginoutservlet-name>
    <servlet-class>com.zhang.loginout.LoginOutservlet-class>
servlet>
<servlet-mapping>
    <servlet-name>loginoutservlet-name>
    <url-pattern>/loginouturl-pattern>
servlet-mapping>


<filter>
    <filter-name>SysFilterfilter-name>
    <filter-class>com.zhang.filter.SysFilterfilter-class>
filter>
<filter-mapping>
    <filter-name>SysFilterfilter-name>
    <url-pattern>/Sucess/*url-pattern>		
filter-mapping>

JDBC

JDBC 固定步骤:

  1. 加载驱动
  2. 连接数据库,代表数据库
  3. 向数据库发送SQL的对象Statement : CRUD
  4. 编写SQL (根据业务,不同的SQL)
  5. 执行SQL
  6. 关闭连接
public class TestJdbc {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        String url ="jdbc:mysql://localhost:3306/jdbc?useSSL=false&serverTimezone=UTC" +
                "&useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "1234";

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //3.向数据库发送SQL的对象Statement,PreparedStatement : CRUD
        Statement statement = connection.createStatement();

        //4.编写SQL
        String sql = "select * from users";

        //5.执行查询SQL,返回一个 ResultSet  : 结果集
        ResultSet rs = statement.executeQuery(sql);

        while (rs.next()){
            System.out.println("id="+rs.getObject("id"));
            System.out.println("name="+rs.getObject("name"));
            System.out.println("password="+rs.getObject("password"));
            System.out.println("email="+rs.getObject("email"));
            System.out.println("birthday="+rs.getObject("birthday"));
        }

        //6.关闭连接,释放资源(一定要做) 先开后关
        rs.close();
        statement.close();
        connection.close();
    }
}

预编译SQL

public class TestJDBC2 {
    public static void main(String[] args) throws Exception {
        //配置信息
        //useUnicode=true&characterEncoding=utf-8 解决中文乱码
        String url ="jdbc:mysql://localhost:3306/jdbc?useSSL=false&serverTimezone=UTC" +
                "&useUnicode=true&characterEncoding=utf-8";
        String username = "root";
        String password = "1234";

        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库,代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //3.编写SQL
        String sql = "insert into  users(id, name, password, email, birthday) values (?,?,?,?,?);";

        //4.预编译
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        preparedStatement.setInt(1,2);//给第一个占位符? 的值赋值为1;
        preparedStatement.setString(2,"zz");//给第二个占位符? 的值赋值为狂神说Java;
        preparedStatement.setString(3,"123456");//给第三个占位符? 的值赋值为123456;
        preparedStatement.setString(4,"[email protected]");//给第四个占位符? 的值赋值为[email protected]
        preparedStatement.setDate(5,new Date(new java.util.Date().getTime()));//给第五个占位符? 的值赋值为new Date(new java.util.Date().getTime());

        //5.执行SQL
        int i = preparedStatement.executeUpdate();

        if (i>0){
            System.out.println("insert sucess");
        }

        //6.关闭连接,释放资源(一定要做) 先开后关
        preparedStatement.close();
        connection.close();
    }
}

事务

搭建一个环境

CREATE TABLE account(
   id INT PRIMARY KEY AUTO_INCREMENT,
   `name` VARCHAR(40),
   money FLOAT
);

INSERT INTO account(`name`,money) VALUES('A',1000);
INSERT INTO account(`name`,money) VALUES('B',1000);
INSERT INTO account(`name`,money) VALUES('C',1000);
start transaction ;#开启事务
update account set money = money-100 where name='A';
update account set money = money+100 where name='B';
rollback;#回滚  要发生在commit之前才有用
commit;#提交事务
@Test
public void test() {
    //配置信息
    //useUnicode=true&characterEncoding=utf-8 解决中文乱码
    String url="jdbc:mysql://localhost:3306/jdbc?useUnicode=true&characterEncoding=utf-8";
    String username = "root";
    String password = "1234";

    Connection connection = null;

    //1.加载驱动
    try {
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库,代表数据库
         connection = DriverManager.getConnection(url, username, password);

        //3.通知数据库开启事务,false 开启
        connection.setAutoCommit(false);

        String sql = "update account set money = money-100 where name = 'A'";
        connection.prepareStatement(sql).executeUpdate();

        //制造错误
        //int i = 1/0;

        String sql2 = "update account set money = money+100 where name = 'B'";
        connection.prepareStatement(sql2).executeUpdate();

        connection.commit();//以上两条SQL都执行成功了,就提交事务!
        System.out.println("success");
    } catch (Exception e) {
        try {
            //如果出现异常,就通知数据库回滚事务
            connection.rollback();
        } catch (SQLException e1) {
            e1.printStackTrace();
        }
        e.printStackTrace();
    }finally {
        try {
            connection.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

流程

web.xml最新的


<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
                      http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0"
         metadata-complete="true">


web-app>

servlet

req.setCharacterEncoding("utf-8");
resp.setCharacterEncoding("utf-8");	//告诉servlet用UTF-8转码
resp.setContentType("text/html;charset=utf-8"); //设置响应的页面类型		让浏览器用utf8来解析返回的数据 

<dependency>
    <groupId>javax.servletgroupId>
    <artifactId>javax.servlet-apiartifactId>
    <version>4.0.1version>
    <scope>compilescope>
dependency>

<dependency>
    <groupId>javax.servlet.jspgroupId>
    <artifactId>javax.servlet.jsp-apiartifactId>
    <version>2.3.3version>
dependency>

<dependency>
    <groupId>javax.servlet.jsp.jstlgroupId>
    <artifactId>jstl-apiartifactId>
    <version>1.2version>
dependency>

<dependency>
    <groupId>taglibsgroupId>
    <artifactId>standardartifactId>
    <version>1.1.2version>
dependency>

<dependency>
    <groupId>mysqlgroupId>
    <artifactId>mysql-connector-javaartifactId>
    <version>5.1.48version>
dependency>

<dependency>
    <groupId>junitgroupId>
    <artifactId>junitartifactId>
    <version>4.12version>
dependency>
jdbc:mysql://localhost:3306/jdbc?useSSL=false&serverTimezone=UTC

你可能感兴趣的:(Java)