SSM-项目整合简单思路

目录

1.首先我们先写好dao与mapper

2.然后我们实现service层,要明白service与dao层的区别,它是根据具体业务实现:

3.Controller层:调用后台的业务逻辑,并且返回数据给到前端jsp页面上,可以理解为最终的实现层,也是与数据交接的地方;(一般来说,Controller层获取的数是由前端jquery实现ajax获取前台数据给到对应controller的)

4.这里的验证方式是通过ajax来实现的

5.工具类:MD5Utils

 1.盐值;2.DigestUtils.md5DigestAsHex(xxx.getBytes());

6.拦截器的实现:只有登录的用户才有资格访问

拦截器实现思路:1.实现HandlerInterceptor 2.利用preHandle()方法进行拦截

7.配置文件

1.首先是web.xml

2.application.xml配置

3.spring-mvc.xml配置



1.首先我们先写好dao与mapper

UserDao:

package com.yanzhen.dao;

import java.util.List;
import java.util.Map;

import com.yanzhen.entity.User;

public interface UserDao {
    public int create(User pi);

    public int delete(Map<String, Object> paramMap);

    public int update(Map<String, Object> paramMap);

    public List<User> query(Map<String, Object> paramMap);

    public User detail(Map<String, Object> paramMap);

    public int count(Map<String, Object> paramMap);
}

