Spring 入门(二) 使用SpringMVC

1.Spring MVC依赖于Spring核心,实现了传统MVC三层架构

完整流程如下

可总结出 Spring MVC 的工作流程如下:
1.客户端请求提交到 DispatcherServlet。
2.由 DispatcherServlet 控制器寻找一个或多个 HandlerMapping,找到处理请求的 Controller。
3.DispatcherServlet 将请求提交到 Controller。
4.Controller 调用业务逻辑处理后返回 ModelAndView。
5.DispatcherServlet 寻找一个或多个 ViewResolver 视图解析器,找到 ModelAndView 指定的视图。
6.视图负责将结果显示到客户端。

DispatcherServlet、HandlerMapping、Controller 和 ViewResolver 是springMVC中比较重要4个接口,感兴趣可以查资料详细了解

2.创建SpringMVC项目

1.打开IDEA->new project->Maven 记得勾选create from archetype


直接点击到最后一步

2.创建完项目还缺少一些文件目录,需要建立缺少的文件夹

目录说明:
main/java 生产环境代码主目录
-com.mike 包名,根据情况建立
--common 公用类目录
--controller 控制器目录,处理客户端请求,调用service处理业务
--dao 数据访问对象查代码目录,主要是增删改
--entity 数据表实体类目录,与数据库表对应的类,属性与字段对应
--pojo 普通实体类目录,不需要与表属性对应
--service 服务类目录,主要是调用一个或多个dao

webapp 静态资源主目录
jsp jsp视图文件目录
web.xml文件 serlvet原生配置,在springmvc中主要是配置DispatcherServlet 来接管所有请求
springmvc-serlvet.xml文件 bean配置,配置视图解析器,及静态资源可见性,及使用@AutoWried自动注解时需要扫描的包目录

test/java 测试环境代码主目录
-com.mike 包名,根据情况建立

3.编写配置文件

1.在WEB-INF目录下找到web.xml 没有就新建

<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >

<web-app>
  <display-name>springMVC-demo1</display-name>
  <servlet>
    <servlet-name>springmvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springmvc</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

2.在WEB-INF下新建springmvc-servlet.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: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
           https://www.springframework.org/schema/context/spring-context.xsd
           http://www.springframework.org/schema/mvc
           http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--基于注解的注入需要配置扫描包-->
    <context:component-scan base-package="com.mike"/>
    <!-- annotation-driven用于简化开发的配置,注解DefaultAnnotationHandlerMapping和AnnotationMethodHandlerAdapter -->
    <mvc:annotation-driven/>
    <!--允许css目录下文件可见-->
    <mvc:resources location="/css/" mapping="/css/**" />
    <!-- 允许html目录下的所有文件可见 -->
    <mvc:resources location="/html/" mapping="/html/**"/>
    <!-- 允许image目录下的所有文件可见 -->
    <mvc:resources location="/images/" mapping="/images/**"/>
    <!--视图配置器-->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/jsp/" />
        <property name="suffix" value=".jsp"/>
    </bean>
</beans>

3.SpringMVC常用的注解

注解在java中的作用简单可以理解为代码中带@特殊标记,这些标记有不同种类,功能也不同,注解是java的语法特性,用户可以自定义注解,jdk也自带一些注解,这两种注解都会被jvm处理

  • javax.annotation.Resource包下的@Resource(name="bean_name") 自带注解,当一个构造方法,或setter,或属性被申明为@Resource注解时,容器会实例化其引用的对象实例,而无须手动实例化
  • org.springframework.stereotype.Controller包下的@Controller,申明该类为控制器,当客户端请求到来,会被用来处理请求
  • org.springframework.stereotype.Service包下的@Service ,申明该类为服务,可以在Controller调用该服务
  • org.springframework.stereotype.Repository包下的@Repository,申明该类为dao及数据访问对象,可以该类中实现对数据库增删改查
  • org.springframework.stereotype.Component 包下的@Component ,申明该类为普通的pojo类,及普通实体类
  • org.springframework.beans.factory.annotation.Autowired包下的@AutoWired; 申明后,使用容器自动注解,容器会根据xml中配置的包路径,扫描该引用的实例,并绑定到该类中
  • org.springframework.web.bind.annotation.RequestMapping下的@RequestMapping;申明后,将该方法与路由绑定,用户可以通过路由访问该方法

注意: 上述注解中 @Resource 和@AutoWired注解主要用来进行依赖注入,而当使用@AutoWried时,引用的类有多个实例时,建议使用@Qualifier注解,该注解基于name来查找实例,可以冲突

在springMVC中注入其他类基本上是利用spring核心的容器实现即

  • setter注入,
  • 构造方法注入
  • 属性注入
    下面简述一下使用三种方法注入

1.setter注入,推荐使用,当引用的对象可能会经常变化时使用


public class UserController {
    public UserService userService;
     
    @AutoWried
    public void setUserService(UserService userService) { // 在类中申明要引用类的setter方法,容器会自动注入该引用的类实例
        this.userService = userService
    }

    //使用userService 对象
}

2.构造方注入,也推荐使用,当引用的对象不经常变化时使用

public class UserController{
    public UserService userService;
    
    @AutoWried
    UserController(UserService userService) { //在类的构造方法参数中申明要引用类的变量,容器会自动注入该引用的实例
        this.userService = userService;
    }

