SpringMVC学习笔记(一)--SpringMVC框架+Mybatis+maven+C3p0实现用户登录

前言:最近在做一个小项目,要实现登录功能,因为SSM框架比较火所以就学了一下,首先学的是maven,主要是用来管理jar包方便,然后是Myabtis如何去操作数据库,再是SpringMVC框架中的controller如何接受前端发来的请求以及操作数据库。

一:先看一下我的maven项目的框架

二:配置文件

1:web.xml文件

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5"   
 3     xmlns="http://java.sun.com/xml/ns/javaee"   
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee   
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7   <display-name>zongjin</display-name>
 8   <welcome-file-list>
 9     <welcome-file>index.html</welcome-file>
10     <welcome-file>index.htm</welcome-file>
11     <welcome-file>index.jsp</welcome-file>
12     <welcome-file>default.html</welcome-file>
13     <welcome-file>default.htm</welcome-file>
14     <welcome-file>default.jsp</welcome-file>
15   </welcome-file-list>
16   
17  
18 <!--配置servlet,它的类不用写,直接调用  -->
19 <servlet>
20     <servlet-name>spring</servlet-name>
21     <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
22      <init-param>  
23          <param-name>contextConfigLocation</param-name>  
24          <param-value>classpath*:config/sping.xml</param-value>
25      </init-param>  
26     <load-on-startup>1</load-on-startup>
27 </servlet>
28 
29 <servlet-mapping>
30     <servlet-name>spring</servlet-name>
31     <url-pattern>/</url-pattern>
32 </servlet-mapping>
33 
34 <servlet-mapping>
35     <servlet-name>default</servlet-name>
36     <url-pattern>*.jpg</url-pattern>
37 </servlet-mapping>
38 <servlet-mapping>
39     <servlet-name>default</servlet-name>
40     <url-pattern>*.png</url-pattern>
41 </servlet-mapping>
42 <servlet-mapping>
43     <servlet-name>default</servlet-name>
44     <url-pattern>*.js</url-pattern>
45 </servlet-mapping>
46 <servlet-mapping>
47     <servlet-name>default</servlet-name>
48     <url-pattern>*.css</url-pattern>
49 </servlet-mapping>  
50 
51 </web-app>

这里需要注意的是下面的这个代码,如果你的DispatcherServlet拦截 *.do这样的URL,就不存在访问不到静态资源的问题。如果你的DispatcherServlet拦截“/”,拦截了所有的请求,同时对*.js,*.jpg的访问也就被拦截了。就相当于你的css,js,jpg,png文件等信息不能够显示,这是个很大的问题。

<servlet>
    <servlet-name>spring</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     <init-param>  
         <param-name>contextConfigLocation</param-name>  
         <param-value>classpath*:config/sping.xml</param-value>
     </init-param>  
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>spring</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

分析原因:<servlet-mapping>的<url-pattern>/</url-pattern>把所有的请求都交给spring去处理了,而所有available的请求url都是在Constroller里使用类似@RequestMapping(value = "/login/{user}", method = RequestMethod.GET)这样的注解配置的,这样的话对js/css/jpg/gif等静态资源的访问就会得不到。

解决方案有三个,其中一个是在web.xml文件中加入下面代码,将你在jsp文件中用到的所有不能显示的信息都以这样的格式写入,就好了,或者你就使用<url-pattern>*.do</url-pattern>这样的形式来接受前端界面传到后台的url。就不存在这种问题。

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.jpg</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>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>*.css</url-pattern>
</servlet-mapping>  

这个是我看一个大神博客总结的,下面是他的博客地址

 http://blog.csdn.net/u012730299/article/details/51872704

