文档章节

SpringBoot 使用笔记

noob_fly
 noob_fly
发布于 2017/07/24 15:39
字数 1353
阅读 511
收藏 1

码上生花,ECharts 作品展示赛正式启动!>>>

SpringBoot文档: https://docs.spring.io/spring-boot/docs/2.0.4.RELEASE/reference/htmlsingle/#boot-features-external-config-application-property-files

pom

默认打成jar,在pom.xml中指定mainClass。项目根目录下执行mvn package生成可执行的jar包, jar包中MANIFEST.MF文件会显示mainclass。

<properties>
    <mainClass>com.noob.Bootstrap</mainClass>
</properties>

<plugins> 
  <plugin> 
    <groupId>org.springframework.boot</groupId>  
    <artifactId>spring-boot-maven-plugin</artifactId>  
    <version>${spring-boot.version}</version>  
    <configuration> 
      <fork>true</fork> 
    </configuration>  
  </plugin> 
</plugins>

 

SpringMvc 设置 HttpMessageConverter 处理时间等字段的转义

  1. 第一种: 局部修改 。 针对response的每一个bean增加:
    @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss",timezone = "GMT+8")
    
  2. 第二种: 全局修改MappingJackson2HttpMessageConverter。 
    处理@RequestBody与@ResponseBody的实现类RequestResponseBodyMethodProcessor调用超类AbstractMessageConverterMethodArgumentResolver.readWithMessageConverters 处理请求、响应时解析数据使用。
    ObjectMapper中可以指定序列化及反序列化时特性
    @Bean
    public HttpMessageConverter<?> getMappingJackson2HttpMessageConverter() {
    	MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
    	ObjectMapper objectMapper = new ObjectMapper();
    	objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    	objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
    	// 设置日期格式
    	SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	objectMapper.setDateFormat(smt);
    	mappingJackson2HttpMessageConverter.setObjectMapper(globalObjectMapper);
    	// 设置中文编码格式
    	List<MediaType> list = new ArrayList<MediaType>();
    	list.add(MediaType.APPLICATION_JSON_UTF8);
    	mappingJackson2HttpMessageConverter.setSupportedMediaTypes(list);
    	return mappingJackson2HttpMessageConverter;
    }
    也可以通过以下方式注入:
    import java.text.SimpleDateFormat;
    import java.util.List;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.http.converter.HttpMessageConverter;
    import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
    import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
    import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
    
    @Configuration
    public class WebConfiguration implements WebMvcConfigurer {
    	@Override
    	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
    		Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder().indentOutput(true)
    				.dateFormat(new SimpleDateFormat("yyyy-MM-dd"));
    		converters.add(new MappingJackson2HttpMessageConverter(builder.build()));
    	}
    
    }

     

WebMvcConfigurationSupport 用来初始化SpringMVC重要bean:  RequestMappingHandlerMapping、HttpMessageConverter、HandlerMethodReturnValueHandler、HandlerMethodArgumentResolver等。
WebMvcAutoConfiguration 自动注入了 EnableWebMvcConfiguration (extends DelegatingWebMvcConfiguration ,实际上就是 WebMvcConfigurationSupport 的实现,构建bean提供属性配置),等价于@EnableWebMvc。

如果外部申明使用@EnableWebMvc,将直接执行DelegatingWebMvcConfiguration ,此时只有WebMvcConfigurer里的配置生效,失去WebMvcAutoConfiguration中自动默认配置
 

静态资源和拦截器处理

addResourceLocations指的是文件放置的目录,addResoureHandler指的是对外暴露的访问路径。

@Configuration
public class NoobMvcConfigurer implements WebMvcConfigurer {
    /**
     * 配置静态访问资源
     * @param registry
     */
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**").addResourceLocations("classpath:/noob/");
    }
}

若指定外部的目录:

registry.addResourceHandler("/**").addResourceLocations("file:E:/noob/");

一般SpringMVC访问页面要写Controller类,然后再写一个方法跳转到页面,重写WebMvcConfigurer 中的addViewControllers方法即可达到效果:

/**
  * 直接访问http://localhost:8080/toLogin就跳转到login.jsp页面
  */
@Override
public void addViewControllers(ViewControllerRegistry registry) {
   registry.addViewController("/toLogin").setViewName("login");
}

增加拦截器:

addPathPatterns 用于添加拦截规则 excludePathPatterns 用户排除拦截

@Override
public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("/toLogin","/login");
}

SpringBootTest

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

读取某个 application- 开头的properties或yml中的属性:  application-dev.properties     application-dev.yml  

  1. org.springframework.test.context.ActiveProfiles
    @RunWith(SpringRunner.class)
    @ActiveProfiles("test") // 指定使用application-test.yml
    @SpringBootTest(classes = TrustsServerApplication.class)
    public class BaseTest {}
  2. org.springframework.test.context.TestPropertySource:   可用于有选择地覆盖系统和应用程序属性源中定义的属性
    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = TrustsServerApplication.class)
    @TestPropertySource(properties = { "spring.config.location = classpath:test.properties" })
    public class BaseTest {}

    @SpringBootTest 本身也可以设置properties 来给 Environment 注入属性值:  @SpringBootTest(classes = CbmsOpenApp.class, properties = {"spring.profiles.active=dev"})

