【网上商城】原来jfinal框架可以这么强大

本项目探索如何利用jfinal框架来设计网上商城。项目简单但功能齐全,能够基本符合使用对象的需求,可以实现商品购买和数据管理。其中,项目用到enjoy模板引擎、控制器、validator等技术,实现了分页、文件上传、动态添加商品、用户订单等效果。

总体功能设计

76928fbf1543416794fb3080b8ffa55c.png

管理员

管理员通过商品管理,能够查看所有的商品信息,根据信息增加库存,还能够添加商品的有关信息,设置商品的库存数量、价格、商品名称、所属种类,并完成图片的上传,这样用户就能从前台显示的页面中看到所有在售商品。管理员还可以根据需要对已经添加的商品信息进行修改和删除。

664d9cebc4fd42b0be77eec641bc7ed4.png

331295b9e07644cf90693d3d966b810f.png

管理员通过订单管理,能够查看到用户上传的订单信息,包括商品名称、数量、收件人姓名、收件地址、电话。管理员还可以修改订单的状态,其中订单状态有未出库、已出库、已送达、未签收、已签收,在用户签收订单后,管理员可将订单信息删除。

0bdb5b483478489aaac3d42360151cc6.png

管理员通过用户管理,能够查看所有的账号信息,包括用户名、身份、手机号,并可以根据需要添加管理员。

f438c28f73624bbcaf9f8d5583851e04.png

普通用户

没有注册的用户,可以点击“注册”,即可注册账号。用户在未登录时,能够看到当前所有出售的商品,登录后,可以选择商品进行购买,还能进入“我的订单”,查看所有订单的信息,并签收订单。

461b4e8cd64e4f9abe3ead6d1077648f.png

4173201802ef49ec8c95abddafd8b32e.png

商品展示 

ea1a6171bb514b258550fdf49b9ccabf.png

搜索框 

b065df113bf9414196534bf2892864f3.png

我的订单 

环境配置

1.配置Java的基础环境和Maven的环境配置。

新建MAVEN_HOME,在它的后面加上MAVEN安装文件路径。然后在path中添加“%MAVEN_HOME%/bin”

2.创建Maven项目,添加 jfinal-undertow 与 jfinal 依赖。

打开 pom.xml 文件,在其中添加如下依赖.

<dependency>
    <groupId>com.jfinal</groupId>
    <artifactId>jfinal-undertow</artifactId>
    <version>2.0</version>
</dependency>
<dependency>
    <groupId>com.jfinal</groupId>
    <artifactId>cos</artifactId>
    <version>2019.8</version>
</dependency>
 <dependency>
    	<groupId>mysql</groupId>
    	<artifactId>mysql-connector-java</artifactId>
    	<version>8.0.15</version>
    </dependency>
      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.0.29</version>
      </dependency>
<dependency>
    <groupId>com.jfinal</groupId>
    <artifactId>jfinal</artifactId>
    <version>4.8</version>
</dependency>

 3.创建项目

在项目 src/main/java 目录下创建demo包,并在 demo 包下创建 DemoConfig 文件

public class DemoConfig extends JFinalConfig {
 
    /**
     * 注意:用于启动的 main 方法可以在任意 java 类中创建,在此仅为方便演示
     *      才将 main 方法放在了 DemoConfig 中
     *
     *      开发项目时,建议新建一个 App.java 或者 Start.java 这样的专用
     *      启动入口类放置用于启动的 main 方法
     */
	static Prop p;
	static void loadConfig() {
		if(p==null) {
			p=PropKit.useFirstFound("demo-config.txt","demo-config-dev.txt");
		}
	}
	public static DruidPlugin createDruidPlugin() {
		loadConfig();
		return new DruidPlugin(p.get("jdbcUrl"),p.get("user"),p.get("password").trim());
	}
    public static void main(String[] args) {
//设置端口号
        UndertowServer.start(DemoConfig.class, 82, true);
    }
 
    public void configConstant(Constants me) {
       loadConfig();
       me.setDevMode(true);
       
    }
    
    public void configRoute(Routes me) {
//设置路由
       me.add("/shopping", shoppingController.class);
    }
    
