您的位置:首页 > 编程语言 > Java开发

SpringBoot系列——Java配置(SpringMVC配置)

2018-02-06 17:51 741 查看
接下来我们来学习SpringMVC的Java配置方式,现在让我们来快速的搭建一个springMVC项目。

实例:

1. 构建Maven项目

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.shangfu</groupId>
<artifactId>Spring-Boot</artifactId>
<version>1.0-SNAPSHOT</version>

<properties>
<java.version>1.7</java.version>
</properties>

<dependencies>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.2.5.RELEASE</version>
</dependency>

<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.3</version>
</dependency>
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>

<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>

<!--jstl-->
<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>
</dependency>

<!--使用slf4j和LogBack作为日志-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.5</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.0.13</version>
</dependency>

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

<!--文件上传和下载-->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>

<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>

</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>${java.version}</source>
<target>${java.version}</target>
</configuration>
</plugin>
</plugins>
</build>

</project>


2. 日志配置

在src/main/resource目录下,新建一个logback.xml用来配置日志,内容如下:

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

<!-- scan="true"    当此属性设置为true时,配置文件如果发生改变,将会被重新加载,默认值为true。 -->
<!--  scanPeriod="30 seconds"   设置每30秒自动扫描,若没有指定具体单位则以milliseconds为标准(单位:milliseconds, seconds, minutes or hours)  -->
<!-- debug="false"当此属性设置为true时,将打印出logback内部日志信息,实时查看logback运行状态。默认值为false。-->
<configuration  scan="true" scanPeriod="30 seconds">

<!-- ch.qos.logback.core.ConsoleAppender 控制台输出 -->
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="console" />
</root>
</configuration>


3. 演示界面

在src/resources下建立views目录,并在此目录下新建index.jsp,内容如下

<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>Insert title here</title>
</head>
<body>
<pre>
Welcome to Spring MVC world
</pre>
</body>
</html>


4. SpringMVC配置

@Configuration
@EnableWebMvc  //开启SpringMVC注解
@ComponentScan("springmvc")
public class MyMvcConfig extends WebMvcConfigurerAdapter{
@Bean
public InternalResourceViewResolver viewResolver(){ //添加一个解析jsp的视图解析器
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setPrefix("/WEB-INF/classes/views/");
viewResolver.setSuffix(".jsp");
viewResolver.setViewClass(JstlView.class);
return viewResolver;
}
}


你可能对路径的前缀配置为WEB-INF/classes/views有些奇怪,怎麽和我开发的目录不一致,因为看到的页面的效果是运行时而不是开发时的代码,运行时的代码会将我们页面开发自动编译到/WEB-INF/classes/views下,所以我们的目录就应该写成这样!


6. 简单的controller

@Controller  //声明是一个控制器
public class HelloController {
@RequestMapping("/index") //配置URL与方法之间的映射
public String hello(){
return "index";  //返回试图解析名,
}
}


7. 运行

将程序部署到Tomcat中,启动Tomcat,并访问http://localhost:8080/项目名/index

结果如下:



SpringMVC的常用注解

@Controller

@Controller 注解在类上,表明这个类是SpringMVC中controller,将其声明为Spring的一个Bean,Dispatcher Servlet会自动扫描注解了次注解的类,并将web请求映射到注解了@ResquestMapping的方法上。这里特别指出,在声明普通的Bean的时候,使用@Component、@Service、@Repository和@Controller是等价的,但在声明控制器的时候,只能用@Controller

@RequestMapping

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。

返回值会通过视图解析器解析为实际的物理视图,对于 InternalResourceViewResolver 视图解析器,会做如下的解析:

通过 prefix + returnVal + suffix 这样的方式得到实际的物理视图,然后做转发操作;

RequestMapping注解有六个属性:

  1. value

  value:指定请求的实际地

  2. method

method: 指定请求的method类型, GET、POST、PUT、DELETE等,下面例子的@PathVariable后面讲解:

  3. consumes