2:sping.xml文件,这个文件名我起错了,应该是spring-mvc.xml,不过别介意这些细节

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:task="http://www.springframework.org/schema/task"
    xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="
    http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd
    http://www.springframework.org/schema/mvc 
    http://www.springframework.org/schema/mvc/spring-mvc.xsd">
   
    <!-- 引入属性文件 -->
    <context:property-placeholder location="classpath*:config/db.properties" ignore-unresolvable="true" />
    <!-- 自动扫描(自动注入) -->
    <context:component-scan base-package="com.ttms.service"/>
    <context:component-scan base-package="com.controller"/>
    
    <!-- 
         开启注解//该配置项其实也包含了自动注入上述processor的功能,因此当使用<context:component-scan/>后,即可将<context:annotation-config/>省去
        <context:annotation-config />
    -->
    
    <!-- 一、使用数据库连接池注册数据源,引入相关的配置文件 -->
         <import resource="c3p0.xml"/>
         
    
    <!-- 二、创建mybatis会话工厂 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
       <property name="dataSource" ref="dataSource"></property>     
       <property name="mapperLocations" value="classpath:com/ttms/mybatis/mapper/*Mapper.xml"></property>
    </bean>
    <!-- 注册接口类的bean,使得程序中可以用注解方式获取 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">   
        <property name="basePackage" value="com.ttms.mybatis.mapper" />           
    </bean> 
    
     <!--事务管理器类--> 
     <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
 
    <!--内部视图解析器,JSP与JSTL模板 -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <!--指定视图渲染类 -->
        <property name="viewClass"    value="org.springframework.web.servlet.view.JstlView" />
        <!--自动添加到路径中的前缀 -->
        <property name="prefix" value="/login/" />
        <!--自动添加到路径中的后缀 -->
        <property name="suffix" value=".jsp" />
        <!--设置所有视图的内容类型,如果视图本身设置内容类型视图类可以忽略 -->
        <property name="contentType" value="text/html;charset=UTF-8" />
    </bean>
 
</beans>

 3:c3p0.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:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
        
    <!-- 一、使用c3p0连接池注册数据源 -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
       <!-- 基础配置 -->
       <property name="jdbcUrl" value="${jdbc.url}"></property>
       <property name="driverClass" value="${jdbc.driver}"></property>
       <property name="user" value="${jdbc.username}"></property>
       <property name="password" value="${jdbc.password}"></property>
 
       
     <!-- 关键配置 -->
     <!--初始化时获取三个连接,取值应在minPoolSize与maxPoolSize之间。Default: 3 -->
     <property name="initialPoolSize" value="${c3p0.initialPoolSize}"></property>
     <!--连接池中保留的最小连接数。Default: 2 -->
     <property name="minPoolSize" value="${c3p0.minPoolSize}"></property>
     <!--连接池中保留的最大连接数。Default: 15 -->
     <property name="maxPoolSize" value="${c3p0.maxPoolSize}"></property>
     <!--当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3 -->
     <property name="acquireIncrement" value="${c3p0.acquireIncrement}"></property>
     
     <!-- 性能配置 -->
     <!-- 控制数据源内加载的PreparedStatements数量。如果maxStatements与maxStatementsPerConnection均为0,则缓存被关闭。Default: 0 -->
     <property name="maxStatements" value="${c3p0.maxStatements}"></property>
     <!-- maxStatementsPerConnection定义了连接池内单个连接所拥有的最大缓存statements数。Default: 0 -->
     <property name="maxStatementsPerConnection" value="${c3p0.maxStatementsPerConnection}"></property>
     <!--最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。Default: 0 -->
     <property name="maxIdleTime" value="${c3p0.maxIdleTime}"></property>
     <property name="acquireRetryAttempts" value="${c3p0.acquireRetryDelay}"></property>
     <property name="autoCommitOnClose" value="${c3p0.autoCommitOnClose}"></property>
    
     
    </bean>

</beans>

4:db.properties文件,这个文件的创建可以可以用记事本创建,把后缀名更改就可以了。

#DB login parameters
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ttms?useUnicode=true&characterEncoding=utf-8&useSSL=true
jdbc.username=root
jdbc.password=zongjin123


