支付
一、后台模块梳理
后台登录
访问/admin/login.jsp,进行登录,修改login.jsp的访问路径
创建AdminController,映射路径为:/admin/auser, login方法中处理登录功能;并存储凭证
登录成功后,跳转到/admin/admin.jsp页面
public String adminLogin(HttpServletRequest request, HttpServletResponse response){
//1. 获取参数
String username = request.getParameter("username");
String password = request.getParameter("password");
//2. 在业务层处理
User user = userService.login(username,password);
if(user!=null){
if(user.getU_role()==0){ //非管理员
request.setAttribute("msg","非管理员用户不能登录");
}else{ //管理员账户
request.getSession().setAttribute(ConstUtils.ADMIN,user);
return ConstUtils.FOR+"/admin/admin.jsp";
}
}else{
request.setAttribute("msg","管理员账户或密码出错");
}
return ConstUtils.FOR+"/admin/login.jsp";
}
展示用户信息
在admin.jsp页面中点击”会员管理“,在userList.jsp中,发ajax请求,在后端将集合数据转JSON回传到前端
public String show(HttpServletRequest request,HttpServletResponse response){
//1.通过业务层调用方法,返回user集合
List<User> list = userService.showUsers();
//2. 再将集合转json数据,回传到前端
return new Gson().toJson(list);
}
删除与搜索
删除功能:
在userList.jsp页面中,点击”删除“,根据uid删除指定的记录;删除完成后,跳转到展示页面
public String delete(HttpServletRequest request, HttpServletResponse response){
String id = request.getParameter("id");
int res = userService.deleteById(id);
System.out.println("删除:"+id);
return show(request,response);
}
搜索功能:
在userList.jsp页面中,传用户名,在后端模糊匹配用户名或性别,进行查询
public String search(HttpServletRequest request, HttpServletResponse response){
String username = request.getParameter("username");
String gender = request.getParameter("gender");
System.out.println("username-->"+username+";gender-->"+gender);
if(username.equals("")&&gender.equals("")){ //如果都没有取到值,则显示所有
return show(request,response); //查所有
}else{
List<User> list = userService.showUsers(username,gender);
return new Gson().toJson(list);
}
}
public List<User> selectAll(String username, String gender) throws SQLException {
String value = "";
boolean flag = false;
if(!username.equals("")){ //用户名的匹配
value = "u_name like '%"+username+"%'";
flag = true;
}
if(!gender.equals("")){
if(flag){
value += "and u_sex = '"+gender+"'";
}else{
value += "u_sex = '"+gender+"'";
}
}
String sql = "select * from user where "+value;
System.out.println("sql--->"+sql);
return runner.query(sql,new BeanListHandler<>(User.class));
}
权限管理
权限管理的必要性: 如果没有权限管理,那么账户没有登录,也可以访问到后端重要的服务器资源中,有安全隐患问题。
具体操作:进入后端的访问,都需要在过滤器中进行拦截检查:如果有登录凭证,或login.jsp或后端访问需要放行,其余的拦截住
@WebFilter("/admin/*")
public class AdminLoginFilter implements Filter {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) servletRequest;
HttpServletResponse response = (HttpServletResponse) servletResponse;
//判断是否有登录凭证, 如果有,则放行
User user = (User) request.getSession().getAttribute(ConstUtils.ADMIN);
if(user!=null){
filterChain.doFilter(request,response); //有凭证则放行
}else{
String uri = request.getRequestURI(); //获取访问的部分路径
String type = request.getParameter("action");
System.out.println("uri--->"+uri+"; action-->"+type);
//如果是后台的login登录和login.jsp,需要放行
if(uri.endsWith("login.jsp")||(uri.endsWith("auser")&&"adminLogin".equals(type))){
filterChain.doFilter(request,response); //放行
}else{
response.sendRedirect(request.getContextPath()+"/admin/login.jsp");
}
}
}
}
二、订单详情
前端处理
点击"订单详情"后,需要从后端带回展示数据;查看orderDetail.jsp页面中需要展示的数据
从页面中可看出,需要返回订单对象,里面包含了地址属性及详情属性集合;订单详情中包含了商品。
<tr>
<td>订单编号:</td>
<td>${od.o_id}</td>
<td>订单时间:</td>
<td>${od.o_time}</td>
</tr>
<tr>
<td>收件人:</td>
<td>${od.addr.a_name}</td>
<td>联系电话:</td>
<td>${od.addr.a_phone}</td>
</tr>
...
后端展示
实体类中的属性包含:
public class Orders {
//...
//订单中包含地址和订单集合属性
private Address addr; //每个订单中由一条地址信息
private List<Item> list; //订单里面包含详情集合
}
public class Item {
//...
private Product goods; //详情中包含商品属性
}
控制层处理:
//订单详情展示
public String showDetail(HttpServletRequest request, HttpServletResponse response){
String oid = request.getParameter("oid"); //获取OID
Orders orders = orderService.showDetail(oid); //展示订单与详情
request.setAttribute("od",orders);
return ConstUtils.FOR+"/orderDetail.jsp";
}
业务层处理:
public Orders showDetail(String oid) {
Orders orders = null;
try{
//1.根据oid获取到订单对象
orders = orderDao.selectOdByOid(oid);
//2.根据oid获取到详情集合
List<Item> list = orderDao.selectItemsByOid(oid);
//3.订单对象中设置详情集合
orders.setList(list);
}catch (Exception e){
e.printStackTrace();
}
return orders;
}
DAO层的处理:
@Override
public Orders selectOdByOid(String oid) throws SQLException, InvocationTargetException, IllegalAccessException {
//查询订单和地址的关联
String sql = "select * from orders o inner join address a on " +
"o.a_id=a.a_id and o.o_id=?";
Map<String, Object> map = runner.query(sql, new MapHandler(), oid);
Orders o = new Orders();
BeanUtils.populate(o,map); //值的注入
Address a = new Address();
BeanUtils.populate(a,map);
o.setAddr(a); //将地址放入订单对象中
return o;
}
@Override
public List<Item> selectItemsByOid(String oid) throws SQLException, InvocationTargetException, IllegalAccessException {
//订单详情与商品的关联
String sql = "select * from item i inner join product p " +
"on i.p_id=p.p_id and i.o_id=?";
List<Map<String, Object>> query = runner.query(sql, new MapListHandler(), oid);
List<Item> items = new ArrayList<>();
for(Map<String, Object> map:query){
Item item = new Item();
BeanUtils.populate(item,map);
Product product = new Product();
BeanUtils.populate(product,map);
item.setGoods(product);
items.add(item);
}
return items;
}
三、支付
查看”沙箱支付“文档,里面有相关配置说明;
测试案例
根据步骤,下载测试案例,并进行调试测试案例。
做支付功能,需要先在测试案例中完成测试,找出与支付相关的文件
需要根据沙箱中的信息来进行配置:AppID,网关,公钥私钥、回调路径
在config配置文件中进行配置,如下所示:
//在案例支付中进行配置
public class AlipayConfig {
// 应用ID,您的APPID,收款账号既是您的APPID对应支付宝账号
public static String app_id = "9021000122699441";
// 商户私钥,您的PKCS8格式RSA2私钥
public static String merchant_private_key = "MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCZUka8yrj4q7jECjhpenZ4eyxc8ivsG3mQ2FmiUkdsUdRiF1wYKo0nej9PUQ3cWIXdZaPdMklO7+aUfGaT0eXNXgpgAwHBKCbqDtZZ/EovvgEpsoS3xFdTHVi3B7va9gLhXvTDm1seDEcZXAIJ3C6Zw0i4lvS5+R3M94PlktsnbsBpOUXPmXOXrqrikKN1f5seJuFQAtDon2N4frfETCLYVb5KhRi62aDTqBevSV55GsPKWUM0UN3mhnxMQrtz8nezfftqUIKSjCyXveWXVUpXCSFCjzhgfcUjho9BqQtUM0y85LVNyon7WDoj9GXw/hTUJmiA4jjl5Mnxnz8D+45RAgMBAAECggEACfAjValuQ/Adkdd3wJ6Hf1e8kGnCHxPI1XKwnKzopETJl3IcLhTUAXMTF3kRhO7X/nnQHU5dIhi6wXUu0PYSBzXJRl/rhTGtFA7SJhMMW/vc528C20aGwoRsc7C0pIS9uw4En4k6ZsA0+5fTKgBzpNPbqtteEY/sNpT0n7TdL7kMYC1Kt3DI4tKFM1x3t5xnlzQIZHHLr+usMs3yUV18UVL81RPE0KGYDbWfH7oslNOw1wnX4X2WypF1pn7rT7ukj7s51Gb2xwrJvhGfQTRqzG/NjD6SK9+DZcN3/vkkTshMhL3st6cshZPTgyNQDtt/ipz4JBmBVGw9yrPgFHSCgQKBgQDIy7++y6ZEJjrpU7ao/230EuTK3uLW1vtOhoGeQUHmSViYhqUzTlC5nDeUQmZ4q9I+2jrquO156TiKyv67fUf4+7hAZKBW8rRwWKbPauhq3wwRmq0KkBiV9s3U1GCUVhSk9cgGfxkvsI1Y4yX7HBPCkPJClhiF8+oLJLy5uNKV/QKBgQDDeTdN12KIan9TSFztMs6v/JOWp3itT2O2iyuOOUoDvcuZ8xXHRJ2XteRpEbB/p6mQWBepRoI6hMMVLwgcAdFJe4WEFYzI6YLWOoxmg/KodPBoHrdd4K95GfzXNM7Gi5UOKcwVKRhFwdo94WtkbvnYZxcOOrgEEH+sizevswTf5QKBgQCId5l41bXJqWXugDurffY/pLukeXkX5IJl6xqa8OUV2xGAkDoktXw9ucM4WyyDpNs+ZlkWf9q+OVh5U99uk4Xf3UxrTzh9/3PMyyOL4q/VOoRcTpB+llJvUY6wsCp3hk1/k59/ctAuTkKyf6anlHyFhrdvs8009QJC0pQFcWyGDQKBgEzmyFoobUxL0ZG7O0vaHDRiQtIXSsOsIwdy0wzd/v9f0NTdLGk71mAUICsx2WUvWec+sPhYk+1fw7v2x9L06BhnrwxaygtUyrNrT0cZjAK4FshvpSYaug4DqlQkI2E7EsYCrZZ5l2ICNND5eR2HB2YakJh5g2Gd+AyyrJLD9Bv9AoGASrwaxb+4D+v4/hkwsuD1DZTT9uZh+57QTsCe1j78Lg+Tem6rU7cd8bc28hjODuF6z/icpRwPogk+APp1N14ViDtgUhrXQfGF7aYQ3H92qDvm0F9t6CxvQCgAUBvA6eFbHduUoZhZ4Jb7gO2YWYl9tZYBfSzA0XjuybuuCeaCqck=";
// 支付宝公钥,查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应APPID下的支付宝公钥。
public static String alipay_public_key = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAi72K+GD45f4pSN+3tyPKUoMoKNTaTLUDABT4xHbBpIg7iSKW9YmiGo4QRxRZte5mJ0X5t6Az4ccLgmKagcc36Nsil7XUzpRTYc2SfPXlE1Hs2RsbmZoDxnT0Q/vR7/6BECYyYMUKZtnJRqZk7+yrdGtPrD3QXVwNZGntXL60+7pWg08quGOPyRhroeFi13nrYEOB6Mju0CXai6KMYNdk7UUFyDe9sz0TiMTVwK/313sS8PMVHXUin6ZpjHwVy4occ9cjrJ1dUoD6o9GF4K608y8PiINn56F9xFHK5uyMt54F6WXb1X7PlZdw29irt6T+2JB8bgsgOEosVvWHq532HwIDAQAB";
// 服务器异步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String notify_url = "http://localhost:8080/notify_url.jsp";
// 页面跳转同步通知页面路径 需http://格式的完整路径,不能加?id=123这类自定义参数,必须外网可以正常访问
public static String return_url = "http://localhost:8080/return_url.jsp";
// 签名方式
public static String sign_type = "RSA2";
// 字符编码格式
public static String charset = "utf-8";
// 支付宝网关
public static String gatewayUrl = "https://openapi-sandbox.dl.alipaydev.com/gateway.do";
}
项目引入支付
导入测试案例中的依赖包,将config配置文件,return_url.jsp,notify_url.jsp拷贝到商城项目中,以及将支付功能页面放到订单控制层,如下所示:
//阿里支付
public String pay(HttpServletRequest request, HttpServletResponse response) throws AlipayApiException, UnsupportedEncodingException {
//获得初始化的AlipayClient
AlipayClient alipayClient = new DefaultAlipayClient(AlipayConfig.gatewayUrl, AlipayConfig.app_id, AlipayConfig.merchant_private_key, "json", AlipayConfig.charset, AlipayConfig.alipay_public_key, AlipayConfig.sign_type);
//设置请求参数
AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
alipayRequest.setReturnUrl(AlipayConfig.return_url);
alipayRequest.setNotifyUrl(AlipayConfig.notify_url);
//商户订单号,商户网站订单系统中唯一订单号,必填
String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"),"UTF-8");
//付款金额,必填
String total_amount = new String(request.getParameter("WIDtotal_amount").getBytes("ISO-8859-1"),"UTF-8");
//订单名称,必填
String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"),"UTF-8");
//商品描述,可空
String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"),"UTF-8");
alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
+ "\"total_amount\":\""+ total_amount +"\","
+ "\"subject\":\""+ subject +"\","
+ "\"body\":\""+ body +"\","
+ "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//若想给BizContent增加其他可选请求参数,以增加自定义超时时间参数timeout_express来举例说明
//alipayRequest.setBizContent("{\"out_trade_no\":\""+ out_trade_no +"\","
// + "\"total_amount\":\""+ total_amount +"\","
// + "\"subject\":\""+ subject +"\","
// + "\"body\":\""+ body +"\","
// + "\"timeout_express\":\"10m\","
// + "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");
//请求参数可查阅【电脑网站支付的API文档-alipay.trade.page.pay-请求参数】章节
//请求
String result = alipayClient.pageExecute(alipayRequest).getBody();
return result;
}
在return_url.jsp文件中进行回调商城项目,并更改订单状态。
//根据订单号,在商城中改变订单状态,重定向到订单列表中
OrderService orderService = new OrderServiceImpl();
int res = orderService.updateOidState(out_trade_no); //修改状态
System.out.println("状态修改:"+res);
response.sendRedirect("order?action=show"); //跳到订单管理中
四、Git
介绍
在单人开发中,需要版本控制,方便进入不同的提交版本
多人开发中,需要版本控制,进行协同配合开发,及项目的整合
Git是一个分布式的版本控制系统(推荐),而svn则是集中式版本控制系统
Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。
git安装
下载git版本后,直接下一步安装。安装完成后,只需要DOS指令进行操作即可
git version #查看版本
#配置用户标记
git config --global user.name "lhp" #用户名
git config --global user.email "[email protected]" #邮箱 无需校验
# 查看信息
git config -l
#------本地库操作-----
#创建指定目录 例如d盘下的gitDemo,并进入目录中
git init #将gitDemo变为工作区,里面可存放文件
git add . #将工作区内容放到暂缓区
git commit -m "ont commit" #提交 将暂缓区内容放入版本库
git status #每一步操作都可使用该指令查看状态
远程仓库
目前较为常用的远程仓库有码云、github;推荐使用码云,服务器在国内,性能好,且中文版本
注册后,即可使用账户进行登录,并创建仓库,例如创建gitDemo仓库(建议和本地库名一致)
创建完成后,即可将客户端的提交点推送到远程仓库:
真实场景环境如下:
项目经理推送项目架构; 所有程序员克隆一份完整架构;然后程序员们进行更改后,即可推送到远端,其他程序员都可进行拉取或推送。
#关联远程仓库 标记名为origin
git remote add origin https://gitee.com/lihongping1015/git-demo.git
#查看关联的远程仓库内容
git remote -v
#推送内容到远程仓库 orign是链接标记 master是主分支(默认)
git push origin master
#另一个客户端即可克隆一份完整架构(第一次使用克隆,后面都是拉取)
git clone https://gitee.com/lihongping1015/git-demo.git
#同时也可提交并推送一份更改的内容
git push origin master
#其他用户也可拉取该提交内容
git pull origin master
五、总结与作业
总结
1.后端模块梳理
后台登录、展示用户信息,删除与搜索(搜索判断)、权限关联(过滤器)
2.订单详情
前端处理-查看订单详情页面需要的内容;后端处理-实体类加属性,DAO层关联查询
3.支付(重点)
根据支付文档下载demo,然后使用沙箱支付
通过测试案例来测试支付;完成后,再移到商城项目
4.git
介绍、git安装、远程仓库
作业
1. 请简述git本地仓库存文件的流程
2. 远程仓库的工作模式, 请描述清楚
4. 请描述支付宝的支付流程
晨考
6个git指令
git version
git config -l
git add .
git init
git commit -m "xx"
git remote add origin "路径"