在如下图的使用方式:

@ActiveProfiles("test") 、 @TestPropertySource(properties = {"spring.profiles.active=test"})、 @SpringBootTest(classes = CbmsOpenApp.class, properties = {"spring.profiles.active=test"})
虽然打印出如下日志:

2020-03-19 17:16:36.821 [main] INFO  [trace=,span=,parent=] c.u.f.c.o.h.a.r.ContractSignServiceTest - The following profiles are active: test

但真实情况是: 只是会 覆盖 dev目录下application.yml中的“spring.profiles.active”值,使用的还是 dev目录 编译后的配置,并不是test目录下配置文件。(maven 编译用的配置是dev)

MockMvc模拟http请求

测试用例:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ContractSignApp.class)
@AutoConfigureMockMvc
public class NoobTest {
	@Autowired
	protected MockMvc mockMvc;

	@Test
	public void test3() throws Exception {
		try {
			Map<String, String> postParam = Maps.newHashMap();
			postParam.put("test", "testPpp");
			System.out.println(mockMvc
					.perform(MockMvcRequestBuilders.post("/noob/postFun1").contentType(MediaType.APPLICATION_JSON_UTF8)
							.content(JSONObject.toJSONString(postParam)))
					.andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn()
					.getResponse().getContentAsString());
			System.out.println(mockMvc
					.perform(MockMvcRequestBuilders.get("/noob/getFun2").contentType(MediaType.APPLICATION_JSON_UTF8)
							.param("param1", "param1").param("param2", "param2"))
					.andExpect(MockMvcResultMatchers.status().isOk()).andDo(MockMvcResultHandlers.print()).andReturn()
					.getResponse().getContentAsString());
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

}

Controller:

@RestController
@RequestMapping("/noob")
public class NoobController {

	@PostMapping("/postFun1")
	public String fun1(@RequestBody Map<String, String> map) {
		return map.get("test");
	}

	@GetMapping("/getFun2")
	public String fun2(@RequestParam("param1") String param1, @RequestParam("param2") String param2) {
		return param1 + "_" + param2;
	}

	@GetMapping("/getFun3")
	public String fun3(String param1, Long param2) {
		return param1 + "_" + param2;
	}
}

Controller层接收List类型的参数

后端:

@PostMapping(value = "/reSignForUse")
public void reSignForUse(@RequestBody @NotNull List<String> loanNos) { ... }

前端ajax: 直接传递数组json字符串

外部tomcat

可内嵌容器:

步骤:

  1. 修改pom.xml:
    <packaging>war</packaging>
    
    <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-starter-web</artifactId>
    	<version>1.3.6.RELEASE</version>
        <!-- 移除嵌入式tomcat插件 -->
        <exclusions>
          <exclusion>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
          </exclusion>
        </exclusions>
    </dependency>
    打成war包的名称须和application.properties中server.context-path=/projectName 一致。
    <build>
        <finalName>projectName</finalName>
    </build>

    spring-boot-starter-web内嵌tomcat, 如果需要本地调试可以不移除。

  2. 添加servlet-api的依赖(二选一)

    <dependency>
      <groupId>javax.servlet</groupId>
      <artifactId>javax.servlet-api</artifactId>
      <version>3.1.0</version>
      <scope>provided</scope>
    </dependency>
    
    <dependency>
      <groupId>org.apache.tomcat</groupId>
      <artifactId>tomcat-servlet-api</artifactId>
      <version>8.0.36</version>
      <scope>provided</scope>
    </dependency>
  3. 启动类继承SpringBootServletInitializer类:
    public abstract class SpringBootServletInitializer implements WebApplicationInitializer 
    @SpringBootApplication(scanBasePackages = { "com.noob.loan.route" })
    @ImportResource(locations = "classpath*:spring/applicationContext.xml")
    @MapperScan(basePackages = "com.noob.loan.route.dao")
    @Slf4j
    public class RouteConsoleBootstrap extends SpringBootServletInitializer {
    
    	private static Class<RouteConsoleBootstrap> applicationClass = RouteConsoleBootstrap.class;
    
    	@Override
    	protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
    		return builder.sources(applicationClass);
    	}
    
    	/**
    	 * 还有一种:in a single line in application.properties:
    	 * server.context_parameters.p-name=-value
    	 * 
    	 */
    	@Override
    	public void onStartup(ServletContext servletContext) throws ServletException {
    		servletContext.setAttribute("contextConfigLocation",
               "classpath*:applicationContext.xml"); // 测试结果该设置无效,设置前后都为<NONE>
    		servletContext.setAttribute("failUrl", "/");
    		servletContext.setAttribute("unauthorizedUrl", "/deny.jsp");
    		servletContext.setAttribute("notFilterUrl", "");
    		super.onStartup(servletContext);
    	}
    
    	public static void main(String[] args) {
    		new SpringApplicationBuilder(applicationClass).run(args);
    	}
    }

错误开启webEnvironment

dubbo 2.8.4 中 依赖了 javax.servlet-api 3.1.0 , 导致判定开启webEnvironment =true;

启动报错:

Caused by: org.springframework.context.ApplicationContextException: Unable to start EmbeddedWebApplicationContext due to missing EmbeddedServletContainerFactory bean.
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.getEmbeddedServletContainerFactory(EmbeddedWebApplicationContext.java:185) ~[spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.createEmbeddedServletContainer(EmbeddedWebApplicationContext.java:158) ~[spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
	at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:130) ~[spring-boot-1.3.6.RELEASE.jar:1.3.6.RELEASE]
	... 8 common frames omitted

解决方法:  关闭Web环境

new SpringApplicationBuilder(CreditBootstrap.class).web(false).run(args);

打war包报错:提示缺少web.xml

原因:

spring boot项目中引用了依赖包spring-boot-starter-web。该包中引用的spring-boot-starter-tomcat里包含了tomcat嵌入式servlet容器,其不同版本实现的是不同的servlet版本规范。

解决方法:

servlet 3.0 以下的必须有WEB-INF/web.xml;
servlet 3.0 以上(包括)且没有web.xml: maven-war-plugin 下设置failOnMissingWebXml = flase;

<build>
	<plugins>
		<plugin>
			<groupId>org.apache.maven.plugins</groupId>
			<artifactId>maven-war-plugin</artifactId>
			<version>2.6</version>
			<configuration>
				<failOnMissingWebXml>false</failOnMissingWebXml>
			</configuration>
		</plugin>
	</plugins>
</build>

© 著作权归作者所有

上一篇: Spring启动-web.xml
下一篇: Mycat - 配置
noob_fly
粉丝 10
博文 151
码字总数 171443
作品 0
广州
程序员
私信 提问
加载中
请先登录后再评论。
Java程序员必备的魔鬼文档,springboot核心资料,清晰!齐全!已跪!

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这...

wx5d6cccb1cb158
05/20
0
0
Java程序员必备的魔鬼文档,springboot核心资料,清晰!齐全!已跪!

Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的配置。通过这...

wx5d6cccb1cb158
05/20
0
0
SpringBoot 学习笔记(一)

—本笔记内容为原创内容,转载需注明本人— 本人刚刚毕业没多久,在学校里学的是安卓开发,后来再找实习工作的时候呢,因为安卓开发岗位过于饱和,就转去做后台开发,自学了三个月的框后台框...

osc_mblu5qn4
2018/08/03
9
0
spring boot整合Websocket笔记

特别说明:自学笔记 使用websocket有两种方式: 使用sockjs, 使用h5的标准。 使用Html5标准自然更方便简单,所以记录的是配合h5的使用方法。 1、pom.xml中添加如下: 核心是@ServerEndpoint...

jackcooper2015
2017/12/28
0
0
分布式任务调度平台XXL-JOB学习笔记一

分布式任务调度平台XXL-JOB学习笔记一 XXL-JOB是一个轻量级分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用。...

osc_6pr34qkg
04/16
22
0

没有更多内容

加载失败,请刷新页面

加载更多

解决Cannot download "https://github.com/sass/node-sass/releases/download/binding.nod的问题

输入命令解决即可 npm i node-sass --sass_binary_site=https://npm.taobao.org/mirrors/node-sass/

千年典韦
30分钟前
10
0
测试jar 是否完整有错

cd WEB-INF/lib/for j in *.jar; do echo $j; jar tvf $j > /dev/null ; echo $j done; done

xiaodong16
34分钟前
19
0
ats02.

https://xdays.me/proxy%E6%9C%8D%E5%8A%A1%E5%99%A8-trafficserver%E5%9F%BA%E7%A1%80/ apache traffic server 简称ats 入坑(一)开始使用...

MtrS
35分钟前
19
0
Elasticsearch如何查询使用JSON字符串的DSL

背景 Java处理ES查询逻辑,有一种情况是用户从其他地方粘贴或者手动输入的JSON字符串的DSL语句;这个时候就没法使用QueryBuilder来构建所需要的SearchSource。查了查发现有个Wrapper的方式可...

叫我哀木涕
今天
19
0
JDBC:ResultSet Types

ResultSet Types 用于确定ResultSet的某些特征和功能。 ResultSet.TYPE_FORWARD_ONLY 只能调用 next,不能调用 previous 。否则报错 ResultSet.TYPE_SCROLL_INSENSITIVE 能调用 next/previou...

mrsuperli
昨天
7
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部