SSM项目笔记(遇到的问题+常用的解决思路+高复用的代码)持续更新

说明

  • 作为初学者,最近按照自己的思路写了几个小项目,将项目中遇到的问题和一些复用率较高的代码记录下来,以后持续更新,请按照右侧目录栏快速导航自己需要的模块。

软件环境

IDEA插件一览

  • 插件的安装方式,点击File—>settings—>Plugins在里面搜索安装即可。
  • 如果是使用IDEA进行开发的话,非常建议大家安装一些插件来提高自己dbug和写代码的效率,以下列出一些我在用的觉得很好用的插件:
    • Pokemon Trainer Progress Bar 没啥用的加载进度条美化
    • Alibaba Java Coding Guidelines 阿里巴巴代码规范检查插件,右键点击检查即可 (好的代码规范让你的代码赏心悦目且易读
    • Key promoter 快捷键提示插件,没用快捷键就会提示(新手必备
    • Translation 中英文翻译插件, ctrl+shift+Y新手必备
    • Maven Helper 分析依赖冲突的插件 ,点击pom文件的左下角的两个tab打开Dependency Analyzer
    • Grep Console 控制台日志高亮显示 (新手必备
    • Rainbow Brackets 可以实现配对括号相同颜色,并且实现选中区域代码高亮的功能。 (新手必备
    • CodeGlance 出现类似sublime的代码缩略图 (新手必备
    • Codota 代码智能提示,
    • Statistic 项目信息统计,点击idea底部左下角的statistic可以看到各类代码的大小,行数等信息
    • activate-power-mode:世界在颤抖,装逼插件
    • Background Image Plus + 设置背景图

IDEA常用快捷键

  • 以下是我经常用的IDEA快捷键(仅代表个人)
    • 查找某个类 : Ctrl+Shift+Alt+N
    • 展示该类下所有方法: ctrl+F12
    • 快速清理无用包:ctrl+alt+o (常用)
    • 新建:ctrl+alt+insert
    • 快速切换大小写:ctrl+Shift+u
    • 快捷循环,捕获异常等:ctrl+alt+T (常用)
    • 快速导入未实现方法:ctrl+o (常用)
    • Ctrl+E/Ctrl+Tab查看/切换最近打开过的文件(通过方向键上下选择后,按Enter键进入)
    • ALT+Left/Right 打开的代码编辑窗口中左右切换 (常用)
    • Ctrl+Shift+Y 安装了Translation后能够进行中英文翻译 (需要安装Translation插件) (常用)
    • ctrl+home回到代码顶部

常用

htmlIFrame导入插件

天气的插件

  • 直接弄个iiframe导入即可,非常方便:
<div class="tqyb_nr">
    <iframe  style="padding-top: 20px;padding-left: 20px" scrolling="no" height="54" frameborder="0" allowtransparency="true" src="http://i.tianqi.com/index.php?c=code&id=10&icon=1&num=3"></iframe>
</div>
  • 复制粘贴到html文件上,打开效果如图所示:
    在这里插入图片描述

SSM常见问题

1.样式表单xxxx未能载入,meta值是xxx

  • 将html页面头部的删掉即可
<!--去掉它即可-->
<!DOCTYPE html>

2.SSM中json解析错误的提示(返回json数据重复且太长错误)

  • 问题描述:用火狐显示类似如下错误,用谷歌跳转链接,返回在页面上的json一大堆重复的密密麻麻的数据,说长度太长,且cpu占用飚的老高,卡的一批(•́へ•́╬)。
关于SyntaxError: JSON.parse: unexpected character at line 2 column 1 of the JSON data错误的解决
  • 如果你经历过,八成是这个原因:
    • 不同的Dao层之间有两个方法都有one或者many关系,并且相互调用,例如:

      • 1.我写了一个博客系统,为了让博客文章下面显示与文章相匹配的评论,所以我给文章类加了一个成员变量->评论类的集合,在Dao层通过ID查询文章的时候在返回结果集里面通过文章id一个many关系查询与之相关的所有评论。
      • 2.为了知道评论是针对哪个文章的,我又给评论类添加了一个成员变量->文章类,在评论类的dao层查询所有评论的语句的返回集里添加了one关系,通过评论表中的文章id查询文章,
    • 这是我们常常会遇到的问题(仅代表个人),很显然,这里两个语句出现了相互调用,于是触发任何一句都会无限循环相互调用,这样就会导致一大串重复的数据塞到json里返回回来,然后浏览器就爆掉了(GAMEOVER (✪ω✪))。
      在这里插入图片描述

    • 解决方法:

      • 这些类的使用是有主次的,很显然通过id查询博客的详细信息带上评论是有必要的,而查询所有的评论带上文章信息是次要的,我们可以在通过id查询评论的详细信息中带上博客信息即可,所以我们可以这样解决:
        • 1.将查询所有评论中通过文章id查询文章的语句去掉。
        • 2.如果硬是需要文章,那么可以在文章dao中国专门创建一个用于返回给评论文章的语句,但在语句中不查询与之相关的所有评论。
  • 作者表达能力有限,如果能看到这也是为难大家了(欲哭无泪 o(╥﹏╥)o)

3.SSM框架下可以正常访问jsp但是不能访问html等

  • 将以下代码放置在springMVC配置文件中,前端控制器之前:
<!--放在以下代码的前面-->
<servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
  • 需要放置的代码:
<!--配置正常拦截html,js,css等-->
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.png</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</url-pattern>
</servlet-mapping>

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.gif</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.html</url-pattern>
</servlet-mapping>

4.项目静态资源无法访问的情况

  • 1.如果web.xml文件中springMVC的配置如下:
    • 这里拦截了所有的url,包括静态文件
<servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>    
  • 2.这样就需要在SpringMVC的配置文件中配置资源不拦截:
    • 注意,配置的目录不会递归,所以多级目录要单个配置(有时不配多级也可以,玄学问题(ಥ_ಥ) ,建议删掉out文件,多重启几次,再清除下浏览器缓存
<!-- 设置静态资源不过滤,多级目录需要单个配置 -->
<mvc:resources location="/css/" mapping="/css/**" />
<mvc:resources location="/css/admin/" mapping="/css/admin/**" />
<mvc:resources location="/img/" mapping="/img/**" />
<mvc:resources location="/js/" mapping="/js/**" />
<mvc:resources location="/js/admin/" mapping="/js/admin/**" />
<mvc:resources location="/plugins/" mapping="/plugins/**" />
  • 3.jsp页面可能没有设置不忽略el表达式:
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
  • 4.检查out目录是否有对应的静态资源文件

4.静态资源中带中文的图片无法访问

  • 原因是Tomcat服务器默认使用ISO-8859-1加载,我们修改为utf-8即可。
  • 如果是maven插件tomcat,修改如下:
<plugins>
      <plugin>
        <groupId>org.apache.tomcat.maven</groupId>
        <artifactId>tomcat7-maven-plugin</artifactId>
        <configuration>
          <port>8888</port>
          <path>/</path>
          <uriEncoding>utf-8</uriEncoding>   <!--重要的是这句-->
        </configuration>
        <version>2.2</version>
      </plugin>
    </plugins>
  • 如果是用本地tomcat,在service.xml中修改:
<Connector port="80" protocol="HTTP/1.1" URIEncoding="utf-8"
           connectionTimeout="20000"
           redirectPort="8443" />

5.上传头像显示不出来

  • 很可能是保存在数据库的路径没加http://,因为浏览器访问会默认加http协议,所以误以为能访问。(多次遇到,印象深刻 仅代表个人)
  • 存储头像路径的代码改为:
loginUser.setImgUrl("http://localhost:"+request.getServerPort()+"/upload/touxiang/"+fileName);

常用js代码(jQuery)

1.全选操作

  • html部分全选的复选框设置id为selall,其余复选框设置name=“ids”。
  • js代码如下:
// 全选操作 
$("#selall").click(function () {
    $(":checkbox[name='ids']").prop("checked", this.checked);
});

//获取全选的值
var teacherIds =[];
$("input[name='ids']:checkbox").each(function(){
    if($(this).is(':checked')){
        teacherIds.push(parseInt($(this).val()));
    }
})

2.jQuery获取选框值

  • 1.获取单选框值
var userIds = $("input[name='ids']:checked").val();
  • 2.获取复选框值
//删除角色
$('#delRole').click(function () {
    var del_ids=[];
    $("#del_dataList input[name='del_ids']:checkbox").each(function(){
        if($(this).is(":checked")){
            if ($(this).val()!=""){
                del_ids.push($(this).val());
            }
        }
    })
    console.log(del_ids.toString());
});

3.js的数组循环遍历

  • 1.js中的forEach循环:
array.forEach(function(value,key,arr){//值、键、数组
    console.log(key+" "+value+" "+arr);
})
array.forEach(function(value,key){
    console.log(key+" "+value);
})
array.forEach(function(value){
    console.log(value);
})
  • 2.for in 索引遍历:
for (var item in array) {
    console.log(array[item])
}
  • 3.for of 值遍历:
for (var v of array) {
    console.log(v)
}

4.jQuery获取select选中的值

var options=$(“#select option:selected”); //获取选中的项

alert(options.val()); //拿到选中项的值

alert(options.text()); //拿到选中项的文本

alert(options.attr('url')); //拿到选中项的url值

5.js去除字符串空格

  • 1.这种是修改原生的js的trim方法
//1.直接修改字符串原型的trim,一劳永逸
String.prototype.trim = function() {
  return this.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
}
//2.麻烦点的写法,str表示的是自己的字符串
str = str.replace(/^\s\s*/, '').replace(/\s\s*$/, '');
  • 2其实我更喜欢直接用jQuery的,很方便:
$.trim(str);

6.标准抑制submit提交表单

//方法一:
$("#login_form").submit(function(){
	return false;
});

//方法二:
$("#login_form").submit(function (e) {
    e.preventDefault();
    $.ajax({
        url:"userInfo/login",
        type:"POST",
        dataType:"json",
        data:{

        },
        success:function (data) {
        },
        error:function () {
            alert("服务器出错啦");
        }
    });
    return false;
});

7.异步提交上传文件表单

$("#saveBtn").click(function () {
    let url = $("#form").attr("action");
    let data = new FormData($("#form")[0]);
    $.ajax({
        type:'post',
        url:url,
        cache: false,    //上传文件不需缓存
        processData: false, //需设置为false。因为data值是FormData对象,不需要对数据做处理
        contentType: false, //需设置为false。因为是FormData对象,且已经声明了属性enctype="multipart/form-data"
        data:data,
        dataType:'json',
        success:function(data){
            if(data.flag){
                myLayer.successAlert(data.msg);
                setTimeout(function () {
                    window.history.back();//返回上一页
                },1500);
            }else{
                myLayer.errorMsg(data.msg);
            }
        },
        error:function(){
            myLayer.errorMsg("系统错误!请联系系统管理员!");
        }
    })
});

8.通过多个属性选择元素

$("input[name='logo_bg'][value='color_4']").attr('checked',true);

9.按,(逗号)、(顿号)分割字符串

//包括中英文逗号和顿号
let keyWordArray = blog.keyWord.split(/,|,|、/);

文件操作

1.路径获取

  • 获取文件的绝对路径:
this.getServletContext().getRealPath("/static/img/touxiang/0.jpg");

2.java对文件的创建删除、复制粘贴等

package utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;

//文件操作工具类
public class FileUtils {
    /**
     * 复制文件
     *
     * @param srcPath  源文件路径
     * @param destPath 目标文件路径
     * @throws Exception
     */
    public static void copyFile(String srcPath, String destPath) throws Exception {
        // 打开输入流
        FileInputStream fis = new FileInputStream(srcPath);
        // 打开输出流
        FileOutputStream fos = new FileOutputStream(destPath);
        // 读取和写入信息
        int len = 0;
        // 创建一个字节数组,当做缓冲区
        byte[] b = new byte[1024];
        while ((len = fis.read(b)) != -1) {
            fos.write(b);
        }
        // 关闭流  先开后关  后开先关
        fos.close(); // 后开先关
        fis.close(); // 先开后关
    }

    /**
     * 删除文件
     *
     * @param path 文件全路径
     * @throws Exception
     */
    public static void delFile(String path) throws Exception {
        File file = new File(path);
        if (file.exists() && file.isFile())
            file.delete();
    }

    /**
     * 删除目录
     *
     * @param path 目录全路径
     */
    public static void delDir(String path) {
        File dir = new File(path);
        if (dir.exists()) {
            File[] tmp = dir.listFiles();
            for (int i = 0; i < tmp.length; i++) {
                if (tmp[i].isDirectory()) {
                    delDir(path + "/" + tmp[i].getName());
                } else
                    tmp[i].delete();
            }
        }
        dir.delete();
    }

    /**
     * 创建文件
     * @param path 文件全路径
     * @throws Exception
     */
    public static void createFile(String path) throws Exception{
        File file=new File(path);
        if(!file.exists())
            file.createNewFile();
    }

    /**
     * 创建文件夹
     * @param path 文件夹全路径
     */
    public static void createDir(String path){
        File dir=new File(path);
        if(!dir.exists())
            dir.mkdir();
    }

    /**
     * 重命名
     * @param path 文件夹
     * @param oldname 旧文件名
     * @param newname 新文件名
     */
    public void renameFile(String path,String oldname,String newname){
        if(!oldname.equals(newname)){//新的文件名和以前文件名不同时,才有必要进行重命名
            File oldfile= new File(path+"/"+oldname);
            File newfile= new File(path+"/"+newname);
            if(newfile.exists())//若在该目录下已经有一个文件和新文件名相同,则不允许重命名
                System.out.println(newname+"已经存在!");
            else{
                oldfile.renameTo(newfile);
            }
        }
    }
}


  • 7
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值