#pool parameters
c3p0.initialPoolSize=16
c3p0.minPoolSize=15
c3p0.maxPoolSize=50
c3p0.maxIdleTime=6000
c3p0.acquireIncrement=5
c3p0.acquireRetryAttempts=3
c3p0.acquireRetryDelay=500
c3p0.autoCommitOnClose=false
c3p0.checkoutTimeout=10000
c3p0.idleConnectionTestPeriod=600
c3p0.maxStatements=100
c3p0.maxStatementsPerConnection=5
c3p0.numHelperThreads=3
c3p0.testConnectionOnCheckin=false

有一个坑就是jdbc.username这个值指的是Mysql中的Username,我一开始在纠结是不是Connection Name浪费了很长时间,我真是个傻逼,现在也没搞清这个Connection Name有啥用,谁知道告诉我.

 

5.log4j2.xml这个是日志文件,个人觉得加不加无所谓,

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="off" monitorInterval="1800">    
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>        
    </Appenders>

    <Loggers>            
        <Root level="debug">
            <AppenderRef ref="Console" />
        </Root>
    </Loggers>
</Configuration>

基本的配置文件就这么多,然后看Mybatis的配置,看我项目的结构,在com.ttms.mybatis.mapper的包下先创建UserDAO接口,UserDAOMapper.xml相当于实现了这个接口

6.接口UserDAO

package com.ttms.mybatis.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import com.ttms.Model.*;

@Repository
public interface UserDAO {
    //@Param("aaa") String name;作用是给参数命名,名称就是参数的名称
    //取全部用户 + 分页 + 按条件匹配
    public List<Employee> getAllUsers(@Param("skip") int skip,@Param("size") int size, 
            @Param("search_name") String search_name, @Param("search_account") String search_account);
    //用户数量
    public int getCount(@Param("search_no") String search_no, @Param("search_account") String search_account); 
    //添加用户
    public int addUser(User user);
    public int addEmployee(Employee emp);
    //更新
    public int updateUser(Employee user);
    //删除
    public int deleteUserById(int id);
    
    //public User chack_login(@Param("emp_no") String emp_no,@Param("emp_ps") String emp_ps);
    public User chack_name(@Param("emp_no") String emp_no);

}

7:UserDAOMapper.xml中的id指的是UserDAO中的接口函数名,其他的属性看下边的注释

