SSM + Shiro 整合 (3)- 添加 Spring MVC 成为 Web 项目

来源:互联网 发布:超级mac炮 编辑:程序博客网 时间:2024/06/15 01:51

项目源码:https://github.com/weimingge14/Shiro-project
演示地址:http://liweiblog.duapp.com/Shiro-project/login

  • SSM Shiro 整合 3- 添加 Spring MVC 成为 Web 项目
    • 步骤1 添加 Maven 的 依赖和 web 目录编写 webxml 部署描述符
    • 步骤2编写 webxml 文件
    • 步骤3编写 Spring MVC 的配置文件 spring-webxml
    • 步骤4编写控制层代码
    • 步骤5编写页面的代码举例
    • 步骤6启动 Maven 的 Jetty 插件运行

SSM + Shiro 整合 (3)- 添加 Spring MVC 成为 Web 项目

本节的目标是在项目中添加 Spring MVC 的支持。

步骤1 :添加 Maven 的 依赖和 web 目录,编写 web.xml 部署描述符。

<!-- Spring 的 Web 依赖 --><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-web</artifactId>    <version>${spring.version}</version></dependency><dependency>    <groupId>org.springframework</groupId>    <artifactId>spring-webmvc</artifactId>    <version>${spring.version}</version></dependency><!-- 一般 Web 项目的依赖 --><dependency>    <groupId>javax.servlet</groupId>    <artifactId>servlet-api</artifactId>    <version>3.0-alpha-1</version>    <scope>provided</scope></dependency><dependency>    <groupId>javax.servlet.jsp</groupId>    <artifactId>jsp-api</artifactId>    <version>2.2</version>    <scope>provided</scope></dependency><dependency>    <groupId>javax.servlet</groupId>    <artifactId>jstl</artifactId>    <version>1.2</version>    <scope>runtime</scope></dependency>

Java Web 项目的目录结构:

这里写图片描述
其中 index.jsp 文件、 jsp目录、resources目录、WEB-INF 下的 jsp 目录是根据业务需要添加的,不是必须的文件和目录。

注意:在 Maven 的配置文件中,还要声明打包的方式为 war:

<packaging>war</packaging>

步骤2:编写 web.xml 文件

<?xml version="1.0" encoding="utf-8"?><web-app xmlns="http://java.sun.com/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"         version="3.0">    <!-- 修改 Servlet 版本-->    <!-- 配置 DispatcherServlet-->    <servlet>        <servlet-name>springMVC</servlet-name>        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>        <init-param>            <param-name>contextConfigLocation</param-name>            <param-value>                classpath:spring/spring-web.xml            </param-value>        </init-param>        <load-on-startup>1</load-on-startup>        <async-supported>true</async-supported>    </servlet>    <servlet-mapping>        <servlet-name>springMVC</servlet-name>        <url-pattern>/</url-pattern>    </servlet-mapping>    <!-- 使用 ContextLoaderListener 加载 Spring 容器 -->    <context-param>        <param-name>contextConfigLocation</param-name>        <param-value>            classpath:spring/spring-service.xml,            classpath:spring/spring-dao.xml        </param-value>    </context-param>    <listener>        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>    </listener></web-app>

注意:
1、 <?xml version="1.0" encoding="utf-8"?> 这里节点的编码是 utf-8,如果是其它,则该 xml 文件不能保存中文。

<web-app xmlns="http://java.sun.com/xml/ns/javaee"         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee                      http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"         version="3.0">

<web-app> 节点的文档约束应该到 Tomcat 官网下载的示例代码里面去拷贝,version 属性的值应该为 3.0 或者 3.1 。
2、在这个配置文件中我们配置了 SpringMVC 也配置了 Spring。他们的关系是父子上下文关系。这点我们一定要清楚。
(1)Spring MVC 的容器是一个子容器,Spring 的容器是一个父级容器。它们处在不同的上下文中;
(2)Spring MVC 容器的组件可以访问 Spring 容器的组件;这一点就像我们的继承关系中,子类可以访问父类,但是父类不能够访问子类一样。