UserMaper 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.yanzhen.dao.UserDao">
    <resultMap type="com.yanzhen.entity.User" id="User">
        <id column="id" property="id"/>
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="remark" property="remark"/>
        <result column="user_name" property="userName"/>
        <result column="user_pwd" property="userPwd"/>
    </resultMap>

    <insert id="create" keyProperty="id" useGeneratedKeys="true" parameterType="com.yanzhen.entity.User">
		insert into tb_user(
			name,
			remark,
			user_name,
			user_pwd
		)values(
			#{name},
			#{remark},
			#{userName},
			#{userPwd}
		)
	</insert>

    <select id="query" resultMap="User">
        select * from tb_user
        <include refid="UserFindCriteria"/>
        <if test="offset!=null and rows!=null">limit ${offset} , ${rows}</if>
    </select>

    <select id="count" resultType="int">
        select count(1) from tb_user
        <include refid="UserFindCriteria"/>
    </select>

    <select id="detail" resultMap="User">
        select * from tb_user
        <include refid="UserFindCriteria"/>
        limit 1
    </select>

    <delete id="delete">
        delete from tb_user
        <include refid="UserFindCriteria"/>
    </delete>
    <update id="update">
        update tb_user
        <include refid="UserUpdateCriteria"/>
        <include refid="UserFindCriteria"/>
    </update>
    <sql id="UserFindCriteria">
        <where>
            <if test="id != null">and id = #{id}</if>
            <if test="name != null and name != ''">and name like concat('%',#{name},'%')</if>
            <if test="remark != null and remark != ''">and remark = #{remark}</if>
            <if test="userName != null and userName != ''">and user_name like concat('%',#{userName},'%')</if>
            <if test="userPwd != null and userPwd != ''">and user_pwd = #{userPwd}</if>
        </where>
    </sql>
    <sql id="UserUpdateCriteria">
        <set>
            <if test="updateId != null">id = #{updateId},</if>
            <if test="updateName != null and updateName != ''">name = #{updateName},</if>
            <if test="updateRemark != null and updateRemark != ''">remark = #{updateRemark},</if>
            <if test="updateUserName != null and updateUserName != ''">user_name = #{updateUserName},</if>
            <if test="updateUserPwd != null and updateUserPwd != ''">user_pwd = #{updateUserPwd},</if>
        </set>
    </sql>
</mapper>

2.然后我们实现service层,要明白service与dao层的区别,它是根据具体业务实现:

比如说登录,我们service层首先将userName与userPwd放入map容器中并返回map容器

然后dao层调用查询单个用户的方法(参数都为map),所以userName与userPwd需要放入map中

package com.yanzhen.service;

import com.yanzhen.dao.UserDao;
import com.yanzhen.entity.User;
import com.yanzhen.entity.User;
import com.yanzhen.utils.BeanMapUtils;
import com.yanzhen.utils.MD5Utils;
import com.yanzhen.utils.MapParameter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;

@Service
public class UserService {

    @Autowired
    private UserDao userDao;

    public int create(User pi) {
        pi.setUserPwd(MD5Utils.getMD5(pi.getUserPwd()));
        return userDao.create(pi);
    }

    public int delete(Integer id) {
        return userDao.delete(MapParameter.getInstance().addId(id).getMap());
    }
    public int delete(String ids) {
        int flag = 0;
        for (String str : ids.split(",")) {
            flag = userDao.delete(MapParameter.getInstance().addId(Integer.parseInt(str)).getMap());
        }
        return flag;
    }

    public int update(User user) {
        Map<String, Object> map = MapParameter.getInstance().add(BeanMapUtils.beanToMapForUpdate(user)).addId(user.getId()).getMap();
        return userDao.update(map);
    }

    public List<User> query(User user) {
        return userDao.query(BeanMapUtils.beanToMap(user));
    }

    public User detail(Integer id) {
        return userDao.detail(MapParameter.getInstance().addId(id).getMap());
    }

    public int count(User user) {
        return userDao.count(BeanMapUtils.beanToMap(user));
    }

    public User login(String userName,String password){
        Map<String, Object> map = MapParameter.getInstance()
                .add("userName", userName)
                .add("userPwd", password)
                .getMap();//将用户信息放入map容器中
        return userDao.detail(map);//根据map信息在mapper中的sql语句中进行查询,返回用户
    }

}

因为我们这个项目是有三种登录方式,所以学生以及老师也要各自实现自己login方法,反正都是根据用户名以及密码查询用户,就不具体演示了

3.Controller层:调用后台的业务逻辑,并且返回数据给到前端jsp页面上,可以理解为最终的实现层,也是与数据交接的地方;(一般来说,Controller层获取的数是由前端jquery实现ajax获取前台数据给到对应controller的)

思路:1.参数为用户名及密码,登录类型,验证码,session;2.进行错误验证(比如说用户名密码为空的情况);3.根据type具体类型为多少来实现不同的登录方式;4.登录方式的实现(验证session)

package com.yanzhen.controller;

import com.yanzhen.entity.Student;
import com.yanzhen.entity.Teacher;
import com.yanzhen.entity.User;
import com.yanzhen.service.StudentService;
import com.yanzhen.service.TeacherService;
import com.yanzhen.service.UserService;
import com.yanzhen.utils.Code;
import com.yanzhen.utils.MD5Utils;
import com.yanzhen.utils.MapControll;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.util.Map;

@Controller
public class LoginController {

    @Autowired
    private UserService userService;
    @Autowired
    private StudentService studentService;
    @Autowired
    private TeacherService teacherService;

    @GetMapping("/login")
    public String login(){
        return "login";
    }

    @PostMapping("/login")
    @ResponseBody
    public Map<String,Object> login(String userName, String password, String type,String captcha, HttpSession session){

        if(StringUtils.isEmpty(userName) || StringUtils.isEmpty(password) || StringUtils.isEmpty(type)){
            return MapControll.getInstance().error("用户名或密码不能为空").getMap();
        }
        String _captcha = (String)session.getAttribute("captcha");
        if(StringUtils.isEmpty(captcha)){
            return MapControll.getInstance().error("验证码不能为空").getMap();
        }
        if(!captcha.equals(_captcha)){
            return MapControll.getInstance().error("验证码错误").getMap();
        }

        //管理员登录
        if("1".equals(type)){
            User user = userService.login(userName, MD5Utils.getMD5(password));
            if(user != null){
                //此时user的业务层返回了用户,然后我们将这些用户放入session中
                session.setAttribute("user",user);
                session.setAttribute("type",1);
                return MapControll.getInstance().success().add("data",user).getMap();
            }else{
                return MapControll.getInstance().error("用户名或密码错误").getMap();
            }
        }
        //老师登录
        if("2".equals(type)){
            Teacher teacher = teacherService.login(userName, MD5Utils.getMD5(password));
            if(teacher != null){
//                将用户信息放入session中,并且放入用户类型
                session.setAttribute("user",teacher);
                session.setAttribute("type",2);
                //用户信息存在,将用户信息放入map容器中,并且放入成功提示信息,返回map容器,后给前端页面ajax中的data
                return MapControll.getInstance().success().add("data",teacher).getMap();
            }else{
                return MapControll.getInstance().error("用户名或密码错误").getMap();
            }

        }
        //学生登录
        if("3".equals(type)){
            Student student = studentService.login(userName, MD5Utils.getMD5(password));
            if(student != null){
                session.setAttribute("user",student);
                session.setAttribute("type",3);
                return MapControll.getInstance().success().add("data",student).getMap();
            }else{
                return MapControll.getInstance().error("用户名或密码错误").getMap();
            }
        }
        return MapControll.getInstance().error("用户名或密码错误").getMap();
    }



}

 这里用StringUtils来验证userName、password、type、captcha是否为空,如果为空就返回错误,将错误信息放入map容器中(这里用了自定义工具类)

package com.yanzhen.utils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class MapControll {

    //目标对象
    private Map<String,Object> paramMap = new HashMap<>();

    //私有构造
    private MapControll(){

    }

    public static MapControll getInstance(){
        return new MapControll();
    }

    public MapControll add(String key, Object value){
        paramMap.put(key,value);
        return this;//this这里指的就是对象new MapController();
    }

    public MapControll success(){
        paramMap.put("code",Code.SUCCESS.getCode());
        paramMap.put("msg",Code.SUCCESS.getMsg());//msg为返回给前端的信息,作为验证,若为1000说明成功,则跳转到首页
        return this;
    }
    public MapControll error(){
        paramMap.put("code",Code.ERROR.getCode());
        paramMap.put("msg",Code.ERROR.getMsg());
        return this;
    }

    public MapControll error(String msg){
        paramMap.put("code",Code.ERROR.getCode());
        paramMap.put("msg",msg);
        return this;
    }

    public MapControll notEmpty(){
        paramMap.put("code",Code.NOT_EMPTY.getCode());
        paramMap.put("msg",Code.NOT_EMPTY.getMsg());
        return this;
    }
    public MapControll nodata(){
        paramMap.put("code",Code.NODATA.getCode());
        paramMap.put("msg",Code.NODATA.getMsg());
        return this;
    }

    public MapControll page(List<?> list,Integer count){
        paramMap.put("data",list);
        paramMap.put("count",count);
        return this;
    }

    public MapControll put(String key, Object value){
        this.add(key,value);
        return this;
    }

    public MapControll addId(Object value){
        paramMap.put("id",value);
        return this;
    }

    public MapControll add(Map<String,Object> map){
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            paramMap.put(entry.getKey(),entry.getValue());
        }
        return this;
    }

    public MapControll put(Map<String,Object> map){
        return this.add(map);
    }

    public Map<String,Object> getMap(){
        return paramMap;
    }




}

 至于具体管理员学生老师登录:1.根据类型判断;2.调用业务层方法获取用户;3.如果用户不为空放入session中,type也要放入,然后将用户信息放入map容器中,且调用success得到正确码给,并且返回map容器,将返回数据给到前端验证

4.这里的验证方式是通过ajax来实现的

  // 进行登录操作
        form.on('submit(login)', function (data) {
            $.ajax({
                url:"${basePath}login",
                type:"POST",
                dataType:'json',
                data:data.field,
                success:function(data){
                    if(data.code == "1000"){
                        location.href = "index";
                    }else{
                        //登录失败显示出后端返回给前端的数据
                        layer.msg(data.msg,{time:2000});
                    }
                }
            });
            return false;
        });

最重要的三个点:1.url:对应着controller ;2.data:给对应controller传去的数据 ; 3.success:来自后台controller回显的数据,这里起了一个验证效果;

5.工具类:MD5Utils

 1.盐值;2.DigestUtils.md5DigestAsHex(xxx.getBytes());

package com.yanzhen.utils;

import org.springframework.util.DigestUtils;

public class MD5Utils {

    //盐
    private static final String salt = "StudentSystemManager###$$@@";

    public static String getMD5(String string){
        String val = string+salt;
        return DigestUtils.md5DigestAsHex(val.getBytes());
    }


    public static void main(String[] args) {
        System.out.println(getMD5("123456"));
    }


}

6.拦截器的实现:只有登录的用户才有资格访问

拦截器实现思路:1.实现HandlerInterceptor 2.利用preHandle()方法进行拦截

3.req.getSession(),如果session中为空则抛出异常(自定义异常),否则通过

package com.yanzhen.utils;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class PermissionInterceptor implements HandlerInterceptor {

    //可以根据session中是否有信息进行拦截
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session = request.getSession();
//        如果session中user信息不为空,则放行,否则抛出异常并且传入message提示
        if(session.getAttribute("user") != null){
            return true;
        }else{
            throw new PermissionException("没有权限访问");
        }
    }

  
}

