Java大型互联网项目-移动电子商城-品牌管理
在Console端配置web.xml
<!--spring容器初始化-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:beans.xml</param-value>
</context-param>
<!--springMVC-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<!--拦截.do-->
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
商品管理页面跳转
在Controller类中编写代码
类前添加注解
@Controller //添加springmvc标志注解
@RequestMapping("/item") //映射注解
public class EbItemController {
添加映射
@RequestMapping("/toIndex.do")
public String toIndex(){
return "item/index";
}
启动Tomcat成功访问
同时设置首页点击商品管理跳转到index.jsp
查询品牌
- 对EB_Brand表作逆向工程,生成EbBrandDao实体类及其继承类与EbBrandMapper.xml文件
- 在mapper文件中编写SQL语句
<select id="selectBrandAll" resultMap="BaseResultMap">
select * from eb_brand
</select>
其中,BaseResultMap为生成器自动为我们生成好的
<resultMap id="BaseResultMap" type="com.rl.ecps.model.EbBrand" >
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Tue Apr 02 20:19:35 CST 2019.
-->
<id column="BRAND_ID" property="brandId" jdbcType="DECIMAL" />
<result column="BRAND_NAME" property="brandName" jdbcType="VARCHAR" />
<result column="BRAND_DESC" property="brandDesc" jdbcType="VARCHAR" />
<result column="IMGS" property="imgs" jdbcType="VARCHAR" />
<result column="WEBSITE" property="website" jdbcType="VARCHAR" />
<result column="BRAND_SORT" property="brandSort" jdbcType="DECIMAL" />
</resultMap>
- 编写BrandDao实体类
类前注解+继承SqlSessionDaoSupport代理类
@Repository
public class EbBrandDaoImpl extends SqlSessionDaoSupport implements EbBrandDao {
执行SQL语句
public List<EbBrand> selectBrandAll() {
return this.getSqlSession().selectList(ns+"selectBrandAll");
}
- –>Core模块的Service包的继承类
类前注解与依赖注入
@Service
public class EbBrandServiceImpl implements EbBrandService {
@Autowired
private EbBrandDao brandDao ;
查询方法
public List<EbBrand> selectBrandAll() {
// TODO Auto-generated method stub
return brandDao.selectBrandAll();
}
- 品牌管理入口设置
<li><a href="${path}/item/listBrand.do"><samp class="t05"></samp>品牌管理</a></li>
- listBrand.do跳转
@RequestMapping("/listBrand.do")
public String listBrand(Model model){
List<EbBrand> bList = brandService.selectBrandAll();
model.addAttribute("bList", bList);
return "item/listbrand";
}
其中
brandService为依赖注入
@Autowired
private EbBrandService brandService;
- 前台JSP页面
使用ForEach展示
<table cellspacing="0" summary="" class="tab">
<thead>
<tr>
<th>品牌编号</th>
<th>品牌图片</th>
<th>品牌名称</th>
<th>品牌网址</th>
<th>品牌描述</th>
<th width="10%">排序</th>
<th width="10%">操作</th>
</tr>
</thead>
<tbody>
<c:forEach items="${bList}" var="brand">
<tr>
<td>${brand.brandId}</td>
<td>
<img id='imgsImgSrc' src="${request_file_path}${brand.imgs}"height="50" width="50"/></td>
<td>${brand.brandName}</td>
<td class="nwp">${brand.website}</td>
<td class="nwp">${brand.brandDesc }</td>
<td>155</td>
<td>
<a href="${path }/shop/item/editbrand.jsp?brandId=3185">编辑</a>
<a href="#" onclick="singleDel(3185)">删除</a>
</td>
</tr>
</c:forEach>
</tbody>
</table>
添加品牌
文件上传
图片上传:
我们要把图片上传的逻辑做成一个公用的功能,所以不能把上传逻辑和添加品牌的逻辑混在一起,在点击浏览打开的时候就上传
1.上传文件:
(1)依赖表单,在表单之中
(2)表单的请求方式是Post
(3)表单的enctype="multipart/form-data"
(4)表单中必须要有file类型的input
2.我们要做成提交文件上传的表单,但是页面不能跳转
需要我们使用jquery.form.js插件,这个插件可以以ajax的方式来提交表单,所以不需要跳转页面
引用插件:
<script type="text/javascript" src=${path }/ecps/console/res/item/js/jquery.form.js"/></script>
3.设置springmvc的复杂类型的数据解析器
<!-- 文件上传的视图解析器,id的值是固定的 -->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="10240000"></property>
</bean>
4.把文件服务变成非只读以便于我们可以上传图片和删除图片
找到文件服务器的主机的web.xml, 查找DefaultServlet
<init-param>
<param-name>readonly</param-name>
<param-value>false</param-value>
</init-param>
5.回传绝对路径和相对路径
绝对路径目的显示缩略图,相对路径保存到数据库中
jsp代码
<p><label></label><input type='file' size='27' id='imgsFile' name='imgsFile' class="file" onchange='submitUpload()' /><span id="submitImgTip" class="pos">请上传图片宽为120px,高为50px,大小不超过100K。</span>
<input type='hidden' id='imgs' name='imgs' value='' reg1="^.+$" tip="亲!您忘记上传图片了。" /><span></span>
</p>
function submitUpload(){
var option = {
url:path+"/upload/uploadPic.do",//上传的url
dataType:"text",//回调值的数据类型
success:function(responseText){
//{"realPath":"http://...", "relativePath":"/upload/.."}
var jsonObj = $.parseJSON(responseText);
$("#imgsImgSrc").attr("src", jsonObj.realPath);
$("#imgs").val(jsonObj.relativePath);
$("#lastRealPath").val(jsonObj.realPath);
},
error:function(){
alert("系统错误");
}
}
//使用ajax方式提交表单,上传文件
$("#form111").ajaxSubmit(option);
}
.do代码
@RequestMapping("/upload")
public class EbUploadController {
@RequestMapping("/uploadPic.do")
public void uploadPic(HttpServletRequest request , PrintWriter out , String lastRealPath) throws IOException{
//强制转换request
MultipartHttpServletRequest mr = (MultipartHttpServletRequest)request ;
/*从表单获得文件*/
//获得input的name
java.util.Iterator<String> iter = mr.getFileNames() ;
String inputname = iter.next();
//获得文件
MultipartFile mf = mr.getFile(inputname);
byte[] mfs = mf.getBytes();
//定义上传后的文件名字
String fileName = new SimpleDateFormat("yyyyMMddHHssSSS").format(new Date());
Random random = new Random();
for(int i = 0 ; i<3 ;i++){
fileName = fileName + random.nextInt(10);
}
//获得后缀名
String oriFileName = mf.getOriginalFilename();
String suffix = oriFileName.substring(oriFileName.lastIndexOf("."));
//要上传文件的绝对路径
String realPath = ECPSUtils.readProp("upload_file_path")+"/upload/"+fileName+suffix ;
String relativePath = "/upload/"+fileName+suffix ;
//由于需要在不同主机上上传不能直接通过流的方式写文件
//创建jersey客户端
Client client = Client.create();
//判断是不是第一次上传
if(StringUtils.isNotBlank(lastRealPath)){
WebResource wr = client.resource(lastRealPath) ;
wr.delete();
}
//指定要上传的具体地址,参数就是要上传的图片的绝对路径
WebResource wr = client.resource(realPath) ;
//文件上传到文件主机上
wr.put(mfs) ;
//使用json对象把绝对路径和相对路径写回去
JSONObject jo = new JSONObject();
jo.accumulate("realPath", realPath);
jo.accumulate("relativePath",relativePath );
// {"realPath":"http://...", "relativePath":"/upload/.."}
String result = jo.toString();
out.write(result);
}
}
照片是写在服务器中而不是写在项目中,故项目的file无法看到上传的照片文件
品牌信息验证
全表单验证品牌添加信息是否合理的JS
$(function(){
$("#form111").submit(function(){
var isSubmit = true;
//校验必填字段
$(this).find("[reg2]").each(function(){
//获得输入的值
var val = $(this).val();
val = $.trim(val);
//获得正则
var reg = $(this).attr("reg2");
//获得提示信息
var tip = $(this).attr("tip");
//创建正则表达式的对象
var regExp = new RegExp(reg);
if(!regExp.test(val)){
$(this).next("span").html("<font color='red'>"+tip+"</font>");
isSubmit = false;
//在jQuery中跳出循环要使用return false;
return false;
}else{
//判断当前的input是品牌名称
var inputName = $(this).attr("name");
if(inputName == "brandName"){
//校验品牌名称的重复
var result = validBrandName(val);
if(result == "no"){
$(this).next("span").html("<font color='red'>品牌名称已存在</font>");
isSubmit = false;
//在jQuery中跳出循环要使用return false;
return false;
}else{
$(this).next("span").html("");
}
}else{
$(this).next("span").html("");
}
}
});
$(this).find("[reg1]").each(function(){
//获得输入的值
var val = $(this).val();
val = $.trim(val);
//获得正则
var reg = $(this).attr("reg1");
//获得提示信息
var tip = $(this).attr("tip");
//创建正则表达式的对象
var regExp = new RegExp(reg);
if(val !=null && val != "" && !regExp.test(val)){
$(this).next("span").html("<font color='red'>"+tip+"</font>");
isSubmit = false;
//在jQuery中跳出循环要使用return false;
return false;
}else{
$(this).next("span").html("");
}
})
//防止表单二次提交
if(isSubmit){
tipShow("#refundLoadDiv");
}
return isSubmit;
});
校验使用JQuery主函数的submit事件进行控制,只要提交表单,马上进行校验
其中REG1为非必填字段校验,REG2为必填字段校验
其中,品牌名称的重复性校验需要数据库支持,并且使用AJAX同步判断
AJAX代码:
/**
* 品牌名称重复性校验
* ajax:默认异步的
* 异步
* |---------->ajax
* ————————————>——————————> 主程序
*
* 同步
* ————————————>|---------->——————————>
* @param brandName
* @returns {String}
*/
function validBrandName(brandName){
var result = "yes";
$.ajax({
url:path+"/item/validBrandName.do",
type:"post",
async:false,//把ajax变为同步
data:{
brandName:brandName
},
dataType:"text",
success:function(responseText){
result = responseText;
},
error:function(){
alert("系统错误");
}
})
return result;
}
.do代码
/**
* 验证品牌的名称的重复性
* @param brandName
* @param out
*/
@RequestMapping("/validBrandName.do")
public void validBrandName(String brandName, PrintWriter out){
List<EbBrand> bList = brandService.selectBrandByName(brandName);
String flag = "yes";
if(bList.size() > 0){
flag = "no";
}
out.write(flag);
}
只要能从数据库查询到品牌数据,即返回false
SQL语句:
<select id="selectBrandByName" parameterType="string" resultMap="BaseResultMap">
select * from eb_brand t where t.brand_name = #{brandName}
</select>
友好提示
在客户离开焦点时对所填入内容做正则判断,并进行友好提示
$("#form111").find("[reg2]").blur(function(){
//获得输入的值
var val = $(this).val();
val = $.trim(val);
//获得正则
var reg = $(this).attr("reg2");
//获得提示信息
var tip = $(this).attr("tip");
//创建正则表达式的对象
var regExp = new RegExp(reg);
if(!regExp.test(val)){
$(this).next("span").html("<font color='red'>"+tip+"</font>");
}else{
//判断当前的input是品牌名称
var inputName = $(this).attr("name");
if(inputName == "brandName"){
//校验品牌名称的重复
var result = validBrandName(val);
if(result == "no"){
$(this).next("span").html("<font color='red'>品牌名称已存在</font>");
}else{
$(this).next("span").html("");
}
}else{
$(this).next("span").html("");
}
}
});
$("#form111").find("[reg1]").blur(function(){
//获得输入的值
var val = $(this).val();
val = $.trim(val);
//获得正则
var reg = $(this).attr("reg1");
//获得提示信息
var tip = $(this).attr("tip");
//创建正则表达式的对象
var regExp = new RegExp(reg);
if(val !=null && val != "" && !regExp.test(val)){
$(this).next("span").html("<font color='red'>"+tip+"</font>");
}else{
$(this).next("span").html("");
}
});
.blur事件为离开焦点
效果
品牌信息上传数据库
表单提交到addBrand.do
/**
* 品牌添加
* @param brand
* @return
*/
@RequestMapping("/addBrand.do")
public String addBrand(EbBrand brand){
brandService.saveBrand(brand);
return "redirect:listBrand.do";
}
mapper文件sql
<insert id="insert" parameterType="com.rl.ecps.model.EbBrand" >
<!--
WARNING - @mbggenerated
This element is automatically generated by MyBatis Generator, do not modify.
This element was generated on Tue Apr 02 20:19:35 CST 2019.
-->
insert into EB_BRAND (BRAND_ID, BRAND_NAME, BRAND_DESC,
IMGS, WEBSITE, BRAND_SORT
)
values (seqbrandid.nextval, #{brandName,jdbcType=VARCHAR}, #{brandDesc,jdbcType=VARCHAR},
#{imgs,jdbcType=VARCHAR}, #{website,jdbcType=VARCHAR}, #{brandSort,jdbcType=DECIMAL}
)
</insert>
其中,seqbrandid.nextval作为主键自增