<?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.ttms.mybatis.mapper.UserDAO">  
   <!-- parameterType:是传入参数 
           resultType:传出参数
           id:调用函数名
    -->
   
    
    <!-- 查询用户的登录的用户名和密码是否正确 -->
    <select id = "chack_name" parameterType = "String" resultType = "com.ttms.Model.User"> 
        select * from user where emp_no like #{emp_no}
    </select>
    
    <!--新增用户 -->
    <insert id="addEmployee" parameterType="com.ttms.Model.Employee">
        insert into Employee(emp_no,emp_name,emp_tel_num,emp_addr,emp_email) values(#{emp_no},#{emp_name},#{emp_tel_num},#{emp_addr},#{emp_email})
    </insert>
    <insert id = "addUser" parameterType = "com.ttms.Model.User">
        insert into User(emp_no,emp_pass) values(#{emp_no},#{emp_pass})
    </insert>
    
    <!-- 更新用户 -->
    <update id="updateUser" parameterType="com.ttms.Model.Employee">
        update employee set emp_no=#{emp_no},emp_name=#{emp_name},emp_tel_num=#{emp_tel_num},emp_addr=#{emo_addr},emp_email=#{emp_email} where emp_id=#{emp_id}
    </update>
    <!--删除用户 -->
    <delete id="deleteUserById" parameterType="int">
         delete from employee where emp_id=#{emp_id}
    </delete>
    
    
</mapper>  

 8:User类

package com.ttms.Model;

public class User {
    private String emp_no;
    private String emp_pass;
    private int type;
    private String head_path;
    public String getEmp_no() {
        return emp_no;
    }
    public void setEmp_no(String emp_no) {
        this.emp_no = emp_no;
    }
    public String getEmp_pass() {
        return emp_pass;
    }
    public void setEmp_pass(String emp_pass) {
        this.emp_pass = emp_pass;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public String getHead_path() {
        return head_path;
    }
    public void setHead_path(String head_path) {
        this.head_path = head_path;
    }
    

}

9:定义service层的接口,虽然是实现了登录功能,但里边还有一些其他了函数功能。

package com.ttms.service;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.ttms.Model.*;
@Repository
public interface IorderServer {
    
    /**
     * 获取用户 + 分页 + 筛选
     * @param pageNo 页码
     * @param size 页的大小
     * @param search_name 按姓名匹配
     * @param search_account 按账号匹配
     * @return
     */
    public List<Employee> getAllUsers(int pageNo, int size, String search_name, String search_account);
    /**
     * 用户数量
     * @return
     */
    public int getCount(String search_name, String search_account);
    /**
     * 新增用户
     * @param user
     * @return
     */
    public Boolean addEmployee(Employee emp);
    public Boolean addUser(User user);
    /**
     * 更新用户
     * @param user
     * @return
     */
    public int updateUser(Employee user);
    /**
     * 删除用户
     * @param id
     * @return
     */
    public int deleteUserById(int id);
    
    
    public User login(String name, String password);
    
    
    
    public Boolean chack_zhuce(String name);

}

10:EmployeeTest实现IorderServe接口,其中用到了注解@Autowired来自动装配UserDAO接口,这些注解的具体使用,我会在下一的博客中总结。

package com.ttms.service;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ttms.Model.Employee;
import com.ttms.Model.User;
import com.ttms.mybatis.mapper.UserDAO;
//@Service("UserService") 注解用于标示此类为业务层组件,在使用时会被注解的类会自动由
//spring进行注入,无需我们创建实例
@Service("IorderServer")
public class EmployeeTest implements IorderServer {
    @Autowired //不用你去实现set和get方法它可以对类成员变量、方法及构造函数进行标注,完成自动装配的工作    
    //@Resource
    UserDAO userdao;//这里它是一个接口所以不需要去在xml文件中定义属性和对应的值,自动注入userdao 用于访问数据库
    
  
    public List<Employee> getAllUsers(int pageNo, int size, String search_name,
            String search_account) {
        // TODO Auto-generated method stub
        return null;
    }
    public int getCount(String search_name, String search_account) {
        // TODO Auto-generated method stub
        return 0;
    }

    public Boolean addUser(User user) {
        // TODO Auto-generated method stub
        int flg = userdao.addUser(user);
        if(flg == -1)
            return false;
        return true;
    }
    public Boolean addEmployee(Employee emp)
    {
        int flg =userdao.addEmployee(emp);
        if(flg == -1)
            return false;
        return true;
    }


    public int updateUser(Employee user) {
        // TODO Auto-generated method stub
        return 0;
    }

    public int deleteUserById(int id) {
        // TODO Auto-generated method stub
        return 0;
    }

    public User login(String emp_no, String emp_ps) {
        // TODO Auto-generated method stub
        System.out.println("进入了test1");
        User user = userdao.chack_name(emp_no);
        System.out.println("进入了test2");
        if(user != null)
        {
            if(user.getEmp_no().equals(emp_no) && user.getEmp_pass().equals(emp_ps))
            {
                return user;
            }
            
        }
        
        return null;
    }

    public Boolean chack_zhuce(String search_no) {
        // TODO Auto-generated method stub
        User user = userdao.chack_name(search_no);
        if(user != null)
        {
            
            return true;//表示重名
        }
        return false;//表示未重名
    }
    
}

11.控制器UserController,通过注解@RequestMapping("/login")和@RequestMapping("/save")来获取前端页面form中发过来的aciton="${pageContext.request.contextPath}/login/save",其中

${pageContext.request.contextPath}的作用是取出部署的应用程序名,这样不管如何部署,所用路径都是正确的。

package com.controller;


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

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

import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.RedirectView;

import com.ttms.Model.*;
import com.ttms.service.*;
//method = RequestMethod.POST

@Controller 
@RequestMapping("/login")
//在默认情况下springmvc的实例都是单例模式,所以使用scope域将其注解为每次都创建一个新的实例
@Scope("prototype")
public class UserController{ 
      //自动注入业务层的userService类
    @Autowired
    IorderServer ttms;
   @RequestMapping(value="/save",method = RequestMethod.POST) 
   public ModelAndView chack_login(String emp_no,String emp_ps,ModelAndView mv,HttpSession session){    
       User user = ttms.login(emp_no, emp_ps);    
       if(user!=null){//管理员登陆
           if(user.getType() == 1)
           {
             //转发到main请求
               System.out.println("进入了1");
               mv.setViewName("index");       
               mv.addObject("user", user);     
           }
           //普通用户登陆
           else if(user.getType() == 0)
           {
               mv.setViewName("Emp_index");
               mv.addObject("user",user);
           }
           else {
           //登录失败,设置失败信息,并调转到登录页面    
                mv.addObject("message","登录名和密码错误,请重新输入");
                mv.setViewName("login");
           }
         }
       return mv;
         
   }
  
}  

12.login.jsp,我用的是bootstrap框架,你们用的话可能不会显示出来效果,这里只看功能。

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<%@ page isELIgnored="false"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
        <script src="bootstrap.min.js"></script>
        <script src="jquery-3.1.1.min.js"></script>
        <link rel="stylesheet" href="css/bootstrap.min.css"/>
        <link rel="stylesheet" href="css/login.css" />
        <title></title>
    </head>
    <body>
        <div id="back" >
            <div id="logo"><img src="img/login/logo.png" /></div>
            <div id="lg">
               <label id="lname">${message}</label>
                <div id="lg1"><p><span>用户登录</span></p></div>
                <form action="${pageContext.request.contextPath}/login/save" method="post">    
                <label for="emp_no" class="col-sm-2 control-lable" style="color: white;">账号:</label>
                <div class="clol-sm-4">
                <input type="text" style="color: black;" class="form-control" id="emp_no" name="emp_no"
                            placeholder="请输入大小写字母和数字,长度6-20位" pattern="[a-zA-Z0-9]{4,20}"
                            required="required" oninvalid="setCustomValidity('请输入大小写字母和数字,长度4-20位!')"
                            oninput="setCustomValidity('')" >
                            
                </div>
                
                <label for="emp_ps" class="col-sm-2 control-lable" style="color: white;">密码:</label>
                <div class="clol-sm-4">
                <input type="text" style="color: black;" class="form-control" id="emp_ps" name="emp_ps"
                            placeholder="请输入大小写字母和数字,长度6-20位" pattern="[a-zA-Z0-9]{4,20}"
                            required="required" oninvalid="setCustomValidity('请输入大小写字母和数字,长度4-20位!')"
                            oninput="setCustomValidity('')" >
                </div>
                
                <div class="form-group">
                    <div class="col-sm-2 control-label" style="color:red;font-weight: bold;"></div>
                    <div class="col-sm-4">
                        <button type="submit" class="btn btn-success">登录</button>
                    </div>
                    
                    
                </div>
                
                </form>
                <div class="col-sm-4">
                        <a href="./zhuce.jsp" style="color: white;">注册</a>
                    </div>
                    
                    
            </div>
        </div>
        
  
    <script src="bootstrap.min.js"></script>
    <script type="text/javascript">
   
    </script>
    </body>
</html>

13.index.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>TTMS</title>
  <link rel="stylesheet" href="layui/css/layui.css">
</head>
<body class="layui-layout-body">
  <p>管理员${user.emp_no}登录成功</p>
</body>
</html>

14.Emp_index.jsp

<%@ page language="java" contentType="text/html; charset=utf-8"
    pageEncoding="utf-8"%>
<%@ page isELIgnored="false" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <title>TTMS</title>
  <link rel="stylesheet" href="layui/css/layui.css">
</head>
<body class="layui-layout-body">
  <p>普通用户${user.emp_no}登录成功</p>
</body>
</html>

15.数据库的user表

16:下一篇博客讲一下controller如何向前端jsp页面发送数据,以及jsp界面如何接受数据

原文地址:https://www.cnblogs.com/zongjin/p/7877528.html