SpringMVC+Spring+MyBatis案例-----登录注册知识笔记总结_用户登录模块spring整合myvatis案例-程序员宅基地

技术标签: spring  java  java项目  IDEA  tomcat  maven  spring框架  java-ee  

第一章:需求分析

1-1阅读需求分析

第二章:搭建开发环境

2-1创建数据库

   将sql文件导入crm_login数据库中;

文木心

2-2创建项目

project—new—entry project----项目名称,存储位置;
project Setting:
文木心
编码格式
文木心
创建模块(基于Maven):New–Module----Maven(√)–(选择模版webapp)—开发web应用
文木心
GroupID:一般为公司的域名
Artifactid:项目名称 例:crm
文木心
通过右键–Make Directory As–选择resources文件夹的类型(test和其他类型对应上一级目录)
文木心

2-3搭建ssm开发环境

对pom.xml文件添加依赖

<?xml version="1.0" encoding="UTF-8"?>

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.wkcto.crm</groupId>
  <artifactId>crm</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>crm Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
  </properties>

  <dependencies>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.11</version>
      <scope>test</scope>
    </dependency>
    <!-- MySQL数据库连接驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.43</version>
    </dependency>

    <!-- JDBC数据源连接池 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.1</version>
    </dependency>

    <!-- MyBatis框架依赖 -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.4.1</version>
    </dependency>

    <!-- Spring框架依赖的JAR配置 -->
    <!-- Spring AOP支持-->
    <dependency>
      <groupId>org.aspectj</groupId>
      <artifactId>aspectjweaver</artifactId>
      <version>1.8.9</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.0</version>
    </dependency>

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-core</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-tx</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-web</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-oxm</artifactId>
      <version>4.3.9.RELEASE</version>
    </dependency>

    <!-- 加载jackson插件依赖 -->
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-core</artifactId>
      <version>2.7.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-databind</artifactId>
      <version>2.7.3</version>
    </dependency>
    <dependency>
      <groupId>com.fasterxml.jackson.core</groupId>
      <artifactId>jackson-annotations</artifactId>
      <version>2.7.3</version>
    </dependency>

    <!-- servlet及jstl标签库依赖的JAR配置 -->
    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
    </dependency>
    <dependency>
      <groupId>javax.servlet.jsp.jstl</groupId>
      <artifactId>jstl-api</artifactId>
      <version>1.2</version>
    </dependency>
    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-spec</artifactId>
      <version>1.2.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.taglibs</groupId>
      <artifactId>taglibs-standard-impl</artifactId>
      <version>1.2.1</version>
    </dependency>


    <!-- Log4j2依赖的JAR配置 -->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-api</artifactId>
      <version>2.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-jcl</artifactId>
      <version>2.3</version>
    </dependency>

  </dependencies>

  <build>
    <finalName>crm</finalName>
    <pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
      <plugins>
        <plugin>
          <artifactId>maven-clean-plugin</artifactId>
          <version>3.1.0</version>
        </plugin>
        <!-- see http://maven.apache.org/ref/current/maven-core/default-bindings.html#Plugin_bindings_for_war_packaging -->
        <plugin>
          <artifactId>maven-resources-plugin</artifactId>
          <version>3.0.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-compiler-plugin</artifactId>
          <version>3.8.0</version>
        </plugin>
        <plugin>
          <artifactId>maven-surefire-plugin</artifactId>
          <version>2.22.1</version>
        </plugin>
        <plugin>
          <artifactId>maven-war-plugin</artifactId>
          <version>3.2.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-install-plugin</artifactId>
          <version>2.5.2</version>
        </plugin>
        <plugin>
          <artifactId>maven-deploy-plugin</artifactId>
          <version>2.8.2</version>
        </plugin>
      </plugins>
    </pluginManagement>

    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <include>**/*.*</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

此时如果添加依赖错误,则重新选择新的Maven版本
文木心
添加mybatis-config.xml依赖

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
    <typeAliases>
        <package name="com.bjpowernode.crm.model"/>
    </typeAliases>
    <mappers>
        <package name="com.bjpowernode.crm.mapper"/>
    </mappers>
</configuration>

对applicationContext-datasource.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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-4.3.xsd
      http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
      http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
    <!-- 配置数据源,使用连接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="username" value="root"/>
        <property name="password" value="yf123"/>
        <property name="url" value="jdbc:mysql://127.0.0.1:3306/crm_login?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
    </bean>
    <!-- 配置SqlSessionFactory -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 必须注入属性dataSource -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 如果mybatis没有特殊的配置(比如别名等),configLocation可以省去 ;否则,不能省略-->
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>
    <!-- mapper注解扫描器配置,扫描@MapperScan注解,自动生成代码对象 -->
    <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wkcto.crm.mapper,
                                            com.wkcto.crm.settings.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

    <!-- 配置事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"/>
    </bean>
    <!-- 配置事务 -->
    <aop:config>
        <aop:pointcut expression="execution(* com.wkcto.crm..service.*.*(..))" id="allMethodPointcut"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="allMethodPointcut"/>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="add*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="save*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="edit*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="update*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="delete*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="do*" propagation="REQUIRED" rollback-for="Exception"/>
            <tx:method name="*" propagation="REQUIRED" read-only="true"/>
        </tx:attributes>
    </tx:advice>
</beans>


对applicationContext.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"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:task="http://www.springframework.org/schema/task"
       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
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
    <!-- 扫描注解 -->
    <context:component-scan base-package="com.wkcto.crm.service" />
    <context:component-scan base-package="com.wkcto.crm.settings.service" />
    <!-- 导入数据相关配置 -->
    <import resource="applicationContext-datasource.xml" />
</beans>

对applicationContext-mvc.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"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:util="http://www.springframework.org/schema/util"
       xmlns:aop="http://www.springframework.org/schema/aop"
       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.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util.xsd">
    <!-- dispatcherServlet截获所有URL请求 -->
    <mvc:default-servlet-handler />
    <!-- spring mvc 扫描包下的controller -->
    <context:component-scan base-package="com.wkcto.crm.web.controller"/>
    <context:component-scan base-package="com.wkcto.crm.settings.web.controller"/>
    <context:component-scan base-package="com.wkcto.crm.workbench.web.controller"/>
    <!-- 配置注解驱动 -->
    <mvc:annotation-driven/>
    <!-- 配置视图解析器 -->
    <bean id="viewResolver"
          class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/pages/"/>
        <property name="suffix" value=".jsp"/>
    </bean>
    <!-- 配置文件上传解析器 id:必须是multipartResolver-->
    <!--<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
        <property name="maxUploadSize" value="#{1024*1024*80}"/>
        <property name="defaultEncoding" value="utf-8"/>
    </bean>-->
</beans>

对web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xmlns="http://java.sun.com/xml/ns/javaee"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         id="dataservice" version="3.0">
  <display-name>dataservice application</display-name>
  <!-- spring监听器加载applicationContext.xml配置文件 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:applicationContext.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <!-- spring字符过滤器 -->
  <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>
  <!-- Spring mvc分发servlet -->
  <servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:applicationContext-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  <servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <!-- 欢迎页,默认进入index controller -->
  <welcome-file-list>
    <welcome-file>/</welcome-file>
  </welcome-file-list>
</web-app>

目录最好创建一下,要不然容易报错!!!

静态页面一般放在WEB-INF(保护),js,css,img->放在webapp容易获取

2-4:用户登录-显示登录页面

位置:webapp下
index.html页面----index.jsp动态页面
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
<%--    相当于http://ip:port/项目名/--%>
	String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
	<base href="<%=basePath%>">
<meta charset="UTF-8">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        $(function () {
    
            //给整个窗口添加键盘按下的事件
            $(window).keydown(function (e) {
    
                if(e.keyCode==13){
    
                    $("#loginBtn").click();//单击"登录"按钮
                }
            });

            //"登录"按钮添加单击事件
            $("#loginBtn").click(function () {
    
                //搜集参数
                var loginAct=$("#loginAct").val();
                var loginPwd=$("#loginPwd").val();
                var isRemPwd=$("#isRemPwd").prop("checked");
                //表单验证
                if (loginAct==""){
    
                    alert("用户名不能为空");
                    return;
                }
                if (loginPwd==""){
    
                    alert("密码不能为空");
                    return;
                }
                //发送请求
                $.ajax({
    
                    url:'settings/qx/user/login.do',
                    data:{
    
                        loginAct:loginAct,
                        loginPwd:loginPwd,
                        isRemPwd:isRemPwd
                    },
                    type:'post',
                    dataType:'json',
                    success:function (data) {
    
                        if (data.code=="1"){
    
                            //跳转到业务主页面
                           window.location.href = "workbench/index.do";
                        }else{
    
                            $("#msg").text(data.message);
                        }
                    },
                    beforeSend:function () {
    //在发送ajax请求之前执行本函数,本函数会返回true或者false;返回值能够决定ajax是否真正发送请求:true-ajax会继续发送请求,false-ajax放弃发送请求。
                        $("#msg").text("正在验证....");
                        return true;
                    }
                });
            });
        });
    </script>
</head>
<body>
	<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
		<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
	</div>
	<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
		<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM &nbsp;<span style="font-size: 12px;">&copy;2019&nbsp;动力节点</span></div>
	</div>
	
	<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
		<div style="position: absolute; top: 0px; right: 60px;">
			<div class="page-header">
				<h1>登录</h1>
			</div>
			<form action="workbench/index.html" class="form-horizontal" role="form">
				<div class="form-group form-group-lg">
					<div style="width: 350px;">
						<input class="form-control" id="loginAct" value="${cookie.loginAct.value}" type="text" placeholder="用户名">
					</div>
					<div style="width: 350px; position: relative;top: 20px;">
						<input class="form-control" id="loginPwd" value="${cookie.loginPwd.value}" type="password" placeholder="密码">
					</div>
					<div class="checkbox"  style="position: relative;top: 30px; left: 10px;">
						<label>
                            <c:if test="${not empty cookie.loginAct and not empty cookie.loginPwd}">
                                <input type="checkbox" id="isRemPwd" checked="true">
                            </c:if>
                            <c:if test="${empty cookie.loginAct or empty cookie.loginPwd}">
                                <input type="checkbox" id="isRemPwd">
                            </c:if>
                            十天内免登录
						</label>
						&nbsp;&nbsp;
						<span id="msg" style="color: red;"></span>
					</div>
					<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block"  style="width: 350px; position: relative;top: 45px;">登录</button>
				</div>
			</form>
		</div>
	</div>
</body>
</html>
从地址栏访问不到login.html,要从controller去访问

UserController.java

/**
package com.wkcto.crm.settings.web.controller;
import com.wkcto.crm.settings.domain.User;
import com.wkcto.crm.settings.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Controller
public class UserController {
    

    @Autowired
    private UserService userService;

    @RequestMapping("/settings/qx/user/toLogin.do")
    public String toLogin(){
    
        return "settings/qx/user/login";
    }

    @RequestMapping("/settings/qx/user/login.do")
    public @ResponseBody Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpSession session, HttpServletResponse response){
    
        //封装参数
        Map<String,Object> map=new HashMap<>();
        map.put("loginAct",loginAct);
        map.put("loginPwd",loginPwd);
        //调用service层方法,查询用户
        User user=userService.queryUserByLoginActAndPwd(map);

        //根据查询结果,生成响应信息
        Map<String,Object> retMap=new HashMap<>();
        if(user==null){
    
            //账号或者密码错误,登录失败
            retMap.put("code","0");
            retMap.put("message","账号或者密码错误");
        }else{
    
            //进一步判断账号是否过期、状态是否被锁定,ip是否被允许
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String nowStr=simpleDateFormat.format(new Date());
            if(nowStr.compareTo(user.getExpireTime())>0){
    
                //账号已过期,登录失败
                retMap.put("code","0");
                retMap.put("message","账号已过期");
            }else if("0".equals(user.getLockState())){
    
                //账号状态被锁定,登录失败
                retMap.put("code","0");
                retMap.put("message","账号状态被锁定");
            }else if(!user.getAllowIps().contains(request.getRemoteAddr())){
    
                //ip受限,登录失败
                retMap.put("code","0");
                retMap.put("message","ip受限");
            }else{
    
                //登录成功
                retMap.put("code","1");
                //为了在所有的业务页面中显示用户的名字,把user保存到session中
                session.setAttribute("sessionUser",user);

                //如果需要记住密码
                if("true".equals(isRemPwd)){
    
                    Cookie c1=new Cookie("loginAct",loginAct);
                    c1.setMaxAge(10*24*60*60);
                    response.addCookie(c1);

                    Cookie c2=new Cookie("loginPwd",loginPwd);
                    c2.setMaxAge(10*24*60*60);
                    response.addCookie(c2);
                }else{
    //如果不需要记住密码,则清空cookie
                    Cookie c1=new Cookie("loginAct",loginAct);
                    c1.setMaxAge(0);
                    response.addCookie(c1);

                    Cookie c2=new Cookie("loginPwd",loginPwd);
                    c2.setMaxAge(0);
                    response.addCookie(c2);
                }
            }
        }

        return retMap;
    }
}

java的包结构最好与前端页面的结构保持一致!!!

配置tomcat

Run/debug  Configurations----->+----Tomcat Server----local---

在这里插入图片描述

点击Deployment-------部署项目在服务器上
点击加号—war exploded

在这里插入图片描述
ok,配置完成!!!

第三章 设计及编码实现

3-1:用户登录-分析与设计实现登录功能

Rational Rose工具
时序图:反应业务逻辑
在这里插入图片描述

3-2 用户登录-概述如何编码实

先写被依赖的类

实体类,根据表来建立,对应一个数据库表。
UserMapper:属性--------字段,+get,set方法

3-3 用户登录-创建mybatis的逆向工程

New Module—Maven(java)-----可以不属于任何一个工程,-----ArtifactId:项目名—mybatis—ok

添加配置文件
generator.properties

jdbc.driverLocation=D:/testDir/Maven/repository_g/mysql/mysql-connector-java/5.1.43/mysql-connector-java-5.1.43.jar
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://127.0.0.1:3306/crm_login
jdbc.userId=root
jdbc.password=yf123

generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>

    <!--指定mysql数据库驱动-->
    <!--<classPathEntry location="E://repository-p2p//mysql//mysql-connector-java//5.1.43//mysql-connector-java-5.1.43.jar"/>-->

    <!--导入属性配置-->
    <properties resource="generator.properties"></properties>

    <!--指定特定数据库的jdbc驱动jar包的位置-->
    <classPathEntry location="${jdbc.driverLocation}"/>

    <context id="default" targetRuntime="MyBatis3">

        <!-- optional,旨在创建class时,对注释进行控制,false生成注释,true无注释 -->
        <commentGenerator>
            <property name="suppressDate" value="false"/>
            <property name="suppressAllComments" value="false"/>
        </commentGenerator>

        <!--jdbc的数据库连接 -->
        <jdbcConnection
                driverClass="${jdbc.driverClass}"
                connectionURL="${jdbc.connectionURL}"
                userId="${jdbc.userId}"
                password="${jdbc.password}">
        </jdbcConnection>


        <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>


        <!-- Model模型生成器,用来生成含有主键key的类,记录类 以及查询Example类
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在该项目下所在的路径|指定生成到的工程名称
        -->
        <javaModelGenerator targetPackage="com.wkcto.crm.settings.domain"
                            targetProject="F:/teaching/wkcto/crm/code/crm-project/crm/src/main/java">

            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>
            <!-- 是否对model添加 构造函数 true添加,false不添加-->
            <property name="constructorBased" value="false"/>
            <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!--Mapper映射文件生成所在的目录 为每一个数据库的表生成对应的SqlMap文件 -->
        <sqlMapGenerator targetPackage="com.wkcto.crm.settings.mapper"
                         targetProject="F:/teaching/wkcto/crm/code/crm-project/crm/src/main/java">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>

        <!-- 客户端代码,生成易于使用的针对Model对象和XML配置文件 的代码
                type="ANNOTATEDMAPPER",生成Java Model 和基于注解的Mapper对象
                type="MIXEDMAPPER",生成基于注解的Java Model 和相应的Mapper对象
                type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
        -->
        <javaClientGenerator targetPackage="com.wkcto.crm.settings.mapper"
                             targetProject="F:/teaching/wkcto/crm/code/crm-project/crm/src/main/java" type="XMLMAPPER">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

		<table tableName="tbl_user" domainObjectName="User"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
        
    </context>
</generatorConfiguration>

数据库文件:



SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `tbl_user`
-- ----------------------------
DROP TABLE IF EXISTS `tbl_user`;
CREATE TABLE `tbl_user` (
  `id` char(32) NOT NULL COMMENT 'uuid\r\n            ',
  `login_act` varchar(255) DEFAULT NULL,
  `name` varchar(255) DEFAULT NULL,
  `login_pwd` varchar(255) DEFAULT NULL COMMENT '密码不能采用明文存储,采用密文,MD5加密之后的数据',
  `email` varchar(255) DEFAULT NULL,
  `expire_time` char(19) DEFAULT NULL COMMENT '失效时间为空的时候表示永不失效,失效时间为2018-10-10 10:10:10,则表示在该时间之前该账户可用。',
  `lock_state` char(1) DEFAULT NULL COMMENT '锁定状态为空时表示启用,为0时表示锁定,为1时表示启用。',
  `deptno` char(4) DEFAULT NULL,
  `allow_ips` varchar(255) DEFAULT NULL COMMENT '允许访问的IP为空时表示IP地址永不受限,允许访问的IP可以是一个,也可以是多个,当多个IP地址的时候,采用半角逗号分隔。允许IP是192.168.100.2,表示该用户只能在IP地址为192.168.100.2的机器上使用。',
  `createTime` char(19) DEFAULT NULL,
  `create_by` varchar(255) DEFAULT NULL,
  `edit_time` char(19) DEFAULT NULL,
  `edit_by` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of tbl_user
-- ----------------------------
INSERT INTO `tbl_user` VALUES ('06f5fc056eac41558a964f96daa7f27c', 'ls', '李四', 'yf123', '[email protected]', '2018-11-27 21:50:05', '1', 'A001', '192.168.1.1,127.0.0.1,0:0:0:0:0:0:0:1', '2018-11-22 12:11:40', '李四', null, null);
INSERT INTO `tbl_user` VALUES ('40f6cdea0bd34aceb77492a1656d9fb3', 'zs', '张三', 'yf123', '[email protected]', '2018-11-30 23:50:55', '1', 'A001', '192.168.1.1,192.168.1.2,127.0.0.1,0:0:0:0:0:0:0:1', '2018-11-22 11:37:34', '张三', null, null);

右侧找到下图----双击运行----连上数据库-----自动创建实体类
在这里插入图片描述

3-4 用户登录-编码实现mapper层和service层

写好UserMapper.java,写User Mapper.xml文件,然后在applicationContext-datasource.xml文件中添加注解

 <bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wkcto.crm.mapper,
                                            com.wkcto.crm.settings.mapper"/>
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    </bean>

UserMapper.java

package com.wkcto.crm.settings.mapper;

import com.wkcto.crm.settings.domain.User;

import java.util.Map;

public interface UserMapper {
    
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table tbl_user
     *
     * @mbggenerated Thu May 14 20:26:52 CST 2020
     */
    int deleteByPrimaryKey(String id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table tbl_user
     *
     * @mbggenerated Thu May 14 20:26:52 CST 2020
     */
    int insert(User record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table tbl_user
     *
     * @mbggenerated Thu May 14 20:26:52 CST 2020
     */
    int insertSelective(User record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table tbl_user
     *
     * @mbggenerated Thu May 14 20:26:52 CST 2020
     */
    User selectByPrimaryKey(String id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table tbl_user
     *
     * @mbggenerated Thu May 14 20:26:52 CST 2020
     */
    int updateByPrimaryKeySelective(User record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table tbl_user
     *
     * @mbggenerated Thu May 14 20:26:52 CST 2020
     */
    int updateByPrimaryKey(User record);
    /**
    * 根据用户名和密码查询用户
    */
    User selectUserByLoginActAndPwd(Map<String,Object> map);
}

UserService.java

package com.wkcto.crm.settings.service;

import com.wkcto.crm.settings.domain.User;

import java.util.Map;


public interface UserService {
    
    User queryUserByLoginActAndPwd(Map<String,Object> map);
}

用applicationContext.xml文件扫描UserServiceImpl.java所在的包
UserServiceImpl.java

/**
 * @项目名:crm-project
 * @创建人: Administrator
 * @创建时间: 2020-05-14
 * @公司: www.bjpowernode.com
 * @描述:
 */
package com.wkcto.crm.settings.service.impl;

import com.wkcto.crm.settings.domain.User;
import com.wkcto.crm.settings.mapper.UserMapper;
import com.wkcto.crm.settings.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Map;


@Service("userService")
public class UserServiceImpl implements UserService {
    

    @Autowired
    private UserMapper userMapper;

    @Override
    public User queryUserByLoginActAndPwd(Map<String, Object> map) {
    
        return userMapper.selectUserByLoginActAndPwd(map);
    }
}

3-5、3-6用户登录-编码实现controller层

UserController.java


package com.wkcto.crm.settings.web.controller;

import com.wkcto.crm.settings.domain.User;
import com.wkcto.crm.settings.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;


@Controller
public class UserController {
    
//注入Service层
    @Autowired
    private UserService userService;

    @RequestMapping("/settings/qx/user/toLogin.do")
    public String toLogin(){
    
        return "settings/qx/user/login";
    }

    @RequestMapping("/settings/qx/user/login.do")
//接受从前端传过来的参数
    public @ResponseBody Object login(String loginAct, String loginPwd, String isRemPwd, HttpServletRequest request, HttpSession session, HttpServletResponse response){
    
        //封装参数
        Map<String,Object> map=new HashMap<>();
        map.put("loginAct",loginAct);
        map.put("loginPwd",loginPwd);
        //调用service层方法,查询用户
        User user=userService.queryUserByLoginActAndPwd(map);

        //根据查询结果,生成响应信息
        Map<String,Object> retMap=new HashMap<>();
        if(user==null){
    
            //账号或者密码错误,登录失败
            retMap.put("code","0");
            retMap.put("message","账号或者密码错误");
        }else{
    
            //进一步判断账号是否过期、状态是否被锁定,ip是否被允许
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
            String nowStr=simpleDateFormat.format(new Date());
            if(nowStr.compareTo(user.getExpireTime())>0){
    
                //账号已过期,登录失败
                retMap.put("code","0");
                retMap.put("message","账号已过期");
            }else if("0".equals(user.getLockState())){
    
                //账号状态被锁定,登录失败
                retMap.put("code","0");
                retMap.put("message","账号状态被锁定");
            }else if(!user.getAllowIps().contains(request.getRemoteAddr())){
    
                //ip受限,登录失败
                retMap.put("code","0");
                retMap.put("message","ip受限");
            }else{
    
                //登录成功
                retMap.put("code","1");
                //为了在所有的业务页面中显示用户的名字,把user保存到session中
                session.setAttribute("sessionUser",user);

                //如果需要记住密码
                if("true".equals(isRemPwd)){
    
                    Cookie c1=new Cookie("loginAct",loginAct);
                    c1.setMaxAge(10*24*60*60);
                    response.addCookie(c1);

                    Cookie c2=new Cookie("loginPwd",loginPwd);
                    c2.setMaxAge(10*24*60*60);
                    response.addCookie(c2);
                }else{
    //如果不需要记住密码,则清空cookie
                    Cookie c1=new Cookie("loginAct",loginAct);
                    c1.setMaxAge(0);
                    response.addCookie(c1);

                    Cookie c2=new Cookie("loginPwd",loginPwd);
                    c2.setMaxAge(0);
                    response.addCookie(c2);
                }
            }
        }

        return retMap;
    }
}

3-7 用户登录-编码实现前端页面

用户输入信息-----发送请求
login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%
<%--    相当于http://ip:port/项目名/--%>
	String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
	<base href="<%=basePath%>">
<meta charset="UTF-8">
<link href="jquery/bootstrap_3.3.0/css/bootstrap.min.css" type="text/css" rel="stylesheet" />
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
    <script type="text/javascript">
        $(function () {
    
            //给整个窗口添加键盘按下的事件
            $(window).keydown(function (e) {
    
                if(e.keyCode==13){
    
                    $("#loginBtn").click();//单击"登录"按钮
                }
            });

            //给"登录"按钮添加单击事件
            $("#loginBtn").click(function () {
    
                //搜集参数
                var loginAct=$("#loginAct").val();
                var loginPwd=$("#loginPwd").val();
                var isRemPwd=$("#isRemPwd").prop("checked");
                //表单验证
                if (loginAct==""){
    
                    alert("用户名不能为空");
                    return;
                }
                if (loginPwd==""){
    
                    alert("密码不能为空");
                    return;
                }
                //发送请求
                $.ajax({
    
                    url:'settings/qx/user/login.do',
                    data:{
    
                        loginAct:loginAct,
                        loginPwd:loginPwd,
                        isRemPwd:isRemPwd
                    },
                    type:'post',
                    dataType:'json',
                    success:function (data) {
    
                        if (data.code=="1"){
    
                            //跳转到业务主页面
                           window.location.href = "workbench/index.do";
                        }else{
    
                            $("#msg").text(data.message);
                        }
                    },
                    beforeSend:function () {
    //在发送ajax请求之前执行本函数,本函数会返回true或者false;返回值能够决定ajax是否真正发送请求:true-ajax会继续发送请求,false-ajax放弃发送请求。
                        $("#msg").text("正在验证....");
                        return true;
                    }
                });
            });
        });
    </script>
</head>
<body>
	<div style="position: absolute; top: 0px; left: 0px; width: 60%;">
		<img src="image/IMG_7114.JPG" style="width: 100%; height: 90%; position: relative; top: 50px;">
	</div>
	<div id="top" style="height: 50px; background-color: #3C3C3C; width: 100%;">
		<div style="position: absolute; top: 5px; left: 0px; font-size: 30px; font-weight: 400; color: white; font-family: 'times new roman'">CRM &nbsp;<span style="font-size: 12px;">&copy;2019&nbsp;动力节点</span></div>
	</div>
	
	<div style="position: absolute; top: 120px; right: 100px;width:450px;height:400px;border:1px solid #D5D5D5">
		<div style="position: absolute; top: 0px; right: 60px;">
			<div class="page-header">
				<h1>登录</h1>
			</div>
			<form action="workbench/index.html" class="form-horizontal" role="form">
				<div class="form-group form-group-lg">
					<div style="width: 350px;">
						<input class="form-control" id="loginAct" value="${cookie.loginAct.value}" type="text" placeholder="用户名">
					</div>
					<div style="width: 350px; position: relative;top: 20px;">
						<input class="form-control" id="loginPwd" value="${cookie.loginPwd.value}" type="password" placeholder="密码">
					</div>
					<div class="checkbox"  style="position: relative;top: 30px; left: 10px;">
						<label>
                            <c:if test="${not empty cookie.loginAct and not empty cookie.loginPwd}">
                                <input type="checkbox" id="isRemPwd" checked="true">
                            </c:if>
                            <c:if test="${empty cookie.loginAct or empty cookie.loginPwd}">
                                <input type="checkbox" id="isRemPwd">
                            </c:if>
                            十天内免登录
						</label>
						&nbsp;&nbsp;
						<span id="msg" style="color: red;"></span>
					</div>
                   <%--  异步请求,submit为同步请求--%>
					<button type="button" id="loginBtn" class="btn btn-primary btn-lg btn-block"  style="width: 350px; position: relative;top: 45px;">登录</button>
				</div>
			</form>
		</div>
	</div>
</body>
</html>

3-8 用户登录-测试基本功能

点击运行

3-9用户登录-登录成功之后所有页面显示用户名

3-10用户登录-实现10天免登录

3-11用户登录-实现回车登录

 //给整个窗口添加键盘按下的事件
            $(window).keydown(function (e) {
    
                if(e.keyCode==13){
    
                    $("#loginBtn").click();//单击"登录"按钮
                }
            });

3-12用户登录-显示登录状态

视频以及资源

资源链接,有需要自取!!!

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_43367377/article/details/119142233

智能推荐

端口扫描技术_在端口扫描中隐蔽扫描能够更精准的判断出端口是否开启-程序员宅基地

文章浏览阅读3.6k次。(79条消息) 端口扫描原理和划分_HideInTime的博客-程序员宅基地_扫描器通过什么来判断端口的状态一、端口分类固定端口(0-1023):TCP的21(ftp),80(http),139(netbios),UDP的7(echo),69(tftp)等等动态端口(1024-49151):这些端口并不被固定的捆绑于某一服务,操作系统将这些端口动态的分配给各个进程, 同一进程两次分配有可能分配到不同的端口二、常用端口扫描技术1. 全TCP连接Connect()扫描此扫描试图与每一..._在端口扫描中隐蔽扫描能够更精准的判断出端口是否开启

Android apk 分析工具:APK Analyzer_什么工具可以比较两个apk 之间的差异-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏6次。前言Android studio 2.2 版本后自带有一个分析工具:APK Analyzer。这是一个专门分析 apk 的神器,主要作用如下: 1. (重要) 直观的看到 apk 中各个文件的大小 (比如 DEX,resource 等等)。我们可根据文件大小信息,减小 apk 的大小; 2. (重要) 学习大企业 app 的命名规范和目录架构规范,还可以查看大公司 app 使用了什么技术和第三方_什么工具可以比较两个apk 之间的差异

web使用自动扫描器_web目录扫描器-程序员宅基地

文章浏览阅读448次。4、有了关于现有漏洞的信息,我们可以跟踪引用并搜索已发布的漏洞,例如,如果我们在用户注册表中搜索CVE-2007-5106,这是一个XSS 漏洞,我们将在Security Focus中找到一个漏洞:https://www.securityfocus.com/bid/25769/exploit。1、我们将扫描Pruggia 漏洞应用程序,并将结果导出到一个HTML报告文件,该命令为:nikto -h http://192.168.120.129/peruggia/-o result.html。_web目录扫描器

解决升级JDK后:找不到sun.misc.Unsafe的类文件_jdk.unsupported位置-程序员宅基地

文章浏览阅读1.1k次。JDK9以后已经将sun.misc.Unsafe弃用,同时改进了lib文件的存储方式,将sun.misc.Unsafe全部存储在了jdk.unsupported里面。_jdk.unsupported位置

C++字符串相加出错:invalid operands of types ‘const char [759]‘ and ‘const char [15]‘ to binary ‘operator+‘_invaild operands oftypes-程序员宅基地

文章浏览阅读1.2k次。但“”括起来的字符串被当成是字符串类型的,而非string类型,而字符串类型与C语言一样是不允许相加的,因此需要强制将其中一个字符串转为String类型。在C语言中字符串是不能直接相加的,在C++中,字符串是一个String类,允许相加。_invaild operands oftypes

C++信息学奥赛1138:将字符串中的小写字母转换成大写字母-程序员宅基地

文章浏览阅读1.9k次。C++信息学奥赛1138:将字符串中的小写字母转换成大写字母该段代码实现了将输入字符串中的小写字母转换为大写字母的功能。_信息学奥赛1138

随便推点

树莓派宝塔搭建NAS私有云盘nextcloud_宝塔做nas-程序员宅基地

文章浏览阅读2.2k次。宝塔新建网站:假设文件夹根目录为/home/nextcloud创建FTP,数据集。并且选择php版本。删除文件夹根目录/home/nextcloud下的两个html文件。下载nextcloud文件:官网链接可以使用wget:wget https://download.nextcloud.com/server/releases/nextcloud-20.0.0.zip,或者本地端下载后拖过去。多线程下载:sudo apt install axel axel -n 20 ht.._宝塔做nas

快学Scala 第一课 (变量,类型,操作符)-程序员宅基地

文章浏览阅读41次。Scala 用val定义常量,用var定义变量。常量重新赋值就会报错。变量没有问题。注意:我们不需要给出值或者变量的类型,scala初始化表达式会自己推断出来。当然我们也可以指定类型。多个值和变量可以一起声明:Scala 类型:Byte, Char, Short, Int, Long, Float, Double, BooleanScala不区分基...

Oracle分区查询_oracle查询分区数据-程序员宅基地

文章浏览阅读1.4w次,点赞4次,收藏19次。根据分区查询速度会快很多:分区查询:SELECT * FROM USER_TAB_PARTITIONS WHERE TABLE_NAME = '表名'分区键查询:SELECT * FROM all_PART_KEY_COLUMNS where name='表名';根据分区名查询:select * from 表名 partition('分区名');根据分区键查询:select * from 表名 partition where ACTDATETIME>=to_date('2022_oracle查询分区数据

使用JS判断移动设备的终端类型(浏览器UserAgent)_user-agent判断终端类型-程序员宅基地

文章浏览阅读8.5k次。JavaScript 是如何判断移动设备的类型呢?答案是:User Agent。什么是 User Agent?懂一点网页制作的人应该都明白。简单的说,User Agent 就是用来识别浏览器名称、版本、引擎以及操作系统等信息的内容。 User Agent 的判断是识别浏览器的关键,不仅仅如此,移动互联网开发势头迅猛,通过 User Agent 判断桌面端设备或移动设备就变的很为重要。当然,通过_user-agent判断终端类型

gz文件合并解压_hic的两个r1 gz文件合并-程序员宅基地

文章浏览阅读2.6k次。从veritas网站下载一个storage foundation 5.0的软件,for solaris的,下载了三段文件:sxrt5.0.dvd1.tar.gzaa sxrt5.0.dvd1.tar.gzab sxrt5.0.dvd1.tar.gzac gzcat sxrt5.0.dvd1.tar.gza[a-c]|tar xvf -二楼的办法_hic的两个r1 gz文件合并

SpringBoot:起步依赖-自动配置_spring-configuration-metadata.json-程序员宅基地

文章浏览阅读4.2k次,点赞3次,收藏8次。SpringBoot:起步依赖-自动配置_spring-configuration-metadata.json

推荐文章

热门文章

相关标签