consumes: 指定处理请求的提交内容类型(Content-Type),例如application/json, text/html

  4. produces

produces: 指定返回的内容类型,仅当request请求头中的(Accept)类型中包含该指定类型才返回;

  5. params

params: 指定request中必须包含某些参数值是,才让该方法处理。

  6. headers

headers: 指定request中必须包含某些指定的header值,才能让该方法处理请求。

@PathVariable

当使用@RequestMapping URI template 样式映射时, 即 someUrl/{paramId}, 这时的paramId可通过 @Pathvariable注解绑定它传过来的值到方法的参数上。

@RequestParam

@RequestParam用于将请求参数区数据映射到功能处理方法的参数上,用例:

@ResponseBody 

作用: 该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区。

使用时机:返回的数据不是html标签的页面,而是其他某种格式的数据时(如json、xml等)使用

@SessionAttributes

@SessionAttributes即将值放到session作用域中,写在class上面。  

@SessionAttributes 除了可以通过属性名指定需要放到会话中的属性外(value 属性值),

还可以通过模型属性的对象类型指定哪些模型属性需要放到会话中(types 属性值),用例:

注意: 该注解只能放在类的上面,不能放在方法上面


@ModelAttribute

代表的是:该Controller的所有方法在调用前,先执行此@ModelAttribute方法,可用于注解和方法参数中,可以把这个@ModelAttribute特性,应用在BaseController当中,所有的Controller继承BaseController,即可实现在调用Controller时,先执行@ModelAttribute方法。

@RestController

我们经常见到一些控制器实现了REST的API,只为服务于JSON,XML或其它自定义的类型内容,@RestController用来创建REST类型的控制器,与@Controller类型。@RestController就是这样一种类型,它避免了你重复的写@RequestMapping与@ResponseBody。

示例:

由于前面我们已经搭建好了后面学习的环境,所以后面我们直接写代码

1. 传值类

封装request对象参数和返回此对象到response

