构建一个spring mvc web程序

在学习spring secuity之前我们先构建一个spring mvc的web程序,以后的spring secuity就在这个web程序基础上去构建。

  • 加入依赖
    我们使用maven构建项目,我们加入了springmvcservlet相关的依赖,并且加入了jetty插件,可以不使用外部容器的情况下去运行启动项目,依赖如下:
<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.3.13.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
    </dependencies>


    <build>
        <finalName>springmvc-web</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.3.v20170317</version>
                <configuration>
                    <httpConnector>
                        <port>8001</port>
                    </httpConnector>
                    //配置contextPath为/
                    <webApp>
                        <contextPath>/</contextPath>
                    </webApp>
                </configuration>
            </plugin>
        </plugins>
    </build>
  • 首先定义系统启动根类

配置的@EnableWebMvc注解的类需要继承WebMvcConfigurerAdapter,来做一下回调配置(比如说自己定义的类型转换器,自己定义的拦截器等),详细了解可以点击查看@EnableWebMvc的源码备注

@EnableWebMvc
@ComponentScan("com.zhihao.miao.mvc")
public class WebAppConfig extends WebMvcConfigurerAdapter {

    public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
        //配置默认的DefaultServletHttpRequestHandler(静态资源默认使用的servlet),DefaultServletHttpRequestHandler是HttpRequestHandler的默认实现,
        configurer.enable();
    }

}
  • 其他的一些配置
/**
 * 系统启动类,配置url过滤的url
 */
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        //以我的理解就是以WebAppConfig来创建spring 容器上下文
        return new Class<?>[]{WebAppConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[]{"/*"};
    }
}
  • 定义自己的Controller
@RestController
public class HelloController {

    @GetMapping("/hello")
    public String hello(){
        return "hello spring mvc web";
    }

    @GetMapping("/home")
    public String home(){
        return "home spring mvc web";
    }

    @GetMapping("/admin")
    public String admin(){
        return "admin spring mvc web";
    }
}
  • 测试

访问下面三个接口,都可以访问,

http://localhost:8001/hello
http://localhost:8001/home
http://localhost:8001/admin
  • url的组成

这边说明一下url地址的一些组成,比如说http://127.0.0.1:8081/home,其可以看成http[s]://[host]:[port][request url][?queryString],而request url = [context path][servlet path][path info],url路径除了context pathservlet path之外就是path_info了,我们这边没有配置context pathservlet path

修改一下Controller,

@RestController
public class HelloController {

@GetMapping("/hello")
public String hello(HttpServletRequest req){
    System.out.println("==================");
    System.out.println(" req.getRequestURI(): " + req.getRequestURI());
    System.out.println(" req.getContextPath(): " + req.getContextPath());
    System.out.println(" req.getServletPath(): " + req.getServletPath());
    System.out.println(" req.getPathInfo(): " + req.getPathInfo());
    System.out.println("==================");
    return "hello spring mvc web";
}

@GetMapping("/home")
public String home(){
    return "home spring mvc web";
}

@GetMapping("/admin")
public String admin(){
    return "admin spring mvc web";
}

}

控制台打印:

==================
 req.getRequestURI(): /hello
 req.getContextPath(): 
 req.getServletPath(): 
 req.getPathInfo(): /hello
==================
  • 我们修改pom文件的jetty插件的context path

如下,

<build>
        <finalName>springmvc-web</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.eclipse.jetty</groupId>
                <artifactId>jetty-maven-plugin</artifactId>
                <version>9.4.3.v20170317</version>
                <configuration>
                    <httpConnector>
                        <port>8001</port>
                    </httpConnector>
                    <webApp>
                        <!--修改contextPath>
                        <contextPath>/web</contextPath>
                    </webApp>
                </configuration>
            </plugin>
        </plugins>
</build>

此时访问的url地址就改成了:

http://localhost:8001/web/hello

控制台打印:

==================
 req.getRequestURI(): /web/hello
 req.getContextPath(): /web
 req.getServletPath(): 
 req.getPathInfo(): /hello
==================
  • 我们再去修改servlet path,修改配置类中
public class WebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {
        //以我的理解就是以WebAppConfig来创建spring 容器上下文
        return new Class<?>[]{WebAppConfig.class};
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {
        return null;
    }

    /**
     * url mapping 通常有三种配置方式
     *
     * 1: /*
     * 2: /aaa/*, /aaa/bbb/*
     * 3: *.do, *.action
     *
     * 第一种配置方式 servlet Path 为空
     * 第二种配置方式 servlet Path /aaa, /aaa/bbb/
     * 第三种配置方式servlet Path /aaa/bbb.do, /aaa/bbb.action
     *
     */
    @Override
    protected String[] getServletMappings() {
        return new String[]{"/v1/*","/v2/*"};
    }
}

此时访问路径:

http://localhost:8001/web/v1/hello

控制台打印:

==================
 req.getRequestURI(): /web/v1/hello
 req.getContextPath(): /web
 req.getServletPath(): /v1
 req.getPathInfo(): /hello
==================

或者:

http://localhost:8001/web/v2/hello

控制台打印:

==================
 req.getRequestURI(): /web/v2/hello
 req.getContextPath(): /web
 req.getServletPath(): /v2
 req.getPathInfo(): /hello
==================

讲到这边一个基于spring web构建的web程序已经搭建成功,并且可以进行访问了,我们发现我们应用暴露的url地址不管是谁都可以访问,这样是不安全的,我们希望其得到一些权限认证,不同的人员认证之后才可以访问具体的资源。而spring secuity就是为了解决这个问题的,当然spring secuity框架能为我们做的事情不仅如此。

Spring Security

Spring Security is a powerful and highly customizable authentication and access-control framework. It is the de-facto standard for securing Spring-based applications.
Spring Security是一个强大的且高度可定制化的身份认证和访问控制框架。是一个基于Spring之上的一个提供安全解决方案的框架

  • 特征
  1. 多种认证方式HTTP BASIC,HTTP Digest(HTTP摘要认证),X.509,LDAP。Form-based(HTTP表单认证),OpenID,CAS
  2. 多种权限验证,支持基于URL的权限验证,方法的权限验证等
  3. 多种安全领域的解决方案,XSS,XSRF,CORS,session管理,单点登录(CAS),OAuth等等。
  4. 强大的可扩展性,可配置性
  5. 基于官方Java Config(注解)和xml的配置方式
  6. 官方集成springboot,大大简化了spring security的开发难度。

参考资料

官方文档
Spring Security 从入门到进阶系列教程

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,277评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,777评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,946评论 0 245
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,271评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,636评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,767评论 1 221
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,989评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,733评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,457评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,674评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,155评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,518评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,160评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,114评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,898评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,822评论 2 280
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,705评论 2 273

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,103评论 18 139
  • Spring Boot 参考指南 介绍 转载自:https://www.gitbook.com/book/qbgb...
    毛宇鹏阅读 46,377评论 6 343
  • 要加“m”说明是MB,否则就是KB了. -Xms:初始值 -Xmx:最大值 -Xmn:最小值 java -Xms8...
    dadong0505阅读 4,763评论 0 53
  • 在我搭建基于Spring Cloud的微服务体系应用的时候所需要或者是常用的属性配置文件,还有这些属性的用途,此配...
    StrongManAlone阅读 3,899评论 0 18
  • 一提到爱情,相比绝大多数人想到的是那种心跳的感觉,两个人相望一笑的美好。期待一场美好的爱情便是生命中最值得的等待。...
    风写阅读 386评论 0 1