java web project--learning through building 7
a full-stack web application for users to understand java web system
- Filter
- 事务管理
- listener
- JSON
- AJAX
- use AJAX invalidate the username
- use AJAX to add the item to the cart
Filter
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();
}
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) {
}
}
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
目的: 用来发送异步的请求,然后当服务器给我响应的时候再进行回调操作
好处: 提高用户体验;局部刷新:降低服务器负担、减轻浏览器压力、减轻网络带宽压力
开发步骤
-
创建 XMLHttpRequest
-
调用 open 进行设置:“GET” , URL , true
-
绑定状态改变时执行的回调函数 - onreadystatechange
-
发送请求 - send()
-
编写回调函数,在回调函数中,我们只对 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);
}