SpringMVC基础配置

Easter79
• 阅读 748

按:最近公众号文章主要是整理一些老文章,主要是个人CSDN上的博客,也会穿插一些新的技术点。


SpringMVC是什么,有多火,我这里就不再啰嗦了,SpringMVC比Struts2好用太多,我在学校的时候私下里两种都接触过,对比之后果断选择了SpringMVC,后来在做Android应用开发的时候,偶尔需要搭建一个后台服务,都是毫不犹豫的选择了SpringMVC作为首选。不过在之前使用SpringMVC的时候都是使用xml文件来进行配置的,那么这里我想换一种方式,通过Java注解来配置SpringMVC框架。OK,废话不多说,那我们就开始吧。对了,如果小伙伴对Spring的基本使用还不太了解,可以先参考这三篇文章:

Spring基础配置
Spring常用配置
Spring常用配置(二)

创建项目

为什么要说项目的创建呢?这是因为我自己之前一直使用STS做Web,后来因为Android Studio做久了,深深地爱上了IntelliJ IDEA,所以Web开发干脆也挪到IntelliJ IDEA上了,不过这个东西做Web还不太熟,掉进了一个项目创建的坑,所以这里稍微说一下项目的创建过程,避免其他小伙伴再掉坑。
1.创建普通Web Application

SpringMVC基础配置
注意创建的时候取消Create web.xml的选项,因为这里我将不通过xml进行SpringMVC的配置,而是通过注解的方式,后面的就是给项目取名字,然后一路下一步即可。
2.添加Maven支持

项目创建成功之后,选中项目,右键单击,选择第二项Add Framework Support,然后在新打开的页面中选择Maven,点击确定即可,如下:
SpringMVC基础配置
这样就成功创建了一个被Maven管理的Web项目了。
OK,关于项目创建流程这个问题如果小伙伴们有更好的方式欢迎留言讨论。

添加依赖库