自定义异常:继承运行异常,当异常出现,可以自定义异常所报出的信息

package com.yanzhen.utils;

public class PermissionException extends  RuntimeException {

//自定义异常
    public PermissionException(String message) {
        super(message);
    }
}

但是我们还需要处理异常,因为你如果没有权限而去访问就会报出405,所以我们要有一个全局异常处理,这样我们就可以返回一个error页面或者返回json,相对来说比较友好

package com.yanzhen.utils;

import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.jws.HandlerChain;
import java.util.Map;

@ControllerAdvice
public class GlobalControllerAdvice {
//全局异常处理
    private final String ERROR = "error";
//设定全局处理的异常
    @ExceptionHandler(value=PermissionException.class)
    public ModelAndView noPermission(PermissionException e){
        //new一个返回页面为error
        ModelAndView modelAndView = new ModelAndView(ERROR);
        //绑定:将异常中的message信息与error页面绑定,也就是说当抛出PermissionException异常时,就返回error页面
        modelAndView.addObject(ERROR,e.getMessage());
        return modelAndView;
    }

    @ExceptionHandler(value=RuntimeException.class)
    @ResponseBody
    public Map<String,Object> runtimeException(RuntimeException e){
        e.printStackTrace();
        return MapControll.getInstance().error().getMap();
    }


}