    //使用userService对象
}

3.属性注入,该注入方式最简单,只需在引用的类属性上加入@AutoWried即可,但是不推荐使用该方法,spring官方也说明不推荐使用属性注入,具体原因可以查阅资料

public class UserController{
    @AutoWired
    public UserService userService;

    //使用userService对象
}

4.完整例子

在controller目录下新建UserController类文件

package com.mike.controller;

import javax.servlet.http.HttpSession;
import com.mike.pojo.UserForm;
import com.mike.service.UserService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;

@Controller
@RequestMapping(value="/user")
public class UserController {
    public UserService userService;

    @Autowired
    UserController(UserService userService) { //构造方法注入UserService实现类,当有多个UserService实现类使用@Qualifier注解
        this.userService = userService;
    }

//    @Autowired
//    public void setUserService(UserService userService) { // setter注入UserService实现类
//        this.userService = userService;
//    }

    @RequestMapping(value = "/login")
    public String login(UserForm user,HttpSession session,Model model) { //当表单name和UserForm的属性一致时会自动将表单值填入UserForm中
        if(userService.login(user)) { //判断用户名和密码是否正确
            session.setAttribute("user",user);
            System.out.println("登陆成功");
            return "main";
        } else {
            model.addAttribute("messageError","用户名或密码错误"); //当登陆失败提示信息,并跳转到登陆页面
            System.out.println("登陆失败");
            return "login";
        }
    }

    @RequestMapping(value="/register")
    public String register(UserForm user,Model model) {
        if(userService.register(user)) {
            System.out.println("注册成功");
            return "login";
        } else {
            model.addAttribute("username",user.getUsername());//注册失败将原来用户名重新显示在文本框
            System.out.println("注册失败");
            return "register";
        }
    }
}

在pojo目录下新建UserForm类文件

package com.mike.pojo;

public class UserForm {
    private String username;
    private String password;
    private String newPassword;


    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getNewPassword() {
        return newPassword;
    }

    public void setNewPassword(String newPassword) {
        this.newPassword = newPassword;
    }
}

在service目录下建立UserService接口及UserService接口的实现类UserServiceImpl

package com.mike.service;

import com.mike.pojo.UserForm;

public interface UserService {
    boolean login(UserForm user);
    boolean register(UserForm user);
}

package com.mike.service;

import com.mike.pojo.UserForm;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {
    public boolean login(UserForm user) {
        return "mike".equals(user.getUsername()) && "123".equals(user.getPassword());
    }

    public boolean register(UserForm user) {
        return "mike".equals(user.getUsername()) && "123".equals(user.getPassword());
    }
}

在jsp目录下分别新建login.jsp

<%--
  Created by IntelliJ IDEA.
  User: mike
  Date: 2021/1/6
  Time: 13:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <%@page isELIgnored="false" %> <!--应为默认的servlet1.2 el表达式是关闭的,需要启用-->
    <title>登陆</title>
</head>
<body>
<form action="<%request.getContextPath();%>/user/login" method="post" name="loginForm">
    <table>
        <tr>
            <td>姓名:</td>
            <td><input class="textSize" type="text" name="username"/></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input class="textSize" type="password" name="password"/></td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="submit" value="登陆"/>
            </td>
        </tr>
    </table>
    ${messageError}
</form>
</body>
</html>

register.jsp

<%--
  Created by IntelliJ IDEA.
  User: gaoyong
  Date: 2021/1/6
  Time: 13:03
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <%@page isELIgnored="false" %> <!--应为默认的servlet1.2 el表达式是关闭的,需要启用-->
    <title>注册</title>
</head>
<body>
<form action="<%request.getContextPath();%>/user/register" method="post" name="registerForm">
    <table>
        <tr>
            <td>姓名:</td>
            <td><input class="textSize" type="text" name="username" value="${username}"/></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input class="textSize" type="password" name="password"/></td>
        </tr>
        <tr>
            <td>确认密码:</td>
            <td><input class="textSize" type="password" name="newPassword"/></td>
        </tr>
        <tr>
            <td colspan="2" align="center">
                <input type="submit" value="注册"/>
            </td>
        </tr>
    </table>
</form>
</body>
</html>

main.jsp

<%@ page import="com.mike.pojo.UserForm" %><%--
  Created by IntelliJ IDEA.
  User: gaoyong
  Date: 2021/1/6
  Time: 14:43
  To change this template use File | Settings | File Templates.
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>登陆成功页面</title>
</head>
<body>
<% UserForm user = (UserForm)request.getSession().getAttribute("user");%>
<h1>当前登陆用户为:<%= user.getUsername() %></h1>
</body>
</html>

注意:控制器中如 login(UserForm user,HttpSession session,Model model)方法中的参数,user会在当页面的表单的name名和UserForm类中的属性一致时,自动填充到该类,而model参数会将我们写的信息返回到jsp页面
当我们访问http://localhost:8080/index/register 方法会看到注册表单register.jsp,输入mike,123,123 注册成功会跳转到登陆表单login.jsp,当我们再次输入mike,123登陆成功后会跳转到main.jsp会显示当前登陆的用户名

posted @ 2021-01-07 17:57  allgy  阅读(185)  评论(0编辑  收藏  举报