    public void configEngine(Engine me) {
//分页
    	me.addSharedFunction("_paginate.html");
    }
    public void configPlugin(Plugins me) {
//加载数据库
    	DruidPlugin druidPlugin=new                     DruidPlugin(p.get("jdbcUrl"),p.get("user"),p.get("password").trim());
    	me.add(druidPlugin);
    	
    	ActiveRecordPlugin arp=new ActiveRecordPlugin(druidPlugin);   	
    	_MappingKit.mapping(arp);
    	me.add(arp);
    	
    }
    public void configInterceptor(Interceptors me) {}
    public void configHandler(Handlers me) {}

}

 在demo 包下创建 HelloController 类文件

package demo;
import com.jfinal.core.Controller;
 
public class shoppingController extends Controller {
	    public void index() {
	       renderText("Hello JFinal World.");
	    }
	}

启动项目(http://localhost:82/shopping):点击demoConfig,选择run as->java application 

303d386c6b2147ceb9997308312b031d.png

项目功能技术

 enjoy模板引擎

利用该技术可以直接把java代码嵌入到html文件中,实现前端与后台之间的信息传递。

控制器

通过继承interceptor接口并编辑相应的方法,给特定功能设置附加条件,完善系统功能。

83ce01c7845549c8a23f49e69a7face4.png

Validator

通过继承Validator类,可以避免用户输入空白信息,产生bad request,并能暂时保存用户上传的信息,便于修改。

分页

能够快速显示相应信息,减轻服务器存储过多数据的负担。

在网址中传入参数

通过设置跳转界面的网址,添加参数,便于系统判断相应的信息。

文件上传

设置file类的实例对象,获取文件类型并下载文件。

jfinal官网https://jfinal.com/doc

项目功能实现

1.商品显示

利用enjoy引擎中的for指令,结合for.index方法和循环结构,显示商品图片。

<table name="table" style="text-align:right;margin-top:10px" border="1px solid grey" >
        		<tr >
        		#for(x:item)  		
        		#set(i=x.id)
        		<td ><form type="hidden" style="height:340px;width:316px" name="i++" value="#(i)" method="post" action="buy/#(x.id)?id=#(x.id)&&user=#(request.getParameter('user'))">       		
        				<input type='image' src='img/#(i).jpg'  style='margin:2px;width:300px;height:260px'/><br/>
        				<span style="text-align:center;padding-right:10px;">价格:#(x.price)元</span>&nbsp&nbsp&nbsp
        				<span style="text-align:center;padding-right:30px;">数量:#(x.storage)</span><br>
        				<input type='submit' value='立即购买' name="add" style="margin-right:30px;text-align:center;margin-top:10px;text-align:right;" >  				   		
        		#if((for.index)%4==3)
        		</form>
        		</td>
        			</tr>
        		<tr>      		
        		#end
        		#if((for.index)%4!=3)
        		</form>
        		</td>
        		#end

2.登录

设置方法查询该账号是否存在、密码是否正确,根据不同情况,将验证的信息存在attribute中便于长期存储信息,后台从中取出并显示出信息,有一个条件不符合,就会返回登录界面,否则根据身份跳转到对应的界面。

@Before(shopInterceptor.class)
    public void userEnter() {  	
    	String u=this.getPara("username"); 
    	String p=this.getPara("pwd");
    	java.util.List<Login>  pwd=new ArrayList<Login> ();
    	pwd=s.findPwd(u);
    	
    	if(u!=null && p!=null)//密码或账号不为空
    	{if(s.findByName(u)&&pwd.size()!=0)
    		{
    		if(p.equals(pwd.get(0).getPwd()))//密码正确
    			{
    			if(pwd.get(0).getRole().equals("1"))//普通用户
    			{this.setAttr("login","consumer success");
    			this.setAttr("username", u);
    			this.setAttr("pwd", p);
    			redirect("index?user="+u);  			
    			System.out.print(this.getAttr("pwd"));
    			}
    			else if(pwd.get(0).getRole().equals("0"))//管理员
    			{this.setAttr("login","admin success");
    			
    			render("business.html");}
    			}
    		else {this.setAttr("login","pwd fails");//密码错误
    		
    		render("userEnter.html");} 
    		}
    	else if(pwd.size()==0) {this.setAttr("login","username fails");//用户不存在
    	render("userEnter.html");}
    	}
    	else {
    		this.setAttr("login","null");
    		render("userDengLu.html");
    	}
    	}

3. 文件上传

 //上传文件
    public void picAdd() {
    	this.setAttr("clothe", s.findByIdClothe(this.getParaToInt("id")));
    	render("picAdd.html");
    }   
    public void upload() {     	
    	UploadFile uploadFile=getFile();
//获取文件名
		String fileName=uploadFile.getOriginalFileName();
//获取文件类型
		String type=fileName.substring(fileName.lastIndexOf("."));
		System.out.print(fileName);
//通过文件流读文件
		File file=uploadFile.getFile();
//获取文件在项目中的存储位置
		File t=new File(this.getRequest().getServletContext().getRealPath("/")
				+"/shopping/img/"+this.getPara("id")+type);
//文件名重命名
		file.renameTo(t);
//url重定向
		redirect("goodManage/1");
		
    }

4.设置当前日期及星期数

Calendar c=Calendar.getInstance();
		int y=c.get(Calendar.YEAR);//年
		int m=c.get(Calendar.MONTH)+1;//月
		int r=c.get(Calendar.DATE);//日
		this.setAttr("date", y+"年"+m+"月"+r+"日");
        String week = c.get(c.DAY_OF_WEEK) - 1 + "";
        if ("0".equals(week)) {
            week = "七";
        }
        if ("1".equals(week)) {
            week = "一";
        }
        if ("2".equals(week)) {
            week = "二";
        }
        if ("3".equals(week)) {
            week = "三";
        }
        if ("4".equals(week)) {
            week = "四";
        }
        if ("5".equals(week)) {
            week = "五";
        }
        if ("6".equals(week)) {
            week = "六";
        }      
        this.setAttr("week", "星期"+week);

5.分页显示用户数据

<body>
  #include("page_head.txt")
  <div>
    			<form method="post" action="useAdd">
    				<input type="submit" style="margin: 10px 320px 10px 0px;float:right;background-color: rgb(196, 32, 32);color:white;height:30px;width:100px" value="添加管理员"/>
    			</form>
    			<form method="post" action="selUse">
    				<input type="submit" style="margin: 10px 10px 10px 0px;float:right;background-color: rgb(196, 32, 32);color:white;height:30px;width:100px" value="查询"/>
    			</form>
    		</div>
    		<div>
    <div style="padding-left:10px;padding-top:20px">
 
 
    	<form action="" method="post">    
    		<table style='text-align:center;' border='1' width='80%' >
			<tr>
				<td>编号</td>
				<td>用户名</td>
				<td>身份</td>				
				<td>电话</td>
				<td width='10%'></td>
				<td width='10%'></td>
			</tr>
			#for(x:login)		
			<tr>
				<td style="text-align:center;">编号:#(x.useId)</td>
				<td style="text-align:center;">用户名:#(x.username)</td>
				#if((x.role).equals("1"))
				<td style="text-align:center;">用户</td>
				#end
				#if((x.role).equals("0"))
				<td style="text-align:center;">管理员</td>
				#end
				<td style="text-align:center;">电话:#(x.phone)</td>		
				<td><a href="userDelete/#(x.useId)"  class="link1" style="color:blue">删除</a></td>
				<td><a href="userEdit/#(x.useId)" class="link1" style="color:blue;">修改</a></td>		
			</tr>
			#end
	</table>
    	</form>
    </div>	
  </body>
public void useManage() {
    	this.setAttr("login", s.findAllLogin());
    	render("useManage.html");
    }
public List<Login> findAllLogin(){
//查询数据库,返回系统内置方法
		return l.findAll();
	}

6.拦截器

public class shopV extends Validator {

	@Override
	protected void validate(Controller c) {
		// TODO Auto-generated method stub
		this.validateRequiredString("clothe.clotheName", "clotheName", "clotheName cannot be null");//是否有数值
		this.validateRequiredString("clothe.price", "price", "price cannot be null");
		this.validateRequiredString("clothe.storage", "storage", "storage cannot be null");
		
	}

	@Override
	protected void handleError(Controller c) {
		// TODO Auto-generated method stub
		c.keepModel(Clothe.class);
		String actionKey=this.getActionKey();
		if("/shopping/saveGood".equals(actionKey))
			c.render("produceAdd.html");
	}	
		
}

 

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

绚烂的萤火

互相学习,共同成长!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值