7.配置文件

1.首先是web.xml

三步骤:1.前端控制器DispatcherServlet(注意里面初始化加载的spring-mvc.xml);

2.配置web.xml配置文件的节点<context-param>:当你启动项目时,容器就会读取它,并将Context-param中的给到servletContext上下文,并且会读取listener对上下文进行监听

3.配置过滤器filter

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!-- 整合spring
    1.前端控制器,为了加载spring-mvc和容器
    2.配置spring上下文监听器,加载spring容器
    3.编码过滤器-->
    <servlet>
        <servlet-name>student_system</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>classpath:spring-mvc.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    
    <servlet-mapping>
        <servlet-name>student_system</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>

    <!--上下文参数-->
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:applicationContext.xml</param-value>
    </context-param>
    <!--    配置spring容器上下文监听,ContextLoader里面有ContextConfigLocation属性,然后会被servlet调用-->
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>



    <!--编码过滤-->
    <filter>
        <filter-name>encodingFilter</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>utf-8</param-value>
        </init-param>
    </filter>
    <filter-mapping>
        <filter-name>encodingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    
<!--    <welcome-file-list>-->
<!--        <welcome-file>index.jsp</welcome-file>-->
<!--    </welcome-file-list>-->
</web-app>

2.application.xml配置

我们这里就不多配置一个spring-service.xml了(这种配置方式狂神视频中有),我们直接全部放在application.xml中;

