当前位置: 首页 > news >正文

项目实战系列三: 家居购项目 第五部分

🌳显示订单[订单管理]

🌳暂时缺货

需求分析
1.如果某家居库存为0, 首页的"Add to Cart" 按钮显示为"暂时缺货"
2.后台也加上校验. 只有在 库存>0 时, 才能添加到购物车

在这里插入图片描述

代码实现
1.修改web/views/customer/index.jsp

<c:if test="${furn.inventory <= 0}"><button disabled title="Add To Cart" class="add-to-cart">AddTo Cart[缺货]</button>
</c:if>
<c:if test="${furn.inventory > 0}"><button furnId="${furn.id}" title="Add To Cart" class="add-to-cart">AddTo Cart</button>
</c:if>

2.修改src/com/zzw/furns/web/CartServlet.java, 当添加购物车时, 要保证商品的库存>购物车中的已有的商品数量, 不然库存不够没法继续添加

//添加一个添加家居到购物车的方法
protected void addItem(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {int id = DataUtils.parseInt(request.getParameter("id"), 1);//家居id//根据id获取对应的家居信息Furn furn = furnService.queryFurnById(id);//先把正常的逻辑走完, 再处理异常的情况if (furn != null && furn.getInventory() <= 0) {response.sendRedirect(request.getHeader("Referer"));return;}HttpSession session = request.getSession();Cart cart = (Cart) session.getAttribute("cart");//得到购物车 有可能是空的,也有可能是上次的if (cart == null) {cart = new Cart();session.setAttribute("cart", cart);}Map<Integer, CartItem> items = cart.getItems();if (cart.isEmpty()) {CartItem cartItem = new CartItem(id, furn.getName(), 1, furn.getPrice(), furn.getPrice());cart.addItem(cartItem, furn.getInventory());}//构建一条家居明细: id,家居名,数量, 单价, 总价//count类型为Integer, 不赋值默认值为nullCartItem cartItem = new CartItem(id, furn.getName(), 1, furn.getPrice(), furn.getPrice());//将家居明细加入到购物车中. 如果家居id相同,数量+1;如果是一条新的商品,那么就新增cart.addItem(cartItem, furn.getInventory());System.out.println("cart= " + cart);String referer = request.getHeader("referer");response.sendRedirect(referer);
}

3…修改src/com/zzw/furns/entity/Cart.java

//添加购物车, 只有在结账的时候库存变化.
public void addItem(CartItem cartItem, Integer inventory) {//检查要添加的商品是否已存在购物车中//如果没有, 则添加; 如果有, 则增加购物车中商品的数量.//这里默认添加的数量为1CartItem item = items.get(cartItem.getId());if (item == null) {items.put(cartItem.getId(), cartItem);} else if (item.getCount() < inventory){//添加购物车时, 要保证商品的库存>购物车中商品数量, 不然没法下单发货item.setCount(item.getCount() + 1);//修改总价,新的数量✖单价item.setTotalPrice(item.getPrice().multiply(new BigDecimal(item.getCount())));}
}

需求分析
1.购物车里, 更新家居数量时,前台加以限制.
2.后台也加上校验. 只有在 库存>0 时, 才能更新家居数量

代码实现
1.修改src/com/zzw/furns/web/CartServlet.java

//修改指定cartItem的数量和总价
protected void updateCount(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {//传 商品id, 商品countInteger id = DataUtils.parseInt(request.getParameter("id"), 1);Integer count = DataUtils.parseInt(request.getParameter("count"), 0);//得到商品库存Furn furn = furnService.queryFurnById(id);if (furn != null && !(furn.getInventory() > 0 && count <= furn.getInventory())) {response.sendRedirect(request.getHeader("Referer"));return;}//得到购物车HttpSession session = request.getSession();Cart cart = (Cart) session.getAttribute("cart");if (cart != null) {cart.updateCount(id, count);}response.sendRedirect(request.getHeader("Referer"));
}

🌳管理订单

需求分析
1.完成订单管理-查看
2.具体流程参考显示家居
3.静态页面order.html 和 order_detail.html 已提供

程序框架图

在这里插入图片描述

代码实现
1.修改com.zzw.furns.OrderDAO

//根据memberId返回Order对象
public List<Order> queryOrderByMemberId(Integer memberId);

2.修改com.zzw.furns.impl.OrderDaoImpl

@Override
public List<Order> queryOrderByMemberId(Integer memberId) {String sql = "SELECT id, `create_time` as createTime, price, `count`, " +"`status`, member_id as memberId FROM `order` WHERE member_Id=?" +" order by createTime desc";List<Order> orderList = queryMany(sql, Order.class, memberId);return orderList;
}

3.测试, 修改OrderDaoTest

@Test
public void queryOrderByMemberId() {List<Order> orderList = orderDAO.queryOrderByMemberId(9);for (Order order : orderList) {System.out.println(order);}
}

4.修改com.zzw.furns.OrderService

//显示订单
public List<Order> queryOrderByMemberId(Integer memberId);

5.修改com.zzw.furns.impl.OrderServiceImpl

@Override
public List<Order> queryOrderByMemberId(Integer memberId) {List<Order> list = orderDAO.queryOrderByMemberId(memberId);return list;
}

6.测试,修改com.zzw.furns.impl.OrderServiceTest

@Test
public void queryOrderByMemberId() {List<Order> orders = orderService.queryOrderByMemberId(9);for (Order order : orders) {System.out.println(order);}
}

7.web层 - 修改src/com/zzw/furns/web/OrderServlet.java, 增加listByMemberId方法

protected void listByMemberId(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {//获取到登陆的member对象Member member = (Member) req.getSession().getAttribute("member");if (member == null) {//说明用户没有登录//重定向到登陆页面req.getRequestDispatcher("/views/member/login.jsp").forward(req, resp);return;//直接返回}List<Order> orders = orderService.queryOrderByMemberId(member.getId());//把订单集合放入到request域中req.setAttribute("orders", orders);//请求转发到order.jspreq.getRequestDispatcher("/views/order/order.jsp").forward(req, resp);
}

8.新增web/views/order/order.jsp

<c:forEach items="${requestScope.orders}" var="order"><tr><td class="product-name">${order.id}</td><td class="product-name">${order.createTime}</td><td class="product-price-cart"><span class="amount">${order.price}</span></td><td class="product-name"><a href="#"><c:choose><c:when test="${order.status == 1}">未发货</c:when><c:when test="${order.status == 2}">已发货</c:when><c:when test="${order.status == 3}">未结账</c:when><c:otherwise>错误</c:otherwise></c:choose></a></td><td class="product-remove"><a href="#"><i class="icon-eye"></i></a></td></tr>
</c:forEach>

🌳管理订单项

程序框架图

在这里插入图片描述

代码实现
1.修改com.zzw.furns.OrderDAO

//根据id返回Order对象
public Order queryOrderById(String id);

2.修改com.zzw.furns.impl.OrderDaoImpl

@Override
public Order queryOrderById(String id) {String sql = "SELECT id, `create_time` AS createTime, price, `count`, `status`, " +"member_id AS memberId FROM `order` WHERE id= ?";Order order = querySingle(sql, Order.class, id);return order;
}

3.测试, 修改OrderDaoTest

@Test
public void queryOrderById() {Order order = orderDAO.queryOrderById("968d9002-a92e-445f-b77e-7654d7a7598e");System.out.println(order);
}

4.修改com.zzw.furns.OrderItemDAO

//返回所有OrderItem对象
public List<OrderItem> queryOrderItemByOrderId(String orderId);

5.修改com.zzw.furns.impl.OrderItemDaoImpl

@Override
public List<OrderItem> queryOrderItemByOrderId(String orderId) {String sql = "SELECT id, `name`, `count`, price, total_price as totalPrice, " +"order_id as orderId FROM order_item WHERE order_id = ?";List<OrderItem> orderItemList = queryMany(sql, OrderItem.class, orderId);return orderItemList;
}

6.测试, 修改OrderItemDaoTest

@Test
public void queryOrderItemByOrderId() {String orderId = "54062db9-e514-4218-b784-a0f5db91ef41";List<OrderItem> orderItemList = orderItemDAO.queryOrderItemByOrderId(orderId);for (OrderItem orderItem : orderItemList) {System.out.println(orderItem);}
}

7.修改com.zzw.furns.OrderService

//根据id返回Order对象
public Order queryOrderById(String id);

8.修改com.zzw.furns.impl.OrderServiceImpl

@Override
public Order queryOrderById(String id) {Order order = orderDao.queryOrderById(id);List<OrderItem> orderItems = orderItemDao.queryOrderItemByOrderId(id);order.setItems(orderItems);return order;
}

9.测试,修改com.zzw.furns.impl.OrderServiceTest

@Test
public void queryOrderById() {Order order = orderService.queryOrderById("968d9002-a92e-445f-b77e-7654d7a7598e");System.out.println(order);
}

10.web层 - 修改src/com/zzw/furns/web/OrderServlet.java, 增加listOrderItemByOrderId方法

protected void listOrderItemByOrderId(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {String orderId = req.getParameter("orderId");orderId = (orderId == null) ? "" : orderId;Order order = orderService.queryOrderById(orderId);req.setAttribute("order", order);req.getRequestDispatcher("/views/order/order_detail.jsp").forward(req, resp);
}

11.修改前端order.jsp

<td class="product-remove"><a href="orderServlet?action=listOrderItemByOrderId&orderId=${order.id}"><i class="icon-eye"></i></a>
</td>

12.新增并修改order_detail.jsp

<c:forEach items="${requestScope.order.items}" var="orderItem"><tr><td class="product-name"><a href="#">${orderItem.name}</a></td><td class="product-price-cart"><span class="amount">$${orderItem.price}</span></td><td class="product-quantity">${orderItem.count}</td><td class="product-subtotal">$${orderItem.totalPrice}</td></tr>
</c:forEach>
<div class="cart-shiping-update-wrapper"><h4>共${requestScope.order.totalCount}件商品 总价 ${requestScope.order.price}元</h4><div class="cart-clear"><a href="#">继 续 购 物</a></div>
</div>

🌈过滤器权限验证

需求分析
1.加入过滤器权限验证
2.如果没有登陆, 查看购物车和添加到购物车, 就会自动转到会员登陆页面

代码实现
1.修改web.xml, 配置过滤器

<?xml version="1.0" encoding="UTF-8"?>
<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"><!--过滤器一般我们配置在上面--><filter><filter-name>AuthFilter</filter-name><filter-class>com.zzw.furns.filter.AuthFilter</filter-class><init-param><!--这里配置了后, 还需要在过滤器中处理--><param-name>excludedUrls</param-name><param-value>/views/manage/manage_login.jsp,/views/member/login.jsp</param-value></init-param></filter><filter-mapping><filter-name>AuthFilter</filter-name><!--这里配置要验证的url1.在filter-mapping中的url-pattern配置 要拦截/验证的url2.对于我们不去拦截的url, 就不配置3.对于要拦截的目录中的某些要放行的资源, 再通过配置指定--><url-pattern>/views/cart/*</url-pattern><url-pattern>/views/manage/*</url-pattern><url-pattern>/views/member/*</url-pattern><url-pattern>/views/order/*</url-pattern><url-pattern>/cartServlet</url-pattern><url-pattern>/manage/furnServlet</url-pattern><url-pattern>/orderServlet</url-pattern></filter-mapping>
</web-app>

2.新建src/com/zzw/furns/filter/AuthFilter.java,过滤器逻辑判断

/*** 这是用于权限验证的过滤器, 对指定的url进行验证* 如果登陆过, 就放行; 如果没有登陆, 就回到登陆页面** @author 赵志伟* @version 1.0*/
public class AuthFilter implements Filter {private List<String excludedUrls;@Overridepublic void init(FilterConfig filterConfig) throws ServletException {//获取到配置的excludedUrlsString strExcludedUrls = filterConfig.getInitParameter("excludedUrls");//分割 /views/manage/manage_login.jsp,/views/member/login.jspString[] split = strExcludedUrls.split(",");//将 splitUrl 转成 listexcludedUrls = Arrays.asList(split);System.out.println("excludedUrls= " + excludedUrls);}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {System.out.println("请求/cartServlet 被拦截...");HttpServletRequest request = (HttpServletRequest) servletRequest;//得到请求的urlString url = request.getServletPath();System.out.println("url= " + url);//判断是否要验证if (!excludedUrls.contains(url)) {//获取到登陆的member对象Member member = (Member) request.getSession().getAttribute("member");if (member == null) {//说明用户没有登录//转发到登陆页面, 转发不走过滤器servletRequest.getRequestDispatcher("/views/member/login.jsp").forward(servletRequest, servletResponse);重定向-拦截-重定向-拦截-重定向-拦截//((HttpServletResponse) servletResponse)//        .sendRedirect(request.getContextPath() + "/views/member/login.jsp");return;//直接返回}}//验证通过, 放行filterChain.doFilter(servletRequest, servletResponse);System.out.println("请求/cartServlet验证通过, 放行");}@Overridepublic void destroy() {}
}

🌈事务管理

数据不一致问题

1.将FurnDAOImpl.java的updateFurn方法的sql故意写错. [furnDAO.updateFurn(furn);由ctrl+alt+b定位到updateFurn的实现方法]
2.在OrderServiceImpl的saveOrder()方法内捕获一下异常, 目的是保证程序能够继续执行
3.查看数据库里的数据会有什么结果. 会出现数据不一致的问题.

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
我在首页购买了一个小台灯, 数据库中生成了对应的订单和订单项, 但家居表里该小台灯的销量和库存没有变化, 纹丝不动. 相当于客户下单了, 但没有给人家发货.

在这里插入图片描述

在这里插入图片描述

程序框架图

思路分析
1.使用 Filter + ThreadLocal 来进行事务管理
2.说明: 在一次http请求中, servlet-service-dao 的调用过程, 始终是一个线程, 这是使用ThreadLocal的前提
3.使用ThreadLocal来确保所有dao操作都在同一个Connection内

程序框架图

在这里插入图片描述

1.修改src/com/zzw/furns/utils/JdbcUtilsByDruid.java工具类

public class JdbcUtilsByDruid {private static DataSource dataSource;//定义属性ThreadLocal, 这里存放一个Connectionprivate static ThreadLocal<Connection> threadlocalConn = new ThreadLocal<>();/*** 从ThreadLocal获取connection, 从而保证在一个线程中* 获取的是同一个Connection*/public static Connection getConnection() {Connection connection = threadlocalConn.get();if (connection == null) {//说明当前的threadlocal没有这个连接try {//就从数据库连接池中取出连接放入threadlocalconnection = dataSource.getConnection();//将连接设置为手动提交, 既不要让它自动提交connection.setAutoCommit(false);threadlocalConn.set(connection);} catch (SQLException e) {throw new RuntimeException(e);}}return connection;}/*** 提交事务*/public static void commit() {Connection connection = threadlocalConn.get();if (connection != null) {try {connection.commit();} catch (SQLException e) {throw new RuntimeException(e);} finally {try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}//1.当提交后, 需要把connection从threadlocalConn中清除掉//2.不然会造成threadlocalConn长时间持有该连接, 会影响效率//3.也因为Tomcat底层使用的是线程池技术threadlocalConn.remove();}}/*** 说明: 所谓回滚是 回滚/撤销 和connection管理的操作 删除/修改/添加*/public static void rollback() {Connection connection = threadlocalConn.get();if (connection != null) {try {connection.rollback();} catch (SQLException e) {throw new RuntimeException(e);} finally {try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}threadlocalConn.remove();}}//public static Connection getConnection() {//    try {//        return dataSource.getConnection();//    } catch (SQLException e) {//        throw new RuntimeException(e);//    }//}static {try {Properties properties = new Properties();//properties.load(new FileInputStream("src/druid.properties"));//因为我们是web项目, 它的工作目录在out. 文件的加载,需要使用类加载器//需要找到我们的工作目录properties.load(JdbcUtilsByDruid.class.getClassLoader().getResourceAsStream("druid.properties"));dataSource = DruidDataSourceFactory.createDataSource(properties);} catch (Exception e) {throw new RuntimeException(e);}}public static void close(ResultSet resultSet, Statement statement, Connection connection) {try {if (resultSet != null) {resultSet.close();}if (statement != null) {statement.close();}if (connection != null) {connection.close();}} catch (SQLException e) {throw new RuntimeException(e);}}
}

2.修改src/com/zzw/furns/dao/BasicDAO.java
删掉各个方法finally代码块里的close方法. 只有在事务结束后才实施关闭连接的操作. 一是提交事务后关闭连接; 二是增删改出错后, 回滚关闭连接.

public class BasicDAO<T> {private QueryRunner queryRunner = new QueryRunner();/*** @param sql sql语句, 可以有 占位符?* @param clazz 传入一个类的Class对象, 例如User.class* @param objects 传入具体的值, 对应sql中的占位符?, 可以有多个* @return 根据对应的User.class, preparedStatement->resultSet->ArrayList, 返回最终的ArrayList集合*/public List<T> queryMany(String sql, Class<T> clazz, Object... objects) {Connection connection = null;try {connection = JdbcUtilsByDruid.getConnection();List<T> tList =queryRunner.query(connection, sql, new BeanListHandler<>(clazz), objects);return tList;} catch (SQLException e) {throw new RuntimeException(e);//编译异常->运行异常抛出}}//查询单行, 返回的是一个对象public T querySingle(String sql, Class<T> clazz, Object... objects) {Connection connection = null;try {connection = JdbcUtilsByDruid.getConnection();T object= queryRunner.query(connection, sql, new BeanHandler<>(clazz), objects);return object;} catch (Exception e) {throw new RuntimeException(e);}}//查询某一字段public Object queryScalar(String sql, Object... objects) {Connection connection = null;try {connection = JdbcUtilsByDruid.getConnection();Object query = queryRunner.query(connection, sql, new ScalarHandler(), objects);return query;} catch (Exception e) {throw new RuntimeException(e);}}public int update(String sql, Object... objects) {Connection connection = null;try {//这里是从数据库连接池获取connection//注意:每次从连接池中取出connection, 不能保证是同一个//1.我们目前已经是从和当前线程关联的ThreadLocal获取的connection//2.所以可以保证是同一个连接[在同一个线程中/在同一个请求中 => 因为一个请求对应一个线程]connection = JdbcUtilsByDruid.getConnection();return queryRunner.update(connection, sql, objects);} catch (Exception e) {throw new RuntimeException(e);}}
}

3.修改控制层src/com/zzw/furns/web/OrderServlet.java, 进行事务管理
前提OrderServiceImpl里报错的代码取消try-catch, 在OrderServlet控制层捕获

protected void saveOrder(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {HttpSession session = request.getSession();Cart cart = (Cart) session.getAttribute("cart");//如果购物车为空,或者购物车在session,没有家居信息if (cart == null || cart.isEmpty()) {response.sendRedirect(request.getHeader("Referer"));return;}//获取登录到的memberMember member = (Member) session.getAttribute("member");if (member == null) {//用户未登录,不可点击订单管理,重定向到登陆页面request.getRequestDispatcher("/views/member/login.jsp").forward(request, response);return;}String orderId = "";try {orderId = orderService.saveOrder(cart, member.getId());JdbcUtilsByDruid.commit();} catch (Exception e) {JdbcUtilsByDruid.rollback();e.printStackTrace();}session.setAttribute("orderId", orderId);response.sendRedirect(request.getContextPath() + "/views/order/checkout.jsp");
}

Transaction过滤器

程序框架图

在这里插入图片描述

体会: 异常机制是可以参与业务逻辑的

在这里插入图片描述
在这里插入图片描述

代码实现
1.在OrderService控制层里取消捕获异常, 将代码重新改回下述模样
String orderId = orderService.saveOrder(cart, member.getId());

2.同时BasicServlet模板里也取消异常捕获, 或者将异常抛出, 代码如下

String action = req.getParameter("action");
System.out.println("action= " + action);//login register page
try {Method declaredMethod =this.getClass().getDeclaredMethod(action, HttpServletRequest.class, HttpServletResponse.class);System.out.println("declaredMethod= " + declaredMethod);System.out.println("this = " + this);//com.zzw.furns.web.MemberServlet@38f54ed7declaredMethod.invoke(this, req, resp);System.out.println("this.getClass() = " + this.getClass());
} catch (Exception e) {//将发生的异常, 继续throwthrow new RuntimeException(e);
}

3.新建src/com/zzw/furns/filter/TransactionFilter.java.
在代码执行完毕后, 会运行到Transaction过滤器的后置代码, 在这里进行异常捕获, 如果发生异常, 则回滚.

public class TransactionFilter implements Filter {public void init(FilterConfig config) throws ServletException {}public void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {try {//放行chain.doFilter(request, response);JdbcUtilsByDruid.commit();//统一提交} catch (Exception e) {//出现了异常JdbcUtilsByDruid.rollback();//回滚e.printStackTrace();}}
}

配置web.xml

<filter><filter-name>TransactionFilter</filter-name><filter-class>com.zzw.furns.filter.TransactionFilter</filter-class>
</filter>
<filter-mapping><filter-name>TransactionFilter</filter-name><!--这里我们对请求都进行事务管理 --><url-pattern>/*</url-pattern>
</filter-mapping>

🌈统一错误页面

需求分析
1.如果在访问/操作网站时, 出现了内部错误, 统一显示 500.jsp
2.如果访问/操作的页面/servlet不存在时, 统一显示 404.jsp

思路分析
1.发生错误/异常时, 将错误/异常抛给tomcat
2.在web.xml中配置不同错误显示的页面即可

1.在/views/error引入404.html, 500.html, 修改成jsp文件

在这里插入图片描述

2.将跳转链接改成index.jsp

<a class="active" href="index.jsp"><h4 style="color: darkblue">您访问的页面不存在 返回首页</h4>
</a>
<a class="active" href="index.jsp"><h4 style="color: darkblue">sorry,您访问的页面出现了错误 返回首页</h4>
</a>

3.配置web.xml

<!--错误提示的配置一般写在web.xml的下面--><!--500 错误提示页面-->
<error-page><error-code>500</error-code><location>/views/error/500.jsp</location>
</error-page>
<!--404 错误提示页面-->
<error-page><error-code>404</error-code><location>/views/error/404.jsp</location>
</error-page>

4…修改事务过滤器, 将异常抛给tomcat

public class TransactionFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {}@Overridepublic void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {try {//放行filterChain.doFilter(servletRequest, servletResponse);JdbcUtilsByDruid.commit();//统一提交} catch (Exception e) {//出现了异常//只有在try{}中出现了异常, 才会进行catch{}//才会进行回滚JdbcUtilsByDruid.rollback();//回滚//抛出异常, 给tomcat. tomcat会根据error-page来显示对应页面throw new RuntimeException(e);//e.printStackTrace();}}@Overridepublic void destroy() {}
}

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • C++ STL-Map容器从入门到精通详解
  • HarmonyOs DevEco Studio小技巧9--翻译软件
  • 怎么利用XML发送物流快递通知短信
  • qml Component 组件
  • 【设计模式】设计模式的八大原则
  • 无线麦克风哪个品牌音质最好?十大音质最好的麦克风品牌推荐
  • Lua5.3 参考手册
  • C++(一)----C++基础
  • 用CSS 方式设置 table 样式
  • 抢鲜体验 PolarDB PG 15 开源版
  • AI智能工牌:告别手动录入,1小时上门服务报告,3分钟生成
  • 处理sra数据
  • Node.js学习记录(二)
  • CMake创建OpenGL项目
  • golang hertz框架入门
  • hexo+github搭建个人博客
  • 【Linux系统编程】快速查找errno错误码信息
  • 4月23日世界读书日 网络营销论坛推荐《正在爆发的营销革命》
  • Android路由框架AnnoRouter:使用Java接口来定义路由跳转
  • Angular js 常用指令ng-if、ng-class、ng-option、ng-value、ng-click是如何使用的?
  • Angularjs之国际化
  • echarts的各种常用效果展示
  • es的写入过程
  • Java Agent 学习笔记
  • JavaScript创建对象的四种方式
  • JS创建对象模式及其对象原型链探究(一):Object模式
  • k8s 面向应用开发者的基础命令
  • Sass 快速入门教程
  • TCP拥塞控制
  • Terraform入门 - 3. 变更基础设施
  • Unix命令
  • 持续集成与持续部署宝典Part 2:创建持续集成流水线
  • 对象管理器(defineProperty)学习笔记
  • 服务器从安装到部署全过程(二)
  • 记一次删除Git记录中的大文件的过程
  • 微信开放平台全网发布【失败】的几点排查方法
  • 【云吞铺子】性能抖动剖析(二)
  • ​LeetCode解法汇总2583. 二叉树中的第 K 大层和
  • ​Spring Boot 分片上传文件
  • (3)nginx 配置(nginx.conf)
  • (STM32笔记)九、RCC时钟树与时钟 第一部分
  • (第8天)保姆级 PL/SQL Developer 安装与配置
  • (附源码)ssm学生管理系统 毕业设计 141543
  • (论文阅读11/100)Fast R-CNN
  • (详细文档!)javaswing图书管理系统+mysql数据库
  • (一)RocketMQ初步认识
  • (一)项目实践-利用Appdesigner制作目标跟踪仿真软件
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)Linux NTP配置详解 (Network Time Protocol)
  • (轉貼)《OOD启思录》:61条面向对象设计的经验原则 (OO)
  • (自用)learnOpenGL学习总结-高级OpenGL-抗锯齿
  • .net mvc 获取url中controller和action
  • .Net MVC4 上传大文件,并保存表单
  • .Net mvc总结
  • .NET开发不可不知、不可不用的辅助类(三)(报表导出---终结版)