java web project--learning through building 7

Tue, Jan 12, 2021 5-minute read

a full-stack web application for users to understand java web system

Filter

image

servlets

A ->B -> C demo3.service() -> C -> B -> A

过滤器 Filter

  • Filter 也属于 Servlet 规范

  • Filter 开发步骤:新建类实现 Filter 接口,然后实现其中的三个方法:init、doFilter、destroy
    配置 Filter,可以用注解@WebFilter,也可以使用 xml 文件

  • Filter 在配置时,和 servlet 一样,也可以配置通配符,例如 @WebFilter("*.do")表示拦截所有以.do 结尾的请求

  • 过滤器链

    • 执行的顺序依次是: A B C demo03 C2 B2 A2
    • 如果采取的是注解的方式进行配置,那么过滤器链的拦截顺序是按照全类名的先后顺序排序的
    • 如果采取的是 xml 的方式进行配置,那么按照配置的先后顺序进行排序

chorme: tomcat

  • http://ip:port/project/resource 〰️ ▶️ Filter target rescouce . authorized ▶️ html, jsp, Servlet

. ◀️ 〰️ unauthorized

@WebFilter(filterName ="ManagerFilter", urlPatterns = {"/pages/manager/*", "/manager/bookServlet"})
public class AdminFilter implements Filter {
/**
* doFilter method
*/
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain
filterChain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) servletRequest;
HttpSession session = httpServletRequest.getSession();
Object user = session.getAttribute("user");
// 
if (user == null) {
servletRequest.getRequestDispatcher("/login.jsp").forward(servletRequest,servletResponse);
return;
} else {
// 
filterChain.doFilter(servletRequest,servletResponse);
}
}
}

事务管理

涉及到的组件

  • OpenSessionInViewFilter
  • TransactionManager
  • ThreadLocal
  • ConnUtil
  • BaseDAO

ThreadLocal

  • get() , set(obj)
  • ThreadLocal 称之为本地线程 。 我们可以通过 set 方法在当前线程上存储数据、通过 get 方法在当前线程上获取数据
  • set 方法源码分析:
     public void set(T value) {
         Thread t = Thread.currentThread(); //获取当前的线程
         ThreadLocalMap map = getMap(t);    //每一个线程都维护各自的一个容器(ThreadLocalMap)
         if (map != null)
             map.set(this, value);          //这里的key对应的是ThreadLocal,因为我们的组件中需要传输(共享)的对象可能会有多个(不止Connection)
         else
             createMap(t, value);           //默认情况下map是没有初始化的,那么第一次往其中添加数据时,会去初始化
     }
  • get 方法源码分析
     public T get() {
         Thread t = Thread.currentThread(); //获取当前的线程
         ThreadLocalMap map = getMap(t);    //获取和这个线程(企业)相关的ThreadLocalMap(也就是工作纽带的集合)
         if (map != null) {
             ThreadLocalMap.Entry e = map.getEntry(this);   //this指的是ThreadLocal对象,通过它才能知道是哪一个工作纽带
             if (e != null) {
                 @SuppressWarnings("unchecked")
                 T result = (T)e.value;     //entry.value就可以获取到工具箱了
                 return result;
             }
         }
         return setInitialValue();
     }
image

servlets

image

servlets

image

servlets

ThreadLocal and Filter manage transactions

modify JdbcUtils

private static ThreadLocal<Connection> conns = new ThreadLocal<>();
//  Connection conn = null;
Connection conn = conns.get();

BaseDao

Filter add try-catch to Service

@WebFilter(filterName ="TransactionFilter", urlPatterns = "/*")
public class TransactionFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain
filterChain) throws IOException, ServletException {
try {
filterChain.doFilter(servletRequest,servletResponse);
JdbcUtils.commitAndClose();// 提交事务
} catch (Exception e) {
JdbcUtils.rollbackAndClose();//回滚事务
e.printStackTrace();
}
}

throw new RunException() in BaseServlet to Filter

public abstract class BaseServlet extends HttpServlet {
try {
// 
Method method = this.getClass().getDeclaredMethod(action, HttpServletRequest.class,
HttpServletResponse.class);
// System.out.println(method);
// 
method.invoke(this, req, resp);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);// throw new RunException Filter 
}
}

tomcat display error page

<error-page>
<!--error-code -->
<error-code>500</error-code>
<!--location-->
<location>/pages/error/error500.jsp</location>
</error-page>
<!--error-page -->
<error-page>
<!--error-code -->
<error-code>404</error-code>
<!--location -->
<location>/pages/error/error404.jsp</location>
</error-page>

listener

  • ServletContextListener - 监听 ServletContext 对象的创建和销毁的过程
  • HttpSessionListener - 监听 HttpSession 对象的创建和销毁的过程
  • ServletRequestListener - 监听 ServletRequest 对象的创建和销毁的过程
  • ServletContextAttributeListener - 监听 ServletContext 的保存作用域的改动(add,remove,replace)
  • HttpSessionAttributeListener - 监听 HttpSession 的保存作用域的改动(add,remove,replace)
  • ServletRequestAttributeListener - 监听 ServletRequest 的保存作用域的改动(add,remove,replace)
  • HttpSessionBindingListener - 监听某个对象在 Session 域中的创建与移除
  • HttpSessionActivationListener - 监听某个对象在 Session 域中的序列化和反序列化