1.首先是扫描service,扫描其注解(类似这种文件形式的都是<context:xxx>)

 <context:component-scan base-package="com.yanzhen.service" />

2.配置数据库配置文件位置与数据源驱动参数

<context:property-placeholder location="classpath:db.properties" />
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="${jdbc.driver}"></property>
        <property name="url" value="${jdbc.url}"></property>
        <property name="username" value="${jdbc.username}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>

3.配置sqlSessionFactory(因为是由sqlSessionFactoryBuilder读取mybatis配置文件而得到的关键对象,可以理解为sqlSessionFactory是mybatis的核心,是它配置文件的实例,里面所有的sql操作):里面要注入数据源驱动参数,mybatis配置文件,并且扫描所有的mapper

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <property name="configLocation" value="classpath:mybatis-config.xml"></property>
        <property name="mapperLocations">
            <list>
                <value>classpath:com/yanzhen/dao/*.xml</value>
            </list>
        </property>
        <!--配置分页插件-->
        <property name="plugins">
            <array>
                <bean class="com.github.pagehelper.PageInterceptor">
                    <property name="properties">
                        <value>
                            helperDialect=mysql
                        </value>
                    </property>
                </bean>
            </array>
        </property>
    </bean>

像在xml中对bean中属性进行赋值一般有两种方式:1.ref:将其他bean作为属性值引入;2.value:除了能将其他bean作为属性值引入之外,还能引入路径

4.MapperScannerConfigurer的配置,作用类似于sqlSessionTemplate的配置

 <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.yanzhen.dao"></property>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property>
    </bean>

3.spring-mvc.xml配置

1.mvc一般是和controller接轨的,因为controller和前端页面有关系,所以要扫描controller以及utils下的文件

 <context:component-scan base-package="com.yanzhen.controller,com.yanzhen.utils" />

2.因为web.xml中配置了前端控制器Dispatcher,所以这里要配置一个<mvc:annotation-driven>,作用:注解驱动,能够自动注册@RequestMappingHandlerMapping映射器以及@RequestMappingHandlerAdapter适配器;

映射器作用:controller中每个方法都对应着一个@RequestMapping,它的作用就是识别注解下的方法,根据注解定义的url与方法进行匹配,然后交给前端控制器;

适配器:方法与@RequestMapping进行适配;

<mvc:annotation-driven>
        <mvc:message-converters>
            <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
                <property name="objectMapper">
                    <bean class="com.fasterxml.jackson.databind.ObjectMapper">
                        <property name="dateFormat">
                            <bean class="java.text.SimpleDateFormat">
                                <constructor-arg type="java.lang.String" value="yyyy-MM-dd"/>
                            </bean>
                        </property>
                    </bean>
                </property>
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>

3.视图解析器配置:

 <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/page/"></property>
        <property name="suffix" value=".jsp"></property>
    </bean>

4.拦截器配置:

<mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**/*"/>
            <bean class="com.yanzhen.utils.PathInterceptor" />
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**/*"/>
            <mvc:exclude-mapping path="/login"/>
            <mvc:exclude-mapping path="/logout"/>
<!--            这里是/captcha/*是因为后面只有一个子路径了-->
            <mvc:exclude-mapping path="/captcha/*"/>
<!--            后面还有多个文件-->
            <mvc:exclude-mapping path="/static/**"/>
            <bean class="com.yanzhen.utils.PermissionInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

想要所有源码关注联系我 

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Fairy要carry

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值