SSH网上商城一
Java高级项目之SSH网上商城项目实战: 1、采用目前最主流的三大框架开发即Struts2+Spring+Hibernate框架整合开发.2、通过AJAX技术提供良好的用户体验.3、提供了邮箱激活的功能.4、提供了在线支付的功能.
第一课:用户模块需求分析
需求分析:
第二课:后台需求分析
第三课表与表之间的关系:
订单和商品是一对多的关系,需要引入中间表:
第六课:首页的转向:
通过用户在浏览器访问index.action跳转到web-inf目录下的jsp目录下的index.jsp页面
第7课:注册页面的跳转
在menu.jsp点击页面上的注册按钮:访问的是
<li id="headerRegister" class="headerRegister"
style="display: list-item;"><a href="${ pageContext.request.contextPath }/user_registPage.action">注册</a>|
</li>
对应的是user_registPage这个action
第八课:用户注册页面前台js的校验
在regist.jsp中进行校验
<form id="registerForm" action="${ pageContext.request.contextPath }/user_regist.action" method="post" novalidate="novalidate" onsubmit="return checkForm();">
function checkForm(){ // 校验用户名: // 获得用户名文本框的值: var username = document.getElementById("username").value; if(username == null || username == ''){ alert("用户名不能为空!"); return false; } // 校验密码: // 获得密码框的值: var password = document.getElementById("password").value; if(password == null || password == ''){ alert("密码不能为空!"); return false; } // 校验确认密码: var repassword = document.getElementById("repassword").value; if(repassword != password){ alert("两次密码输入不一致!"); return false; } }
第九课:用户名是否存在的校验
function checkUsername(){ // 获得文件框值: var username = document.getElementById("username").value; // 1.创建异步交互对象 var xhr = createXmlHttp(); // 2.设置监听 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ document.getElementById("span1").innerHTML = xhr.responseText; } } } // 3.打开连接 xhr.open("GET","${pageContext.request.contextPath}/user_findByName.action?time="+new Date().getTime()+"&username="+username,true); // 4.发送 xhr.send(null);
第10课:后台数据校验
参看博客:https://www.cnblogs.com/nayitian/p/3475661.html
使用validate()方法校验时,如果Web应用中存在大量Action就需要多次重写validate()方法,这使得代码非常繁琐。由于Struts2的校验框架本质上是基于XWork的validato框架,因此可以使用XWork的validator框架来对Struts2进行数据校验,以减少代码量。本文即讨论此种校验方式。
1. 前台页面加入错误提示标签(registerX.jsp)
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%>
<%@ page isELIgnored="false"%>
<%@ taglib uri="/struts-tags" prefix="s"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
</head>
<body>
<s:fielderror/>
<s:form action="registerX" method="post">
账号:<s:textfield name="username"></s:textfield>
<br/>
密码:<s:password name="password"></s:password>
<br/>
重复密码:<s:password name="repassword"></s:password>
<br/>
年龄:<s:textfield name="age"></s:textfield>
<br/>
身高:<s:textfield name="height"></s:textfield>
<br/>
<s:submit value="提交"></s:submit>
<br/>
</s:form>
</body>
</html>
2. 后台action继承ActionSupport(RegisterXAction.java)
package com.clzhang.ssh.demo1; import com.opensymphony.xwork2.ActionSupport; public class RegisterXAction extends ActionSupport { public static final long serialVersionUID = 1; private String username; private String password; private String repassword; private Integer age; private Double height; public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getRepassword() { return repassword; } public void setRepassword(String repassword) { this.repassword = repassword; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public Double getHeight() { return height; } public void setHeight(Double height) { this.height = height; } @Override public String execute() { System.out.println(username + "|" + age + "|" + height + " register finished!"); return "register"; } }
. 增加校验配置文件(RegisterXAction-validation.xml) 3.1 命名规范 校验文件命名规则:ActionName-validation.xml,其中ActionName就是需要校验的action的类名。 如果需要在Action中对某个特定的方法进行校验,则需要为此特定方法专门定义一个校验文件(否则,调用默认的)。该文件命名规则为:actionNme-methodNae-validation.xml;同时,还需要在struts.xml文件配置action时指定其method属性(否则,调用默认的)。 3.2 位置规范 该文件应该与action类的文件位于同一个路径下。 3.3 该文件的定义 参考:struts-2.3.x\lib\xwork-core-2.3.x.jar包中xwork-validator-1.0.x.dtd文件的描述。 3.4 该文件中validator的种类 参考:xwork-core-2.3.x.jar\com\opensymphony\xwork2\validator\validators中的default.xml文件。 3.5 进行数据校验遵循的步骤 Struts2框架中的类型转换器对HTTP请求的数据进行数据类型转换,得到符合类型的值,比如本例中age被转换为int。 使用Struts2的XWork校验框架进行校验,即根据actionName-validation.xml文件和actionName-methodName-validation.xml文件校验数据。 调用validateX()方法来进行数据校验。 调用validate()方法进行数据校验。 如果数据校验发生错误,就会返回名为input的result,进入指定的视图资源而不会调用本该被调用的业务逻辑处理方法。如果数据校验过程中未出现错误,则会调用相应Action中的业务逻辑处理方法。 3.6 配置校验文件的方式 Struts2框架提供了两种方式来配置校验文件,一种是字段校验配置方式;另一种是非字段校验配置方式。 字段校验方式(field-validator)
<!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.2//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.2.dtd"> <validators> <field name="username"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>请输入用户名</message> </field-validator> <field-validator type="stringlength"> <param name="minLength">2</param> <param name="maxLength">16</param> <message>用户名长度在${minLength}到${maxLength}位之间!</message> </field-validator> </field> <field name="password"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>请输入密码</message> </field-validator> <field-validator type="regex"> <param name="expression"><![CDATA[\w{6,12}]]></param> <message>密码必须在6-12位之间,且只能为字母和数字</message> </field-validator> </field> <field name="repassword"> <field-validator type="requiredstring"> <param name="trim">true</param> <message>请输入确认密码</message> </field-validator> <field-validator type="fieldexpression"> <param name="expression"><![CDATA[repassword==password]]></param> <!--这里也可以用repassword.equals(password)//--> <message>两次密码不相等</message> </field-validator> </field> <field name="age"> <field-validator type="required"> <param name="trim">true</param> <message>年龄不能为空!</message> </field-validator> <field-validator type="int"> <param name="min">1</param> <param name="max">60</param> <message>年龄取值范围在${min}到${max}之间</message> </field-validator> </field> <field name="height"> <field-validator type="double"> <param name="min">1.10</param> <param name="max">2.10</param> <message>身高取值范围在${min}到${max}米之间</message> </field-validator> </field> </validators>
非字段校验方式(non-fild validator),下面这个只是个示范,非本例所用。
3.7 校验器简介
- required校验器,要求字段非空;
- requiredstring校验器,要求字段值非空且长度大于0;
- int校验器,表示整数,可以通过min/max参数指定范围;
- date校验器,要求日期,可以通过min/max参数指定范围;
- email校验器,要求电子邮件格式;
- stringlength校验器,通过minLength/maxLength参数指定字段长度范围。
4. 在struts.xml文件中配置错误返回页面地址
<action name="registerX" class="com.clzhang.ssh.demo1.RegisterXAction">
<result name="register">/ssh/demo1/success.jsp</result>
<result name="input">/ssh/demo1/registerX.jsp</result>
</action>
5. 测试
打开IE,输入地址:http://127.0.0.1:8080/st/ssh/demo1/registerX.jsp
结果如下:
直接提交,结果如下:
第12课:邮件发送的流程
第十三课:邮件服务器的安装
用户模块的相关所以的代码:
我们来看下
首先是配置文件struct.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN"
"http://struts.apache.org/dtds/struts-2.0.dtd">
<struts>
<package name="shop" extends="struts-default" namespace="/" >
<global-results>
<result name="msg">/WEB-INF/jsp/msg.jsp</result>
</global-results>
<!-- 配置首页访问的Action -->
<action name="index" class="indexAction">
<result name="index">/WEB-INF/jsp/index.jsp</result>
</action>
<!-- 配置跳转到注册页面的action -->
<action name="user_*" class="userAction" method="{1}">
<result name="registPage">/WEB-INF/jsp/regist.jsp</result>
<result name="input">/WEB-INF/jsp/regist.jsp</result>
<result name="loginPage">/WEB-INF/jsp/login.jsp</result>
<result name="login">/WEB-INF/jsp/login.jsp</result>
<!-- 登陆成功,重定向到index这个action,这个action再跳转到首页 -->
<result name="loginSuccess" type="redirectAction">index</result>
<!-- 退出登陆成功,重定向到index这个action,这个action再跳转到首页 -->
<result name="quit" type="redirectAction">index</result>
<!-- 验证码输入错误,重新跳转到注册页面 -->
<result name="checkcodeError">/WEB-INF/jsp/regist.jsp</result>
</action>
<action name="checkImg" class="checkImg"></action>
<!-- 商品模块的Action -->
<action name="product_*" class="productAction" method="{1}">
<result name="findByPid">/WEB-INF/jsp/product.jsp</result>
<result name="findByCid">/WEB-INF/jsp/productList.jsp</result>
</action>
</package>
</struts>
其次是action的代码:
package cn.itcast.shop.user.action; import java.io.IOException; import javax.servlet.http.HttpServletResponse; import org.apache.struts2.ServletActionContext; import cn.itcast.shop.user.beans.User; import cn.itcast.shop.user.service.UserService; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.ModelDriven; public class UserAction extends ActionSupport implements ModelDriven<User>{ private User user = new User(); private UserService userService; private String checkcode; public String getCheckcode() { return checkcode; } public void setCheckcode(String checkcode) { this.checkcode = checkcode; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } public UserService getUserService() { return userService; } public void setUserService(UserService userService) { this.userService = userService; } /** * 跳转到注册页面的执行方法 */ public String registPage() { System.out.println("registPage is called"); return "registPage"; } /** * AJAX进行异步校验用户名的执行方法 * * @throws IOException */ public String findByName() throws IOException { // 调用Service进行查询: System.out.println("findByName is called"); String userName = (String) ServletActionContext.getRequest().getAttribute("username"); System.out.println("userName1:"+userName); System.out.println("userName11:"+ user.getUsername()); User existUser = userService.findByUsername(user.getUsername()); // 获得response对象,项页面输出: HttpServletResponse response = ServletActionContext.getResponse(); response.setContentType("text/html;charset=UTF-8"); // 判断 if (existUser != null) { // 查询到该用户:用户名已经存在 response.getWriter().println("<font color='red'>用户名已经存在</font>"); } else { // 没查询到该用户:用户名可以使用 response.getWriter().println("<font color='green'>用户名可以使用</font>"); } return NONE; } @Override public User getModel() { // TODO Auto-generated method stub return user; } /** * 用户注册的方法: */ public String regist() throws IOException{ //判断验证码是正确 String exitcheckcode = (String) ServletActionContext.getRequest().getSession().getAttribute("checkcode"); if(!checkcode.equalsIgnoreCase(exitcheckcode)){ //用户验证码输入错误,重新跳转到注册页面 this.addActionError("验证码输入不正确"); return "checkcodeError"; } //保存数据到数据库中 userService.save(user); //使用struct标签添加信息 addActionMessage("用户注册成功,请到邮箱进行激活"); return "msg"; } /** * 用户激活的方法: */ public String active() throws IOException{ //依据激活码去查询用户是否存在 String code = user.getCode(); System.out.println("code:"+code); User exitUser = userService.findByCode(code); if(exitUser == null){ //激活失败,用户不存在 this.addActionMessage("激活失败,用户不存在"); return "msg"; }else{ //激活成功修改用户的状态 exitUser.setState(1); exitUser.setCode(null); userService.update(exitUser); this.addActionMessage("激活成功,请登录"); return "msg"; } } /* * 跳转到用户登录页面loginPage * */ public String loginPage() throws IOException{ return "loginPage"; } /* * 用户登录login * */ public String login() throws IOException{ //到数据库去查询用户是否存在 System.out.println("login() is called"); User exitUser = userService.findByUser(user); if(exitUser == null){ //用户不存在,跳转到登陆页面提示 addActionError("用户不存在,用户名或者密码不正确"); System.out.println("用户不存在,用户名或者密码不正确"); return "login"; }else{ //用户存在将用户保存到session中 System.out.println("用户登陆成功"); ServletActionContext.getRequest().getSession().setAttribute("existUser", exitUser); //重定义到页面 // 页面跳转 return "loginSuccess"; } } /* * 用户退出的功能 * */ public String quit() throws IOException{ //将session设置成无效 ServletActionContext.getRequest().getSession().invalidate(); return "quit"; } }
UserAction-user_regist-validation.xml的代码:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE validators PUBLIC "-//Apache Struts//XWork Validator 1.0.3//EN" "http://struts.apache.org/dtds/xwork-validator-1.0.3.dtd"> <validators> <!-- 校验用户名 --> <field name="username"> <field-validator type="requiredstring"> <message>用户名不能为空!</message> </field-validator> </field> <!-- 校验用户名 --> <field name="password"> <field-validator type="requiredstring"> <message>密码不能为空!</message> </field-validator> </field> <!-- 校验用户名 --> <field name="name"> <field-validator type="requiredstring"> <message>姓名不能为空!</message> </field-validator> </field> <!-- 校验用户名 --> <field name="addr"> <field-validator type="requiredstring"> <message>地址不能为空!</message> </field-validator> </field> <!-- 校验邮箱 --> <field name="email"> <field-validator type="email"> <message>邮箱格式不正确!</message> </field-validator> </field> </validators>
4 、访问验证码的action
package cn.itcast.shop.user.action; import java.awt.Color; import java.awt.Font; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.image.BufferedImage; import java.util.Random; import javax.imageio.ImageIO; import org.apache.struts2.ServletActionContext; import com.opensymphony.xwork2.ActionSupport; /** * 验证码Action类现象验证码的action,客户端就是通过访问这个action来获得请求的验证码 * * @author 传智.郭嘉 * */ public class CheckImgAction extends ActionSupport { @Override public String execute() throws Exception { int width = 120; int height = 30; // 步骤一 绘制一张内存中图片 BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); // 步骤二 图片绘制背景颜色 ---通过绘图对象 Graphics graphics = bufferedImage.getGraphics();// 得到画图对象 --- 画笔 // 绘制任何图形之前 都必须指定一个颜色 graphics.setColor(getRandColor(200, 250)); graphics.fillRect(0, 0, width, height); // 步骤三 绘制边框 graphics.setColor(Color.WHITE); graphics.drawRect(0, 0, width - 1, height - 1); // 步骤四 四个随机数字 Graphics2D graphics2d = (Graphics2D) graphics; // 设置输出字体 graphics2d.setFont(new Font("宋体", Font.BOLD, 18)); String words = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890"; // String words = // "\u7684\u4e00\u4e86\u662f\u6211\u4e0d\u5728\u4eba\u4eec\u6709\u6765\u4ed6\u8fd9\u4e0a\u7740\u4e2a\u5730\u5230\u5927\u91cc\u8bf4\u5c31\u53bb\u5b50\u5f97\u4e5f\u548c\u90a3\u8981\u4e0b\u770b\u5929\u65f6\u8fc7\u51fa\u5c0f\u4e48\u8d77\u4f60\u90fd\u628a\u597d\u8fd8\u591a\u6ca1\u4e3a\u53c8\u53ef\u5bb6\u5b66\u53ea\u4ee5\u4e3b\u4f1a\u6837\u5e74\u60f3\u751f\u540c\u8001\u4e2d\u5341\u4ece\u81ea\u9762\u524d\u5934\u9053\u5b83\u540e\u7136\u8d70\u5f88\u50cf\u89c1\u4e24\u7528\u5979\u56fd\u52a8\u8fdb\u6210\u56de\u4ec0\u8fb9\u4f5c\u5bf9\u5f00\u800c\u5df1\u4e9b\u73b0\u5c71\u6c11\u5019\u7ecf\u53d1\u5de5\u5411\u4e8b\u547d\u7ed9\u957f\u6c34\u51e0\u4e49\u4e09\u58f0\u4e8e\u9ad8\u624b\u77e5\u7406\u773c\u5fd7\u70b9\u5fc3\u6218\u4e8c\u95ee\u4f46\u8eab\u65b9\u5b9e\u5403\u505a\u53eb\u5f53\u4f4f\u542c\u9769\u6253\u5462\u771f\u5168\u624d\u56db\u5df2\u6240\u654c\u4e4b\u6700\u5149\u4ea7\u60c5\u8def\u5206\u603b\u6761\u767d\u8bdd\u4e1c\u5e2d\u6b21\u4eb2\u5982\u88ab\u82b1\u53e3\u653e\u513f\u5e38\u6c14\u4e94\u7b2c\u4f7f\u5199\u519b\u5427\u6587\u8fd0\u518d\u679c\u600e\u5b9a\u8bb8\u5feb\u660e\u884c\u56e0\u522b\u98de\u5916\u6811\u7269\u6d3b\u90e8\u95e8\u65e0\u5f80\u8239\u671b\u65b0\u5e26\u961f\u5148\u529b\u5b8c\u5374\u7ad9\u4ee3\u5458\u673a\u66f4\u4e5d\u60a8\u6bcf\u98ce\u7ea7\u8ddf\u7b11\u554a\u5b69\u4e07\u5c11\u76f4\u610f\u591c\u6bd4\u9636\u8fde\u8f66\u91cd\u4fbf\u6597\u9a6c\u54ea\u5316\u592a\u6307\u53d8\u793e\u4f3c\u58eb\u8005\u5e72\u77f3\u6ee1\u65e5\u51b3\u767e\u539f\u62ff\u7fa4\u7a76\u5404\u516d\u672c\u601d\u89e3\u7acb\u6cb3\u6751\u516b\u96be\u65e9\u8bba\u5417\u6839\u5171\u8ba9\u76f8\u7814\u4eca\u5176\u4e66\u5750\u63a5\u5e94\u5173\u4fe1\u89c9\u6b65\u53cd\u5904\u8bb0\u5c06\u5343\u627e\u4e89\u9886\u6216\u5e08\u7ed3\u5757\u8dd1\u8c01\u8349\u8d8a\u5b57\u52a0\u811a\u7d27\u7231\u7b49\u4e60\u9635\u6015\u6708\u9752\u534a\u706b\u6cd5\u9898\u5efa\u8d76\u4f4d\u5531\u6d77\u4e03\u5973\u4efb\u4ef6\u611f\u51c6\u5f20\u56e2\u5c4b\u79bb\u8272\u8138\u7247\u79d1\u5012\u775b\u5229\u4e16\u521a\u4e14\u7531\u9001\u5207\u661f\u5bfc\u665a\u8868\u591f\u6574\u8ba4\u54cd\u96ea\u6d41\u672a\u573a\u8be5\u5e76\u5e95\u6df1\u523b\u5e73\u4f1f\u5fd9\u63d0\u786e\u8fd1\u4eae\u8f7b\u8bb2\u519c\u53e4\u9ed1\u544a\u754c\u62c9\u540d\u5440\u571f\u6e05\u9633\u7167\u529e\u53f2\u6539\u5386\u8f6c\u753b\u9020\u5634\u6b64\u6cbb\u5317\u5fc5\u670d\u96e8\u7a7f\u5185\u8bc6\u9a8c\u4f20\u4e1a\u83dc\u722c\u7761\u5174\u5f62\u91cf\u54b1\u89c2\u82e6\u4f53\u4f17\u901a\u51b2\u5408\u7834\u53cb\u5ea6\u672f\u996d\u516c\u65c1\u623f\u6781\u5357\u67aa\u8bfb\u6c99\u5c81\u7ebf\u91ce\u575a\u7a7a\u6536\u7b97\u81f3\u653f\u57ce\u52b3\u843d\u94b1\u7279\u56f4\u5f1f\u80dc\u6559\u70ed\u5c55\u5305\u6b4c\u7c7b\u6e10\u5f3a\u6570\u4e61\u547c\u6027\u97f3\u7b54\u54e5\u9645\u65e7\u795e\u5ea7\u7ae0\u5e2e\u5566\u53d7\u7cfb\u4ee4\u8df3\u975e\u4f55\u725b\u53d6\u5165\u5cb8\u6562\u6389\u5ffd\u79cd\u88c5\u9876\u6025\u6797\u505c\u606f\u53e5\u533a\u8863\u822c\u62a5\u53f6\u538b\u6162\u53d4\u80cc\u7ec6"; Random random = new Random();// 生成随机数 // 定义StringBuffer StringBuffer sb = new StringBuffer(); // 定义x坐标 int x = 10; for (int i = 0; i < 4; i++) { // 随机颜色 graphics2d.setColor(new Color(20 + random.nextInt(110), 20 + random .nextInt(110), 20 + random.nextInt(110))); // 旋转 -30 --- 30度 int jiaodu = random.nextInt(60) - 30; // 换算弧度 double theta = jiaodu * Math.PI / 180; // 生成一个随机数字 int index = random.nextInt(words.length()); // 生成随机数 0 到 length - 1 // 获得字母数字 char c = words.charAt(index); sb.append(c); // 将c 输出到图片 graphics2d.rotate(theta, x, 20); graphics2d.drawString(String.valueOf(c), x, 20); graphics2d.rotate(-theta, x, 20); x += 30; } // 将生成的字母存入到session中 ServletActionContext.getRequest().getSession() .setAttribute("checkcode", sb.toString()); // 步骤五 绘制干扰线 graphics.setColor(getRandColor(160, 200)); int x1; int x2; int y1; int y2; for (int i = 0; i < 30; i++) { x1 = random.nextInt(width); x2 = random.nextInt(12); y1 = random.nextInt(height); y2 = random.nextInt(12); graphics.drawLine(x1, y1, x1 + x2, x2 + y2); } // 将上面图片输出到浏览器 ImageIO graphics.dispose();// 释放资源 ImageIO.write(bufferedImage, "jpg", ServletActionContext.getResponse() .getOutputStream()); return NONE; } /** * 取其某一范围的color * * @param fc * int 范围参数1 * @param bc * int 范围参数2 * @return Color */ private Color getRandColor(int fc, int bc) { // 取其随机颜色 Random random = new Random(); if (fc > 255) { fc = 255; } if (bc > 255) { bc = 255; } int r = fc + random.nextInt(bc - fc); int g = fc + random.nextInt(bc - fc); int b = fc + random.nextInt(bc - fc); return new Color(r, g, b); } }
注意excute方法的返回值是NONE
package cn.itcast.shop.user.service; import cn.itcast.shop.user.beans.User; import cn.itcast.shop.user.dao.UserDao; import cn.itcast.shop.user.utils.MailUitls; import cn.itcast.shop.user.utils.UUIDUtils; public class UserService { private UserDao userDao; public UserDao getUserDao() { return userDao; } public void setUserDao(UserDao userDao) { this.userDao = userDao; } // 按用户名查询用户的方法: public User findByUsername(String username){ return userDao.findByUsername(username); } public void save(User user) { // TODO Auto-generated method stub //默认设置未激活状态 user.setState(0); String code = UUIDUtils.getUUID()+UUIDUtils.getUUID(); user.setCode(code); System.out.println("user is:"+user.toString()); userDao.save(user); //发送邮件 MailUitls.sendMail(user.getEmail(), code); } public User findByCode(String code) { // TODO Auto-generated method stub User exitUser = userDao.findByCode(code); return exitUser; } public void update(User exitUser) { // TODO Auto-generated method stub userDao.update(exitUser); } public User findByUser(User user) { // TODO Auto-generated method stub User exitUser = userDao.findByUser(user); return exitUser; } }
dao层的代码:
package cn.itcast.shop.user.dao; import java.util.List; import org.springframework.orm.hibernate3.support.HibernateDaoSupport; import cn.itcast.shop.user.beans.User; public class UserDao extends HibernateDaoSupport{ // 按名字查询是否有该用户: public User findByUsername(String username) { String hql = "from User where username = ?"; List<User> list = this.getHibernateTemplate().find(hql, username); if (list != null && list.size() > 0) { return list.get(0); } return null; } public void save(User user) { // TODO Auto-generated method stub this.getHibernateTemplate().save(user); } public User findByCode(String code) { String hql = "from User where code = ?"; List<User> list = this.getHibernateTemplate().find(hql, code); if (list != null && list.size() > 0) { return list.get(0); } return null; } public void update(User exitUser) { // TODO Auto-generated method stub this.getHibernateTemplate().update(exitUser); } public User findByUser(User user) { // TODO Auto-generated method stub user.setState(1); List<User> list = this.getHibernateTemplate().findByExample(user); if (list != null && list.size() > 0) { return list.get(0); } return null; } }
业务bean的代码:
业务bean对应的数据库的名称是
CREATE TABLE `user` ( `uid` int(11) NOT NULL auto_increment, `username` varchar(255) default NULL, `password` varchar(255) default NULL, `name` varchar(255) default NULL, `email` varchar(255) default NULL, `phone` varchar(255) default NULL, `addr` varchar(255) default NULL, `state` int(11) default NULL, `code` varchar(64) default NULL, PRIMARY KEY (`uid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
package cn.itcast.shop.user.beans; public class User { @Override public String toString() { return "User [uid=" + uid + ", username=" + username + ", password=" + password + ", name=" + name + ", email=" + email + ", phone=" + phone + ", addr=" + addr + ", state=" + state + ", code=" + code + "]"; } private Integer uid; private String username; private String password; private String name; private String email; private String phone; private String addr; private Integer state; private String code; public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } public String getAddr() { return addr; } public void setAddr(String addr) { this.addr = addr; } public Integer getState() { return state; } public void setState(Integer state) { this.state = state; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } }
对应的xml文件为:
User.hbm.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="cn.itcast.shop.user.beans.User" table="user"> <id name="uid"> <generator class="native"/> </id> <property name="username"/> <property name="password"/> <property name="name"/> <property name="email"/> <property name="phone"/> <property name="addr"/> <property name="state"/> <property name="code"/> </class> </hibernate-mapping>
该文件需要在hibernate.cfg.xml中进行引入
上面的这些配置文件都在src目录下,我们来看看各个配置文件的内容
hibernate.cfg.xml
<!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/shop</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">123456</property> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <mapping resource="/cn/itcast/shop/user/beans/User.hbm.xml"/> <mapping resource="/cn/itcast/shop/category/beans/Category.hbm.xml"/> <mapping resource="/cn/itcast/shop/product/beans/Product.hbm.xml"/> <mapping resource="/cn/itcast/shop/categorysecond/beans/CategorySecond.hbm.xml"/> </session-factory> </hibernate-configuration>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <import resource="applicationContext-common.xml"/> <import resource="applicationContext-dao.xml"/> <import resource="applicationContext-service.xml"/> <import resource="applicationContext-action.xml"/> </beans>
spring主要通过xml的方式对对象的生命周期进行管理,在applicationContext.xml中引入
applicationContext-common.xml 等几个文件,分别对serive对象 action 对象 dao对象进行声明周期管理 ,common对象对普通的对象进行管理
applicationContext-common.xml文件主要是对spring集成hibernate,已经spring配置事务管理都在这个xml文件中进行配置
applicationContext-common.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 配置SessionFactory --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="configLocation" value="classpath:hibernate.cfg.xml"/> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory"/> </bean> <!-- 配置事务的传播特性(配置Advice) --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="del*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="save*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="*" propagation="REQUIRED" read-only="true"/> </tx:attributes> </tx:advice> <!-- 配置哪些类的哪些方法使用事务(配置事务边界,配置Pointcut) --> <aop:config> <aop:pointcut id="allManagerMethod" expression="execution(* cn.itcast.shop.user.service.*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethod" advice-ref="txAdvice"/> </aop:config> <!-- 配置哪些类的哪些方法使用事务(配置事务边界,配置Pointcut) --> <aop:config> <aop:pointcut id="allManagerMethod1" expression="execution(* cn.itcast.shop.category.service.*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethod1" advice-ref="txAdvice"/> </aop:config> <!-- 配置哪些类的哪些方法使用事务(配置事务边界,配置Pointcut) --> <aop:config> <aop:pointcut id="allManagerMethod2" expression="execution(* cn.itcast.shop.product.service.*.*(..))"/> <aop:advisor pointcut-ref="allManagerMethod2" advice-ref="txAdvice"/> </aop:config> </beans>
applicationContext-action.xml主要对action对象的生命周期进行管理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 为了保证一个action对应一个线程,这里必须要配置scope="prototype" --> <!-- 跳转到用户首页的action --> <bean id="indexAction" class="cn.itcast.shop.index.action.IndexAction" scope="prototype"> <property name="categoryService" ref="categoryService"></property> <property name="productService" ref="productService"></property> </bean> <bean id="userAction" class = "cn.itcast.shop.user.action.UserAction" scope="prototype"> <property name="userService" ref="userService"></property> </bean> <!-- 用于获得验证码的action进行验证 --> <bean id = "checkImg" class = "cn.itcast.shop.user.action.CheckImgAction" scope="prototype"></bean> <bean id="productAction" class = "cn.itcast.shop.product.action.ProductAction" scope="prototype"> <property name="productService" ref="productService"></property> <property name="categoryService" ref="categoryService"></property> </bean> </beans>
applicationContext-service.xml主要对业务层的声明周期进行管理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="userService" class="cn.itcast.shop.user.service.UserService"> <property name="userDao" ref="userDao"/> </bean> <bean id="categoryService" class="cn.itcast.shop.category.service.CategoryService"> <property name="categoryDao" ref="categoryDao"/> </bean> <bean id="productService" class="cn.itcast.shop.product.service.ProductService"> <property name="productDao" ref="productDao"/> </bean> </beans>
applicationContext-dao.xml主要对数据库操作的对象的生命周期进行管理
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <bean id="userService" class="cn.itcast.shop.user.service.UserService"> <property name="userDao" ref="userDao"/> </bean> <bean id="categoryService" class="cn.itcast.shop.category.service.CategoryService"> <property name="categoryDao" ref="categoryDao"/> </bean> <bean id="productService" class="cn.itcast.shop.product.service.ProductService"> <property name="productDao" ref="productDao"/> </bean> </beans>
接下面我们看看在web项目中如何管理上面的配置文件
找到项目的web.xml文件
web.xml的内容如下所示:
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0"> <display-name>SSH_01</display-name> <!-- 需要配置在struct2的OpenSessionInView要放在struts2的过滤器的前面 --> <filter> <filter-name>OpenSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>OpenSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- 配置spring的配置文件 --> <context-param> <param-name>contextConfigLocation</param-name> <!-- <param-value>classpath:applicationContext-*.xml</param-value> --> <param-value>classpath:applicationContext.xml</param-value> </context-param> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> </web-app>
在该xml中配置web项目集成spring 、web项目集成struct2都在web.xml中进行配置
我们来看对应的jsp的页面
首页index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>传智商城</title> <link href="${pageContext.request.contextPath}/css/slider.css" rel="stylesheet" type="text/css"/> <link href="${pageContext.request.contextPath}/css/common.css" rel="stylesheet" type="text/css"/> <link href="${pageContext.request.contextPath}/css/index.css" rel="stylesheet" type="text/css"/> </head> <body> <div class="container header"> <div class="span5"> <div class="logo"> <a href="./网上商城/index.htm"> <img src="${pageContext.request.contextPath}/image/r___________renleipic_01/logo.gif" alt="传智播客"/> </a> </div> </div> <div class="span9"> <div class="headerAd"> <img src="${pageContext.request.contextPath}/image/header.jpg" width="320" height="50" alt="正品保障" title="正品保障"/> </div> </div> <%@ include file="menu.jsp" %> </div> <div class="container index"> <div class="span24"> <div id="hotProduct" class="hotProduct clearfix"> <div class="title"> <strong>热门商品</strong> <!-- <a target="_blank"></a> --> </div> <ul class="tab"> <li class="current"> <a href="./蔬菜分类.htm?tagIds=1" target="_blank"></a> </li> <li> <a target="_blank"></a> </li> <li> <a target="_blank"></a> </li> </ul> <!-- <div class="hotProductAd"> <img src="${pageContext.request.contextPath}/image/a.jpg" width="260" height="343" alt="热门商品" title="热门商品"> </div> --> <ul class="tabContent" style="display: block;"> <s:iterator var="p" value="hList"> <li> <a href="${ pageContext.request.contextPath }/product_findByPid.action?pid=<s:property value="#p.pid"/>" target="_blank"><img src="${pageContext.request.contextPath}/<s:property value="#p.image"/>" data-original="http://storage.shopxx.net/demo-image/3.0/201301/0ff130db-0a1b-4b8d-a918-ed9016317009-thumbnail.jpg" style="display: block;"></a> </li> </s:iterator> </ul> <ul class="tabContent" style="display: none;"> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/c5b1b396-181a-4805-9e68-9b400d71f91e-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/c5b1b396-181a-4805-9e68-9b400d71f91e-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/4107e1ce-5e7c-4941-bc0f-718f35ba14cd-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/4107e1ce-5e7c-4941-bc0f-718f35ba14cd-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/6f8ae4bf-cbd3-41c7-aa22-0fe81db6add4-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/6f8ae4bf-cbd3-41c7-aa22-0fe81db6add4-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/3d835c07-08c5-46d7-912d-adcd41f8c8e6-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/3d835c07-08c5-46d7-912d-adcd41f8c8e6-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/5e5be432-fbee-4bdd-a7bd-a92e01f9bfc4-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/5e5be432-fbee-4bdd-a7bd-a92e01f9bfc4-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/cae1bc6b-0159-4ce0-9a9c-4926df231b4f-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/cae1bc6b-0159-4ce0-9a9c-4926df231b4f-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/40e34b2d-d240-446e-9874-89969edbe89f-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/40e34b2d-d240-446e-9874-89969edbe89f-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/a8db4410-05e5-4dfa-8217-eb885a104af3-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/a8db4410-05e5-4dfa-8217-eb885a104af3-thumbnail.jpg" style="display: block;"></a> </li> </ul> <ul class="tabContent" style="display: none;"> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/9f164e13-bcaa-48a6-9b35-0ca96629f614-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/9f164e13-bcaa-48a6-9b35-0ca96629f614-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/c41d0347-364c-42bb-baeb-25142c1ed167-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/c41d0347-364c-42bb-baeb-25142c1ed167-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/2af8be8a-75b9-41ae-b009-a7c54b685a4e-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/2af8be8a-75b9-41ae-b009-a7c54b685a4e-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/1a3ad7de-7ee9-4530-b89a-46375219beb5-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/1a3ad7de-7ee9-4530-b89a-46375219beb5-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/ea566af4-0cdb-4017-a8c7-27e407794204-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/ea566af4-0cdb-4017-a8c7-27e407794204-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/dea31d42-fa3e-4b69-a631-51ca7c79f032-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/dea31d42-fa3e-4b69-a631-51ca7c79f032-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/1c81f492-a3d7-4c06-8658-bc2c76808cd3-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/1c81f492-a3d7-4c06-8658-bc2c76808cd3-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/f1174ca6-6bdf-4d0b-86e6-5455bc8e89ad-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/f1174ca6-6bdf-4d0b-86e6-5455bc8e89ad-thumbnail.jpg" style="display: block;"></a> </li> </ul> </div> </div> <div class="span24"> <div id="newProduct" class="newProduct clearfix"> <div class="title"> <strong>最新商品</strong> <a target="_blank"></a> </div> <ul class="tab"> <li class="current"> <a href="./蔬菜分类.htm?tagIds=2" target="_blank"></a> </li> <li> <a target="_blank"></a> </li> <li> <a target="_blank"></a> </li> </ul> <!-- <div class="newProductAd"> <img src="${pageContext.request.contextPath}/image/q.jpg" width="260" height="343" alt="最新商品" title="最新商品"> </div> --> <ul class="tabContent" style="display: block;"> <s:iterator var="p" value="nList"> <li> <a href="${ pageContext.request.contextPath }/product_findByPid.action?pid=<s:property value="#p.pid"/>" target="_blank"><img src="${pageContext.request.contextPath}/<s:property value="#p.image"/>" data-original="http://storage.shopxx.net/demo-image/3.0/201301/4a51167a-89d5-4710-aca2-7c76edc355b8-thumbnail.jpg" style="display: block;"></a> </li> </li> </s:iterator> </ul> <ul class="tabContent" style="display: none;"> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/b04a22f5-267d-4e33-ac58-dda941eeaf84-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/b04a22f5-267d-4e33-ac58-dda941eeaf84-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/ca3043f5-dbb0-4a03-9bb6-8274f78b5d7e-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/ca3043f5-dbb0-4a03-9bb6-8274f78b5d7e-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/a2ac0816-37e4-477a-b179-e64f71252cf5-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/a2ac0816-37e4-477a-b179-e64f71252cf5-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/fbb80ec8-a1d3-49de-b83b-79eae4b1ff69-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/fbb80ec8-a1d3-49de-b83b-79eae4b1ff69-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/bb99deac-0b33-48f1-a3ad-e8310516be07-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/bb99deac-0b33-48f1-a3ad-e8310516be07-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/7b3c0647-1016-4d13-8b84-4d63818e1179-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/7b3c0647-1016-4d13-8b84-4d63818e1179-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/3c79f82f-f136-48aa-9e81-7e10fbb3de2a-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/3c79f82f-f136-48aa-9e81-7e10fbb3de2a-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/b998f840-91fc-41b6-b73d-70587babf760-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/b998f840-91fc-41b6-b73d-70587babf760-thumbnail.jpg" style="display: block;"></a> </li> </ul> <ul class="tabContent" style="display: none;"> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/9f164e13-bcaa-48a6-9b35-0ca96629f614-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/9f164e13-bcaa-48a6-9b35-0ca96629f614-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/1a3ad7de-7ee9-4530-b89a-46375219beb5-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/1a3ad7de-7ee9-4530-b89a-46375219beb5-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/7acae4ac-5909-4142-8b20-19c5462859d6-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/7acae4ac-5909-4142-8b20-19c5462859d6-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/ea566af4-0cdb-4017-a8c7-27e407794204-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/ea566af4-0cdb-4017-a8c7-27e407794204-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/dea31d42-fa3e-4b69-a631-51ca7c79f032-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/dea31d42-fa3e-4b69-a631-51ca7c79f032-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/1c81f492-a3d7-4c06-8658-bc2c76808cd3-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/1c81f492-a3d7-4c06-8658-bc2c76808cd3-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/f1174ca6-6bdf-4d0b-86e6-5455bc8e89ad-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/f1174ca6-6bdf-4d0b-86e6-5455bc8e89ad-thumbnail.jpg" style="display: block;"></a> </li> <li> <a target="_blank"><img src="./Mango商城 - Powered By Mango Team_files/2971c96e-9f11-4491-9faf-9ea7e1fec53c-thumbnail.jpg" data-original="http://storage.shopxx.net/demo-image/3.0/201301/2971c96e-9f11-4491-9faf-9ea7e1fec53c-thumbnail.jpg" style="display: block;"></a> </li> </ul> </div> </div> <div class="span24"> <div class="friendLink"> <dl> <dt>新手指南</dt> <dd> <a target="_blank">支付方式</a> | </dd> <dd> <a target="_blank">配送方式</a> | </dd> <dd> <a target="_blank">售后服务</a> | </dd> <dd> <a target="_blank">购物帮助</a> | </dd> <dd> <a target="_blank">蔬菜卡</a> | </dd> <dd> <a target="_blank">礼品卡</a> | </dd> <dd> <a target="_blank">银联卡</a> | </dd> <dd> <a target="_blank">亿家卡</a> | </dd> <dd class="more"> <a >更多</a> </dd> </dl> </div> </div> </div> <div class="container footer"> <div class="span24"> <div class="footerAd"> <img src="${pageContext.request.contextPath}/image/footer.jpg" width="950" height="52" alt="我们的优势" title="我们的优势"> </div> </div> <div class="span24"> <ul class="bottomNav"> <li> <a>关于我们</a> | </li> <li> <a>联系我们</a> | </li> <li> <a>招贤纳士</a> | </li> <li> <a>法律声明</a> | </li> <li> <a>友情链接</a> | </li> <li> <a target="_blank">支付方式</a> | </li> <li> <a target="_blank">配送方式</a> | </li> <li> <a>服务声明</a> | </li> <li> <a>广告声明</a> </li> </ul> </div> <div class="span24"> <div class="copyright">Copyright © 2005-2015 网上商城 版权所有</div> </div> </div> </body> </html>
menu.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <div class="span10 last"> <div class="topNav clearfix"> <ul> <s:if test="#session.existUser == null"> <li id="headerLogin" class="headerLogin" style="display: list-item;"> <a href="${ pageContext.request.contextPath }/user_loginPage.action">登录</a>|</li> <li id="headerRegister" class="headerRegister" style="display: list-item;"><a href="${ pageContext.request.contextPath }/user_registPage.action">注册</a>| </li> </s:if> <s:else> <li id="headerLogin" class="headerLogin" style="display: list-item;"> <s:property value="#session.existUser.name"/> |</li> <li id="headerLogin" class="headerLogin" style="display: list-item;"> <a href="${ pageContext.request.contextPath }/order_findByUid.action?page=1">我的订单</a> |</li> <li id="headerRegister" class="headerRegister" style="display: list-item;"><a href="${ pageContext.request.contextPath }/user_quit.action">退出</a>| </li> </s:else> <li><a>会员中心</a> |</li> <li><a>购物指南</a> |</li> <li><a>关于我们</a></li> </ul> </div> <div class="cart"> <a href="${ pageContext.request.contextPath }/cart_myCart.action">购物车</a> </div> <div class="phone"> 客服热线: <strong>96008/53277764</strong> </div> </div> <div class="span24"> <ul class="mainNav"> <li><a href="${ pageContext.request.contextPath }/index.action">首页</a> |</li> <s:iterator var="c" value="#session.cList"> <li><a href="${ pageContext.request.contextPath }/product_findByCid.action?cid=<s:property value="#c.cid"/>&page=1"><s:property value="#c.cname"/></a> |</li> </s:iterator> </ul> </div>
regist.jsp注册页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>会员注册</title> <link href="${pageContext.request.contextPath}/css/common.css" rel="stylesheet" type="text/css"/> <link href="${pageContext.request.contextPath}/css/register.css" rel="stylesheet" type="text/css"/> <script> function checkForm(){ // 校验用户名: // 获得用户名文本框的值: var username = document.getElementById("username").value; if(username == null || username == ''){ alert("用户名不能为空!"); return false; } // 校验密码: // 获得密码框的值: var password = document.getElementById("password").value; if(password == null || password == ''){ alert("密码不能为空!"); return false; } // 校验确认密码: var repassword = document.getElementById("repassword").value; if(repassword != password){ alert("两次密码输入不一致!"); return false; } } function checkUsername(){ // 获得文件框值: var username = document.getElementById("username").value; // 1.创建异步交互对象 var xhr = createXmlHttp(); // 2.设置监听 xhr.onreadystatechange = function(){ if(xhr.readyState == 4){ if(xhr.status == 200){ document.getElementById("span1").innerHTML = xhr.responseText; } } } // 3.打开连接 xhr.open("GET","${pageContext.request.contextPath}/user_findByName.action?time="+new Date().getTime()+"&username="+username,true); // 4.发送 xhr.send(null); } function createXmlHttp(){ var xmlHttp; try{ // Firefox, Opera 8.0+, Safari xmlHttp=new XMLHttpRequest(); } catch (e){ try{// Internet Explorer xmlHttp=new ActiveXObject("Msxml2.XMLHTTP"); } catch (e){ try{ xmlHttp=new ActiveXObject("Microsoft.XMLHTTP"); } catch (e){} } } return xmlHttp; } function change(){ var img1 = document.getElementById("checkImg"); img1.src="${pageContext.request.contextPath}/checkImg.action?"+new Date().getTime(); } </script> </head> <body> <div class="container header"> <div class="span5"> <div class="logo"> <a href="http://localhost:8080/mango/"> <img src="${pageContext.request.contextPath}/image/r___________renleipic_01/logo.gif" alt="传智播客"> </a> </div> </div> <div class="span9"> <div class="headerAd"> <img src="${pageContext.request.contextPath}/image/header.jpg" width="320" height="50" alt="正品保障" title="正品保障"> </div> </div> <%@ include file="menu.jsp" %> </div> <div class="container register"> <div class="span24"> <div class="wrap"> <div class="main clearfix"> <div class="title"> <strong>会员注册</strong>USER REGISTER </div> <div> <s:actionerror /> </div> <form id="registerForm" action="${ pageContext.request.contextPath }/user_regist.action" method="post" novalidate="novalidate" onsubmit="return checkForm();"> <table> <tbody><tr> <th> <span class="requiredField">*</span>用户名: </th> <td> <input type="text" id="username" name="username" class="text" maxlength="20" onblur="checkUsername()"/> <span id="span1"></span> </td> </tr> <tr> <th> <span class="requiredField">*</span>密 码: </th> <td> <input type="password" id="password" name="password" class="text" maxlength="20" autocomplete="off"/> <span><s:fielderror fieldName="password"/></span> </td> </tr> <tr> <th> <span class="requiredField">*</span>确认密码: </th> <td> <input id="repassword" type="password" name="repassword" class="text" maxlength="20" autocomplete="off"/> </td> </tr> <tr> <th> <span class="requiredField">*</span>E-mail: </th> <td> <input type="text" id="email" name="email" class="text" maxlength="200"> <span><s:fielderror fieldName="email"/></span> </td> </tr> <tr> <th> 姓名: </th> <td> <input type="text" name="name" class="text" maxlength="200"/> <span><s:fielderror fieldName="name"/></span> </td> </tr> <tr> <th> 电话: </th> <td> <input type="text" name="phone" class="text" /> </td> </tr> <tr> <th> 地址: </th> <td> <input type="text" name="addr" class="text" maxlength="200"/> <span><s:fielderror fieldName="addr"/></span> </td> </tr> <tr> <th> <span class="requiredField">*</span>验证码: </th> <td> <span class="fieldSet"> <input type="text" id="checkcode" name="checkcode" class="text captcha" maxlength="4" autocomplete="off"><img id="checkImg" class="captchaImage" src="${pageContext.request.contextPath}/checkImg.action" onclick="change()" title="点击更换验证码"> </span> </td> </tr> <tr> <th> </th> <td> <input type="submit" class="submit" value="同意以下协议并注册"> </td> </tr> <tr> <th> </th> <td> 注册协议 </td> </tr> <tr> <th> </th> <td> <div id="agreement" class="agreement" style="height: 200px;"> <p>尊敬的用户欢迎您注册成为本网站会员。请用户仔细阅读以下全部内容。如用户不同意本服务条款任意内容,请不要注册或使用本网站服务。如用户通过本网站注册程序,即表示用户与本网站已达成协议,自愿接受本服务条款的所有内容。此后,用户不得以未阅读本服务条款内容作任何形式的抗辩。</p> <p>一、本站服务条款的确认和接纳<br>本网站涉及的各项服务的所有权和运作权归本网站所有。本网站所提供的服务必须按照其发布的服务条款和操作规则严格执行。本服务条款的效力范围及于本网站的一切产品和服务,用户在享受本网站的任何服务时,应当受本服务条款的约束。</p> <p>二、服务简介<br>本网站运用自己的操作系统通过国际互联网络为用户提供各项服务。用户必须: 1. 提供设备,如个人电脑、手机或其他上网设备。 2. 个人上网和支付与此服务有关的费用。</p> <p>三、用户在不得在本网站上发布下列违法信息<br>1. 反对宪法所确定的基本原则的; 2. 危害国家安全,泄露国家秘密,颠覆国家政权,破坏国家统一的; 3. 损害国家荣誉和利益的; 4. 煽动民族仇恨、民族歧视,破坏民族团结的; 5. 破坏国家宗教政策,宣扬邪教和封建迷信的; 6. 散布谣言,扰乱社会秩序,破坏社会稳定的; 7. 散布淫秽、色情、赌博、暴力、凶杀、恐怖或者教唆犯罪的; 8. 侮辱或者诽谤他人,侵害他人合法权益的; 9. 含有法律、行政法规禁止的其他内容的。</p> <p>四、有关个人资料<br>用户同意: 1. 提供及时、详尽及准确的个人资料。 2. 同意接收来自本网站的信息。 3. 不断更新注册资料,符合及时、详尽准确的要求。所有原始键入的资料将引用为注册资料。 4. 本网站不公开用户的姓名、地址、电子邮箱和笔名。除以下情况外: a) 用户授权本站透露这些信息。 b) 相应的法律及程序要求本站提供用户的个人资料。</p> <p>五、服务条款的修改<br>本网站有权在必要时修改服务条款,一旦条款及服务内容产生变动,本网站将会在重要页面上提示修改内容。如果不同意所改动的内容,用户可以主动取消获得的本网站信息服务。如果用户继续享用本网站信息服务,则视为接受服务条款的变动。</p> <p>六、用户隐私制度<br>尊重用户个人隐私是本网站的一项基本政策。所以,本网站一定不会在未经合法用户授权时公开、编辑或透露其注册资料及保存在本网站中的非公开内容,除非有法律许可要求或本网站在诚信的基础上认为透露这些信息在以下四种情况是必要的: 1. 遵守有关法律规定,遵从本网站合法服务程序。 2. 保持维护本网站的商标所有权。 3. 在紧急情况下竭力维护用户个人和社会大众的隐私安全。 4. 符合其他相关的要求。</p> <p>七、用户的帐号、密码和安全性<br>用户一旦注册成功,将获得一个密码和用户名。用户需谨慎合理的保存、使用用户名和密码。如果你不保管好自己的帐号和密码安全,将负全部责任。另外,每个用户都要对其帐户中的所有活动和事件负全责。你可随时根据指示改变你的密码。用户若发现任何非法使用用户帐号或存在安全漏洞的情况,请立即通告本网站。 八、 拒绝提供担保 用户明确同意信息服务的使用由用户个人承担风险。本网站不担保服务不会受中断,对服务的及时性,安全性,出错发生都不作担保,但会在能力范围内,避免出错。</p> <p>九、有限责任<br>如因不可抗力或其它本站无法控制的原因使本站销售系统崩溃或无法正常使用导致网上交易无法完成或丢失有关的信息、记录等本站会尽可能合理地协助处理善后事宜,并努力使客户免受经济损失,同时会尽量避免这种损害的发生。</p> <p>十、用户信息的储存和限制<br>本站有判定用户的行为是否符合国家法律法规规定及本站服务条款权利,如果用户违背本网站服务条款的规定,本网站有权中断对其提供服务的权利。</p> <p>十一、用户管理<br>用户单独承担发布内容的责任。用户对服务的使用是根据所有适用于本站的国家法律、地方法律和国际法律标准的。用户必须遵循: 1. 使用网络服务不作非法用途。 2. 不干扰或混乱网络服务。 3. 遵守所有使用网络服务的网络协议、规定、程序和惯例。 用户须承诺不传输任何非法的、骚扰性的、中伤他人的、辱骂性的、恐性的、伤害性的、庸俗的,淫秽等信息资料。另外,用户也不能传输何教唆他人构成犯罪行为的资料;不能传输助长国内不利条件和涉及国家安全的资料;不能传输任何不符合当地法规、国家法律和国际法律的资料。未经许可而非法进入其它电脑系统是禁止的。 若用户的行为不符合以上提到的服务条款,本站将作出独立判断立即取消用户服务帐号。用户需对自己在网上的行为承担法律责任。用户若在本站上散布和传播反动、色情或其它违反国家法律的信息,本站的系统记录有可能作为用户违反法律的证据。</p> <p>十二、通告<br>所有发给用户的通告都可通过重要页面的公告或电子邮件或常规的信件传送。服务条款的修改、服务变更、或其它重要事件的通告都会以此形式进行。</p> <p>十三、信息内容的所有权<br>本网站定义的信息内容包括: 文字、软件、声音、相片、录象、图表;在广告中全部内容;本网站为用户提供的其它信息。所有这些内容受版权、商标、标签和其它财产所有权法律的保护。所以,用户只能在本网站和广告商授权下才能使用这些内容,而不能擅自复制、再造这些内容、或创造与内容有关的派生产品。本站所有的文章版权归原文作者和本站共同所有,任何人需要转载本站的文章,必须征得原文作者或本站授权。</p> <p>十四、法律<br>本协议的订立、执行和解释及争议的解决均应适用中华人民共和国的法律。用户和本网站一致同意服从本网站所在地有管辖权的法院管辖。如发生本网站服务条款与中华人民共和国法律相抵触时,则这些条款将完全按法律规定重新解释,而其它条款则依旧保持对用户的约束力。</p> </div> </td> </tr> </tbody></table> <div class="login"> <div class="ad"> <dl> <dt> 注册即享受 </dt> <dd> 正品保障、正规发票 </dd> <dd> 货到付款、会员服务 </dd> <dd> 自由退换、售后上门 </dd> </dl> </div> <dl> <dt>已经拥有账号了?</dt> <dd> 立即登录即可体验在线购物! <a href="${pageContext.request.contextPath}/user_loginPage.action">立即登录</a> </dd> </dl> </div> </form> </div> </div> </div> </div> <div class="container footer"> <div class="span24"> <div class="footerAd"> <img src="${pageContext.request.contextPath}/image/footer.jpg" width="950" height="52" alt="我们的优势" title="我们的优势"> </div> </div> <div class="span24"> <ul class="bottomNav"> <li> <a >关于我们</a> | </li> <li> <a >联系我们</a> | </li> <li> <a >招贤纳士</a> | </li> <li> <a>法律声明</a> | </li> <li> <a >友情链接</a> | </li> <li> <a target="_blank">支付方式</a> | </li> <li> <a target="_blank">配送方式</a> | </li> <li> <a>服务声明</a> | </li> <li> <a >广告声明</a> </li> </ul> </div> <div class="span24"> <div class="copyright">Copyright © 2005-2015 网上商城 版权所有</div> </div> </div> <div id="_my97DP" style="position: absolute; top: -1970px; left: -1970px;"><iframe style="width: 190px; height: 191px;" src="./会员注册 - Powered By Mango Team_files/My97DatePicker.htm" frameborder="0" border="0" scrolling="no"></iframe></div></body></html>
登陆页面
login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <%@ taglib uri="/struts-tags" prefix="s"%> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <!-- saved from url=(0080)http://localhost:8080/mango/login.jhtml?redirectUrl=%2Fmango%2Fcart%2Flist.jhtml --> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/> <title>会员登录</title> <link href="${pageContext.request.contextPath}/css/common.css" rel="stylesheet" type="text/css"/> <link href="${pageContext.request.contextPath}/css/login.css" rel="stylesheet" type="text/css"/> </head> <body> <div class="container header"> <div class="span5"> <div class="logo"> <a href="http://localhost:8080/mango/"> <img src="${pageContext.request.contextPath}/image/r___________renleipic_01/logo.gif" alt="传智播客"> </a> </div> </div> <div class="span9"> <div class="headerAd"> <img src="${pageContext.request.contextPath}/image/header.jpg" width="320" height="50" alt="正品保障" title="正品保障"> </div> </div> <%@ include file="menu.jsp" %> </div> <div class="container login"> <div class="span12"> <div class="ad"> <img src="${pageContext.request.contextPath}/image/login.jpg" width="500" height="330" alt="会员登录" title="会员登录"> </div> </div> <div class="span12 last"> <div class="wrap"> <div class="main"> <div class="title"> <strong>会员登录</strong>USER LOGIN </div> <div><s:actionerror /></div> <form id="loginForm" action="${ pageContext.request.contextPath }/user_login.action" method="post" novalidate="novalidate"> <table> <tbody><tr> <th> 用户名: </th> <td> <input type="text" id="username" name="username" class="text" maxlength="20"> </td> </tr> <tr> <th> 密 码: </th> <td> <input type="password" id="password" name="password" class="text" maxlength="20" autocomplete="off"> </td> </tr> <tr> <th> </th> <td> <input type="submit" class="submit" value="登 录"> </td> </tr> <tr class="register"> <th> </th> <td> <dl> <dt>还没有注册账号?</dt> <dd> 立即注册即可体验在线购物! <a href="${ pageContext.request.contextPath }/user_registPage.action">立即注册</a> </dd> </dl> </td> </tr> </tbody></table> </form> </div> </div> </div> </div> <div class="container footer"> <div class="span24"> <div class="footerAd"><img src="${pageContext.request.contextPath}/image/footer.jpg" width="950" height="52" alt="我们的优势" title="我们的优势" /></div> </div> <div class="span24"> <ul class="bottomNav"> <li> <a >关于我们</a> | </li> <li> <a>联系我们</a> | </li> <li> <a>招贤纳士</a> | </li> <li> <a>法律声明</a> | </li> <li> <a>友情链接</a> | </li> <li> <a target="_blank">支付方式</a> | </li> <li> <a target="_blank">配送方式</a> | </li> <li> <a>服务声明</a> | </li> <li> <a>广告声明</a> </li> </ul> </div> <div class="span24"> <div class="copyright">Copyright © 2005-2015 网上商城 版权所有</div> </div> </div> </body></html>
posted on 2018-01-22 15:29 luzhouxiaoshuai 阅读(998) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!