ContextLoaderListener


//监听上下文启动,在上下文启动的时候去创建IOC容器,然后将其保存到application作用域
//后面中央控制器再从application作用域中去获取IOC容器
@WebListener
public class ContextLoaderListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        //1.获取ServletContext对象
        ServletContext application = servletContextEvent.getServletContext();
        //2.获取上下文的初始化参数
        String path = application.getInitParameter("contextConfigLocation");
        //3.创建IOC容器
        BeanFactory beanFactory = new ClassPathXmlApplicationContext(path);
        //4.将IOC容器保存到application作用域
        application.setAttribute("beanFactory",beanFactory);
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }
}

image

servlets

JSON

JSON && JavaBean

Person person = new Person(1,"AA");
Gson gson = new Gson();
String personJsonString = gson.toJson(person);
System.out.println(personJsonString);

Person person1 = gson.fromJson(personJsonString, Person.class

JSON && List

List<Person> personList = new ArrayList<>();
personList.add(new Person(1, "AA"));
personList.add(new Person(2, "BB"));

Gson gson = new Gson();
// transfer to json string
String personJsonString = gson.toJson(personList);
System.out.println(personJsonString);

List<Person> list = gson.fromJson(personJsonString, new PersonListType().getType());

JSON && Map

Map<Integer,Person> personMap = new HashMap<>()
personList.add(new Person(1, "AA"));
personList.add(new Person(2, "BB"));

Gson gson = new Gson();
// transfer to json string
String personJsonString = gson.toJson(personMap);
System.out.println(personJsonString);

Map<Integer,Person> personMap2 = gson.fromJson(personJsonString, new TypeToken<HashMap<Integer,Person>>(){}.getType());

AJAX

Ajax : 异步的 JavaScript and XML

目的: 用来发送异步的请求,然后当服务器给我响应的时候再进行回调操作

好处: 提高用户体验;局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力

开发步骤

  1. 创建 XMLHttpRequest

  2. 调用 open 进行设置:“GET” , URL , true

  3. 绑定状态改变时执行的回调函数 - onreadystatechange

  4. 发送请求 - send()

  5. 编写回调函数,在回调函数中,我们只对 XMLHttpRequest 的 readystate 为 4 的时候感兴趣

我们只对 XMLHttpRequest 的 status 为 200 的时候感兴趣

0: (Uninitialized) the send( ) method has not yet been invoked. 1: (Loading) the send( ) method has been invoked, request in progress. 2: (Loaded) the send( ) method has completed, entire response received. 3: (Interactive) the response is being parsed. 4: (Completed) the response has been parsed, is ready for harvesting.

0 - (未初始化)还没有调用 send()方法 1 - (载入)已调用 send()方法,正在发送请求 2 - (载入完成)send()方法执行完成,已经接收到全部响应内容 3 - (交互)正在解析响应内容 4 - (完成)响应内容解析完成,可以在客户端调用了

use AJAX invalidate the username

protected void ajaxExistsUsername(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
// get username
String username = req.getParameter("username");
//  userService.existsUsername();
boolean existsUsername = userService.existsUsername(username);
// 
Map<String,Object> resultMap = new HashMap<>();
resultMap.put("existsUsername",existsUsername);
Gson gson = new Gson();
String json = gson.toJson(resultMap);
resp.getWriter().write(json);
}
$("#username").blur(function () {
//1 get username
var username = this.value;
$.getJSON("http://localhost:8080/book/userServlet","action=ajaxExistsUsername&username=" +
username,function (data) {
if (data.existsUsername) {
$("span.errorMsg").text("xxxx!");
} else {
$("span.errorMsg").text("xxxx!");
}
});
});

use AJAX to add the item to the cart

protected void addItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

//        System.out.println("bookId: " + request.getParameter("id"));

        System.out.println("request head reference value: " + request.getHeader("Referer"));
//        2.1 : 获取请求的参数,商品编号
        int id = WebUtils.parseInt(request.getParameter("id"), 0);
//        2.2: 调用bookService.queryBookById(id): Book得到图书的信息
        Book book = bookService.queryBookById(id);
//        2.3: 把图书信息,转换成CartItem商品项
        CartItem cartItem = new CartItem(book.getId(), book.getName(), 1, book.getPrice(), book.getPrice());
//        2.4: 调用Cart.addItem(CartItem);添加商品项
        Cart cart = (Cart) request.getSession().getAttribute("cart");
        if (cart == null) {
            cart = new Cart();
            request.getSession().setAttribute("cart", cart);
        }
        cart.addItem(cartItem);

//        2.5: 重定向回商品列表页面
        System.out.println(cart);
        request.getSession().setAttribute("lastName", cartItem.getName());
        response.sendRedirect(request.getContextPath());

//use AJAX to add the item to the cart
Map<String,Object> resultMap = new HashMap<String,Object>();
resultMap.put("totalCount", cart.getTotalCount());
resultMap.put("lastName",cartItem.getName());
Gson gson = new Gson();
String resultMapJsonString = gson.toJson(resultMap);
resp.getWriter().write(resultMapJsonString);

    }

javaweb2

javaweb3

javaweb4

javaweb5

spring

springmvc