public class DemoObj implements Serializable{
private Long id;
private String name;
public DemoObj(){}

public DemoObj(Long id, String name) {
this.id = id;
this.name = name;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "DemoObj{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}


2. 注解演示控制器

@Controller  //声明此类是一个控制器
@RequestMapping("/anno")  //此方法的访问路径为/anno
public class DemoAnnoController {
@RequestMapping(produces = "text/plain;charset=UTF-8")  //定义返回数据类型为json
public @ResponseBody String index(HttpServletRequest request){  //接收参数为HttpServletResquest
return "url:"+request.getRequestURL()+"can access";
}

@RequestMapping(value="/pathvar/{str}",produces = "text/plain;charset=UTF-8")  //接收路径参数
public @ResponseBody String demoPathVar(@PathVariable String str, HttpServletRequest request){
return "url:"+request.getRequestURL()+"can access"+"  str:"+str;
}

@RequestMapping(value="/resquestParam" ,produces = "text/plain;charset=UTF-8")  //演示常规的request参数获取
public @ResponseBody String passRequestParam(Long id,HttpServletRequest request){
return "url:"+request.getRequestURL()+"can access ,id:"+id;
}

@RequestMapping(value="/obj" ,produces = "text/plain;charset=UTF-8")  //演示解释参数到对象
public @ResponseBody String passObj(DemoObj obj,HttpServletRequest request){
System.out.println(obj);
return "url:"+request.getRequestURL()+"can access , obj id:"+obj.getId()+"obj name:"+obj.getName();
}

@RequestMapping(value={"/name1","/name2"} ,produces = "text/plain;charset=UTF-8")
public @ResponseBody String remove(HttpServletRequest request){
return "url:"+request.getRequestURL()+"can access";
}

}


结果:

1.访问 localhost:8080/anno/

url:http://localhost:8080/anno/can access


2.访问 localhost:8080/anno/pathvar/2

url:http://localhost:8080/anno/pathvar/2can access  str:2


3. 访问 localhost:8080/anno/resquestParam?id=1

url:http://localhost:8080/anno/resquestParamcan access ,id:1


4. 访问 localhost:8080/anno/resquestParam?id=1&name=hyh

url:http://localhost:8080/anno/resquestParamcan access ,id:1


5. 访问 localhost:8080/anno/name2

url:http://localhost:8080/anno/name2can access


MVC基本配置

SpringMVC的定制配置需要我们的配置类继承一个
WebMvcConfigurerAdapter
类,并在此类使用
@EnableWebMvc
注解,来开启对SpringMVC的配置支持,这样我们就可以重写这个类的方法,完成我们的常用的配置。

1. 静态资源映射

程序的静态文件(js,css,img)等需要直接访问,这是我们可以在配置里重写addResourceHandlers方法来实现

示例:

1.添加静态资源

同上,我们在src/mian/resource/下建立一个assets/js目录,并复制一个jquery.js的文件,放置到下面



2.配置代码

在上面的WebMvcConfig的基础上添加下列代码

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//文件放置的目录     对外暴露的访问路径
registry.addResourceHandler("/assets/**").addResourceLocations("classpath:/assets/");
}


结果如下:



2. 拦截器设置

拦截器实现对每一个请求处理前后进行相关的业务处理,类似于Servlet的Filter

可让普通的Bean实现
HanlderInterceptor
接口或者继承
HandlerInterceptorAdapter
类来实现自定义拦截器

通过重写
WebMvcConfigurerAdapter
addInterceptors
方法来注册自定义的拦截器,本节实例为一个简单的拦截器:计算每一次请求的处理时间

示例:

1.自定义拦截器

public class DemoInterceptor extends HandlerInterceptorAdapter{  //自定义拦截器
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {  //请求方法前执行
long startTime = System.currentTimeMillis();
request.setAttribute("startTime",startTime );
return true;
}

@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { //请求方法后执行
long startTime = (long)request.getAttribute("startTime");
request.removeAttribute("startTime");
long endTime = System.currentTimeMillis();
System.out.println("本次请求时间为:"+ new Long(endTime-startTime)+"ms");
request.setAttribute("handlingTime", endTime-startTime);
}
}


2.配置

同上

@Bean
public DemoInterceptor demoInterceptor(){  //注册拦截器
return new DemoInterceptor();
}


3.运行



3.全局异常处理

通过
@ControllerAdvice
,我们可以将对于控制器的全局配置放置在同一个位置,注解了
@Controller
的类的方法可以使用
@ExceptionHandler
InitBinder
@ModelAttribute
注解到方法上,这对左右注解了
@ResquestMapping
的控制器内的方法有效

@ExceptionHandler:用于全局处理控制器里的异常

@InitBinder:用来设置WebDataBinder,WebDataBinder用来自动绑定前台请求参数到Moder中

@ModerAttribute:作用是绑定键值到Model中

示例:

1.定制ControllerAdvice

@ControllerAdvice  //声明控制器建言
public class ExceptionHandlerAdvice {
@ExceptionHandler(value = Exception.class)  //拦截所有Exception异常,通过value指定
public ModelAndView exception(Exception exception, WebRequest request){
ModelAndView modelAndView = new ModelAndView("error");
modelAndView.addObject("errorMessage",exception.getMessage());
return modelAndView;
}

@ModelAttribute  //将键值对添加到Model
public void addAttrbutes(Model model){
model.addAttribute("msg","额外信息");
}

@InitBinder  //注解定制WebDataBinder
public void initBinder(WebDataBinder webDataBinder){
webDataBinder.setDisallowedFields("id"); //忽略请求参数id
}

}


2.演示控制器

@Controller
public class AdviceController {
@RequestMapping("/advice")
public String getSomething(@ModelAttribute("msg") String msg, DemoObj obj){
throw new IllegalArgumentException("非常抱歉,参数有误/"+"  来自@ModelAttribute:"+msg);
}
}


3.异常界面

public abstract class WebMvcConfigurerAdapter implements WebMvcConfigurer {

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addFormatters(FormatterRegistry registry) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
}

/**
* {@inheritDoc}
* <p>This implementation returns {@code null}
*/
@Override
public Validator getValidator() {
return null;
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addReturnValueHandlers(List<HandlerMethodReturnValueHandler> returnValueHandlers) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public MessageCodesResolver getMessageCodesResolver() {
return null;
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addViewControllers(ViewControllerRegistry registry) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
}

/**
* {@inheritDoc}
* <p>This implementation is empty.
*/
@Override
public void addCorsMappings(CorsRegistry registry) {
}

}


其他的设置请自行参阅!无非就是重写方法而已

SpringMVC高级配置

1.文件上传配置

文件上传是一个项目里经常要用到的功能,SpringMVC通过配置一个MultipartResolver来上传文件

在Spring的控制器中,通过MultipartFile file来接收文件,通过MultipartFile[] files来接收多文件上传

示例:

1.上传页面

<%@ page contentType="text/html;charset=UTF-8" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>upload page</title>
</head>
<body>
<div>
<form action="upload" enctype="multipart/form-data" method="post">
<input type="file" name="file"/>
<input type="submit" value="上传"/>
</form>
</div>
</body>
</html>


2.添加转向到upload页面的ViewController

@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/welcome").setViewName("/index");
registry.addViewController("/toUpload").setViewName("/upload");
}