步骤3:编写 Spring MVC 的配置文件 spring-web.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-4.0.xsd        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">    <mvc:annotation-driven/>    <mvc:resources mapping="/resources/**" location="/resources/"/>    <context:component-scan base-package="com.liwei.shiro.web"/>    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>        <property name="prefix" value="/WEB-INF/jsp/"/>        <property name="suffix" value=".jsp"/>    </bean></beans>

步骤4:编写控制层代码

@Controller@RequestMapping(value = "/admin/user")public class UserController {    private static final Logger logger = LoggerFactory.getLogger(UserController.class);    @Autowired    private IUserService userService;    @Autowired    private IRoleService roleService;    @RequestMapping(value = "/list",method = RequestMethod.GET)    public String list(Model model){        model.addAttribute("list",userService.list());        return "user/list";    }    /**     * 跳转到添加用户的页面     * @param model     * @return     */    @RequestMapping(value = "/add",method = RequestMethod.GET)    public String add(Model model){        logger.debug("跳转到添加用户的页面");        // // TODO: 2016/9/18 为什么?        // 这里使用了 Spring 的表单,进行初始化和表单数据回显        model.addAttribute("user",new User());        model.addAttribute("roles",roleService.list());        return "user/add";    }    /**     * 添加用户保存的方法     * @param model     * @param user     * @param request     * @return     */    @RequestMapping(value = "/add",method = RequestMethod.POST)    public String add(Model model, User user, HttpServletRequest request){        logger.debug("添加用户 post 方法");        logger.debug(user.toString());        List<Integer> roleIdList = new ArrayList<>();        String[] roldIds = request.getParameterValues("roleId");        for(String roleId:roldIds){            roleIdList.add(Integer.parseInt(roleId));        }        userService.add(user,roleIdList);        // 重定向到本 Controller 的 list 方法(Get 方式)        return "redirect:list";    }    @ResponseBody    @RequestMapping(value = "/updateStatus",method = RequestMethod.POST)    public Map<String,Object> updateStatus(User user){        Integer updateNum = userService.update(user);        Map<String,Object> result = new HashMap<>();        if(updateNum > 0){            result.put("success",true);        }else {            result.put("success",false);            result.put("errorInfo","更新状态失败");        }        return result;    }    /**     * 跳转到用户信息更新页面     * @param id     * @param model     * @return     */    @RequestMapping(value = "/update/{id}",method = RequestMethod.GET)    public String update(@PathVariable("id") Integer id,Model model){        // 要从数据库查询对象进行回显        User user = userService.load(id);        model.addAttribute("user",user);        // 所有的角色列表        model.addAttribute("roles",roleService.list());        /**         * 根据用户 id 查询用户的所有角色         */        List<Role> hasRoles = userService.listUserRole(id);        /**         * 将用户的所有角色 id 添加到一个字符串中         */        List<Integer> rids = new ArrayList<>();        for(Role r:hasRoles) {            rids.add(r.getId());        }        // 指定用户拥有的角色信息        model.addAttribute("hasRole", rids);        return "user/update";    }    /**     * 更新用户的信息(包括更新用户绑定的角色)     * @param user     * @return     */    @RequestMapping(value = "/update/{id}",method = RequestMethod.POST)    public String update(User user,HttpServletRequest request){        // // TODO: 2016/9/18 这个过程还是可以优化的,如果属性没有发生变化的地方,是不须要更新的        logger.debug("user => " + user);        String[] roleIds = request.getParameterValues("roleId");        List<Integer> roleIdList = new ArrayList<>();        for(String roleId:roleIds){            roleIdList.add(Integer.valueOf(roleId));        }        userService.update(user,roleIdList);        return "redirect:/admin/user/list";    }    /**     *  根据用户 id 跳转到用户权限的列表页面     * @return     */    @RequestMapping(value = "/resources/{id}",method = RequestMethod.GET)    public String listResources(@PathVariable("id") Integer userId,Model model){        List<Resource> resourceList = userService.listAllResource(userId);        User user = userService.load(userId);        model.addAttribute("resources",resourceList);        model.addAttribute("user",user);        return "user/resources";    }}

步骤5:编写页面的代码(举例)

WEB-INF/jsp/user/list.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %><%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><html>    <head>        <title>用户列表</title>    </head>    <body>        <div class="container">            <jsp:include page="inc.jsp"></jsp:include>            <table class="table table-striped">                <thead>                    <tr class="info">                        <th>用户标识</th>                        <th>用户名</th>                        <th>密码</th>                        <th>用户昵称</th>                        <th>用户状态</th>                        <th>用户操作</th>                    </tr>                </thead>                <tbody>                    <c:forEach items="${list}" var="user">                        <tr>                            <td>${user.id}</td>                            <td>${user.username}</td>                            <td>${user.password}</td>                            <td>${user.nickname}</td>                            <td ><a class="status" data-id="${user.id}" data-status="${user.status}">启用</a></td>                            <td>                                <a href="${pageContext.request.contextPath}/admin/user/update/${user.id}">更新用户信息</a>                                <a href="${pageContext.request.contextPath}/admin/user/resources/${user.id}">查询用户权限</a>                            </td>                        </tr>                    </c:forEach>                </tbody>            </table>            用户操作:            <a class="btn btn-primary" role="button" href="${pageContext.request.contextPath}/admin/user/add">添加用户</a>        </div>        <%-- 不要使用自结束 --%>        <script type="text/javascript" src="${pageContext.request.contextPath}/resources/jquery-3.1.0.min.js"></script>        <script type="text/javascript">            $(function(){                $(".status").each(function(){                    var status = $(this).attr("data-status");                    var oper = $(this);                    if(status == 1){                        oper.text("禁用");                    }else {                        oper.text("启用");                    }                });                $(".status").on("click",function(){                    var oper = $(this);                    var user_id = oper.attr("data-id");                    var user_status = oper.attr("data-status");                    var update_status = (user_status == 1 ? 0: 1);                    $.post("${pageContext.request.contextPath}/admin/user/updateStatus",                            {                                id:user_id,                                status:update_status                            },function(data){                                if(data.success){                                    alert("修改状态成功!");                                    var oper_name = (update_status == 1 ? "禁用":"启用");                                    oper.attr("data-status",update_status);                                    oper.text(oper_name);                                }else{                                    alert("失败");                                }                            }                    );                });            })        </script>    </body></html>

说明:如果我们要使用 @ResponseBody 注解,应该添加依赖。

<dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-core</artifactId>    <version>2.8.1</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-databind</artifactId>    <version>2.8.1</version></dependency><dependency>    <groupId>com.fasterxml.jackson.core</groupId>    <artifactId>jackson-annotations</artifactId>    <version>2.8.1</version></dependency>

步骤6:启动 Maven 的 Jetty 插件运行

测试 SpringMVC 是否添加成功,还须要在容器中运行, Maven 提供了 Jetty 插件,可以帮助我们快速地完成 Web 项目的发布:

<!-- Jetty 插件:在本地部署测试更加方便 --><plugin>    <groupId>org.eclipse.jetty</groupId>    <artifactId>jetty-maven-plugin</artifactId>    <configuration>        <httpConnector>            <port>8080</port>        </httpConnector>    </configuration></plugin>

下一节我们介绍 整合 Shiro 的部分。

0 0