这里涉及到的依赖库略多,我们来看看:

    <properties>
        <spring-framework.version>4.3.4.RELEASE</spring-framework.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>javax</groupId>
            <artifactId>javaee-api</artifactId>
            <version>7.0</version>
            <!--http://blog.csdn.net/daihui05/article/details/7476976-->
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring-framework.version}</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</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>

        <dependency>
            <groupId>javax.servlet.jsp</groupId>
            <artifactId>jsp-api</artifactId>
            <version>2.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>${spring-framework.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.1.8</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.1.8</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-access</artifactId>
            <version>1.1.8</version>
        </dependency>

    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>3.6.0</version>
            </plugin>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-war-plugin</artifactId>
                <version>3.0.0</version>
                <configuration>
                    <failOnMissingWebXml>false</failOnMissingWebXml>
                </configuration>
            </plugin>
        </plugins>
    </build>

但实际上每个依赖库的用处都是非常清晰的,slf4j和LogBack这两个主要是用来打印日志的,jstl支持页面的创建,这些都是JavaEE中非常常见的库,我就不再赘述了。

创建演示页面

由于这一系列文章,我主要是想介绍Spring Boot的使用,所以这里我把jsp文件创建在src/main/resources/views/目录下。如下图:
SpringMVC基础配置
在resources目录下还有一个logback.xml文件,这个文件是用来打印日志的,这个文件小伙伴们一会可以直接下载。

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Hello SpringMVC</title>
</head>
<body>
<h1>Welcome to SpringMVC world!</h1>
</body>
</html>

这个jsp页面很简单,只有一行文字。

SpringMVC配置

老子《道德经》第六十四章:“合抱之木,生于毫末;九层之台,起于垒土;千里之行,始于足下。”

这里我们先看SpringMVC中最基本最简单的配置,完了之后我们再来看复杂的配置。

@Configuration
@EnableWebMvc
@ComponentScan("org.sang")
public class MyMVCConfig {
    @Bean
    public InternalResourceViewResolver viewResolver() {
        InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
        //前缀
        viewResolver.setPrefix("/WEB-INF/classes/views/");
        //后缀
        viewResolver.setSuffix(".jsp");
        viewResolver.setViewClass(JstlView.class);
        return viewResolver;
    }
}

OK,@EnableWebMvc表示开启SpringMVC中一些默认配置,ViewResolver是SpringMVC视图渲染的核心机制,SpringMVC框架中有一个ViewResolver接口,该接口有一个方法叫做resolveViewName,该方法返回一个View对象,这个View的职责就是结合request、response对象,将渲染的视图返回给浏览器,渲染后的视图可以是HTML,也可以是json、xml、PDF等。另外,由于项目编译之后运行的时候,index.jsp 文件是处于/WEB-INF/classes/views/目录下的,所以前缀为/WEB-INF/classes/views/。

Web配置

public class WebInitializer implements WebApplicationInitializer {
    public void onStartup(ServletContext servletContext) throws ServletException {
        AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
        ctx.register(MyMVCConfig.class);
        ctx.setServletContext(servletContext);
        ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcher", new DispatcherServlet(ctx));
        servlet.addMapping("/");
        servlet.setLoadOnStartup(1);
    }
}

这里的代码对照xml配置也都很好理解,首先我们自定义类实现WebApplicationInitializer接口,并实现该接口中的onStartup方法,该方法在Spring容器启动之后就会被自动调用,然后创建AnnotationConfigWebApplicationContext的实例并加载我们的SpringMVC的配置文件,这一步其实也可以通过加载xml文件来完成,当然,这是另外一个话题了。最后创建DispatcherServlet,并设置映射方式以及启动时机等。

创建一个简单控制器

@Controller
@RequestMapping("/index1")
public class HelloController {
    @RequestMapping("/index2")
    public String hello(HttpServletRequest request) {
        System.out.println(request.getParameter("username"));
        return "index";
    }
}

首先利用@Controller注解声明这是一个控制器,在前面的文章中我们说过@Controller和@Service等可以混用,但是在使用SpringMVC时声明控制器Bean的时候,却只能够使用@Controller;然后利用@RequestMapping来配置URL和方法之间的映射关系,@RequestMapping这个注解我们可以使用在类上,也可以使用在方法上,如果用在方法上,则方法上的路径会继承类上的路径,另一方面,使用了@RequestMapping注解的方法也可以添加request或者response参数。

部署项目并运行

OK,做完上面几个步骤之后我们就可以来运行项目了,我们来看看运行结果:
SpringMVC基础配置
.
本案例下载地址:

本案例GitHub地址

OK,上面是一个简单的SpringMVC注解配置,可能很多小伙伴看的还不过瘾,那我们再来说说另外几个注解配置。
1.@ResponseBody 这个注解可以让我们将返回值放在response体内,而不是返回一个html页面,当我们在移动端比如Android、或者通过Ajax来访问服务端的数据的时候,就可以通过这个注解。
2.@RequestBody 这个注解允许request的参数在request体中,而不是直接放在地址后面。
3.@PathVariable 这个注解用来接收路径参数
4.@RestController 这是一个组合注解,组合了@Controller和@ResponseBody两个,在开发中我们可以用@RestController这一个,也可以用后面两个,使用这个可以自动将一个对象转为xml或者json返回给客户端。

OK ,结合上面说的这几个注解,我们来看看几个案例。
首先我们来重新创建一个Project,创建方式和上面说的一样,创建成功之后添加依赖,依赖也和上面一致,只不过这里多添加两个,一个是json转化工具类,一个是xml转化工具类。如下(注释中已经列出请求地址以及请求结果):

        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.8.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.dataformat</groupId>
            <artifactId>jackson-dataformat-xml</artifactId>
            <version>2.8.5</version>
        </dependency>

其他的SpringMVC的配置以及Web配置还是和上文一致,接下来我们来我们主要来看看控制器:

@Controller
@RequestMapping("/user")
public class UserController {
    //http://localhost:8080/user/
    @ResponseBody
    @RequestMapping(produces = "text/plain;charset=UTF-8")//produces描述的是响应的头信息的Content-Type字段
    public String user(HttpServletRequest request) {
        //url:http://localhost:8080/user can access
        return "url:" + request.getRequestURL() + " can access";
    }
    //http://localhost:8080/user/user/张三
    @ResponseBody
    @RequestMapping(value = "/user/{str}",produces = "text/plain;charset=UTF-8")
    public String pathVar(@PathVariable String str, HttpServletRequest request) {
        //url:http://localhost:8080/user/user/%E5%BC%A0%E4%B8%89 can access , str is 张三
        return "url:" + request.getRequestURL() + " can access , str is " + str;

    }

    //http://localhost:8080/user/rp?id=100
    @ResponseBody
    @RequestMapping(value = "/rp",produces = "text/plain;charset=UTF-8")
    public String requestParams(long id, HttpServletRequest request) {
        //url:http://localhost:8080/user/rp can access , username is :100
        return "url:" + request.getRequestURL() + " can access , username is :" + id;
    }

    //http://localhost:8080/user/json?username=%E5%BC%A0%E4%B8%89&password=123
    @ResponseBody
    @RequestMapping(value = "/json", produces = "application/json;charset=UTF-8")
    public String passObj(UserBean user, HttpServletRequest request) {
        Gson gson = new Gson();
        //{"username":"张三","password":"123"}
        return gson.toJson(user);
    }

    @ResponseBody
    @RequestMapping(value = "/getJson",produces = "application/json;charset=UTF-8")
    public UserBean passObj(UserBean userBean) {
        return userBean;
    }

    //http://localhost:8080/user/n1
    //http://localhost:8080/user/n2
    @ResponseBody
    @RequestMapping(value = {"/n1","/n2"},produces = "text/plain;charset=UTF-8")
    public String group() {
        //不同路径定位到同一方法
        return "不同路径定位到同一方法";
    }

}

关于这里的方法我说以下几点:
1.方法中的参数是任意的,可以有可以无,也可以有HttpServletRequest和HttpServletResponse类型的参数,使用方式和Servlet中一致。
2.参数可以接收基本数据类型和任何对象。如果是对象,比如我在客户端传递参数时可以传递http://localhost:8080/user/json?username=%E5%BC%A0%E4%B8%89&password=123,这个时候系统会自动将最后两个参数转为一个UserBean对象交给我。
3.@PathVariable注解可以帮助我们提取请求地址中的字段
4.@RequestMapping注解中的value可以有多个值,这样可以实现多个地址请求到同一个方法。
5.如果想给服务端返回一个json字符串或者xml字符串,直接返回一个对象即可,至于这个对象最终会被转为json还是xml,我们可以通过produces = "application/json;charset=UTF-8"或者produces = "application/xml;charset=UTF-8"来定义。

OK,我们也可以使用我们上文提到的组合注解@RestController,使用方式如下:

@RestController
@RequestMapping("/rest")
public class MyRestController {
    //http://localhost:8080/rest/getJson?username=%E5%BC%A0%E4%B8%89&password=999
    @RequestMapping(value = "/getJson",produces = "application/json;charset=UTF-8")
    public UserBean getJson(UserBean userBean) {
        return userBean;
    }

    //http://localhost:8080/rest/getXml?username=%E5%BC%A0%E4%B8%89&password=999
    @RequestMapping(value = "/getXml",produces = "application/xml;charset=UTF-8")
    public UserBean getXML(UserBean userBean) {
        return userBean;
    }
}

使用@RestController注解,我们可以避免写@Controller和@ResponseBody。这两个方法返回结果分别如下:

SpringMVC基础配置

SpringMVC基础配置

本案例下载地址

本案例GitHub地址

以上。

参考资料:
《JavaEE开发的颠覆者 Spring Boot实战》第四章

本文分享自微信公众号 - 江南一点雨(a_javaboy)。
如有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Easter79 Easter79
3年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Wesley13 Wesley13
3年前
00:Java简单了解
浅谈Java之概述Java是SUN(StanfordUniversityNetwork),斯坦福大学网络公司)1995年推出的一门高级编程语言。Java是一种面向Internet的编程语言。随着Java技术在web方面的不断成熟,已经成为Web应用程序的首选开发语言。Java是简单易学,完全面向对象,安全可靠,与平台无关的编程语言。
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
3年前
Docker 部署SpringBoot项目不香吗?
  公众号改版后文章乱序推荐,希望你可以点击上方“Java进阶架构师”,点击右上角,将我们设为★“星标”!这样才不会错过每日进阶架构文章呀。  !(http://dingyue.ws.126.net/2020/0920/b00fbfc7j00qgy5xy002kd200qo00hsg00it00cj.jpg)  2
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k