3.MultipartResolver配置

/*文件上传下载配置*/
@Bean
public MultipartResolver multipartResolver(){
CommonsMultipartResolver multipartResolver = new CommonsMultipartResolver();
multipartResolver.setMaxUploadSize(1000000);
return multipartResolver;
}


4.控制器

@Controller
public class UpAndLoadController {
@RequestMapping(value="/upload" , method = RequestMethod.POST)
public @ResponseBody String upload(MultipartFile file){  //使用MultipartFile file接收文件上传
try {
FileUtils.writeByteArrayToFile(new File("e:/"+file.getOriginalFilename()),file.getBytes());  //将文件写入硬盘
return "ok";
} catch (IOException e) {
e.printStackTrace();
return "wrong";
}
}
}


5.运行



结果



2.自定义HttpMessageConverter

自定义HttpMessageConverter来处理request和response数据

1.自定义HttpMessageConverter

public class MyMessageConverter extends AbstractHttpMessageConverter<DemoObj>{
public MyMessageConverter(){  //自定义媒体类型application/x-wisely
super(new MediaType("application","x-wisely", Charset.forName("UTF-8")));
}
@Override
protected boolean supports(Class<?> clazz) {
return DemoObj.class.isAssignableFrom(clazz);
}

@Override
protected DemoObj readInternal(Class<? extends DemoObj> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException { //处理请求数据
String temp = StreamUtils.copyToString(inputMessage.getBody(),Charset.forName("UTF-8"));
String[] tempArr = temp.split("-");
return new DemoObj(new Long(tempArr[0]),tempArr[1]);
}

@Override
protected void writeInternal(DemoObj obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {  //处理响应数据
String out = "hello:"+obj.getId()+"-"+obj.getName();
outputMessage.getBody().write(out.getBytes());
}
}


2.配置

@Bean
public MyMessageConverter converter(){
return new MyMessageConverter();
}
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { //添加自己的自定义消息处理器
converters.add(converter());
}


3.演示控制器

@Controller
public class ConverterController  {
@RequestMapping(value = "/convert",produces = {"application/x-wisely"}) //指定返回值类型为我们自定义类型
@ResponseBody
public DemoObj convert(DemoObj demoObj){
return demoObj;
}
}


4.运行

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  springmvc java配置