# java学习
**Repository Path**: corgile/java-learning
## Basic Information
- **Project Name**: java学习
- **Description**: 学习
- **Primary Language**: Unknown
- **License**: Not specified
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 0
- **Forks**: 0
- **Created**: 2022-02-26
- **Last Updated**: 2022-02-28
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
## 整合 Jackson 和 Gson
1. 将服务的返回的对象序列化成json字符串
2. 将前端传来的json字符串反序列化成对象
所有的Json生成都需要相关的 HttpMessageConverter
SpringBoot 中自动配置了Jackson和Gson的HttpMessageConverter,
> 如何配置全局 json 格式(比如说日期格式)
1. 创建配置类
2. 手动提供一个converter的 bean
```java
package com.a.bootweb.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.text.SimpleDateFormat;
@Configuration
public class WebConfig {
@Bean
MappingJackson2HttpMessageConverter mapping() {
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
ObjectMapper om = new ObjectMapper();
// 设置全局统一日期格式
om.setDateFormat(new SimpleDateFormat("yy-MM-dd"));
converter.setObjectMapper(om);
return converter;
}
}
```
3. 或者也可以:因为真正起作用的是`ObjectMapper`
```java
package com.a.bootweb.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.text.SimpleDateFormat;
@Configuration
public class WebConfig {
@Bean
public ObjectMapper mapper() {
ObjectMapper om = new ObjectMapper();
om.setDateFormat(new SimpleDateFormat("MM-dd-yyyy"));
return om;
}
}
```
## 全局异常处理
```java
package com.a.bootweb.controller;
import org.omg.CosNaming.NamingContextPackage.NotFound;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.NoHandlerFoundException;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
@RestControllerAdvice
public class MyExceptionHandler {
@ExceptionHandler(NoHandlerFoundException.class)
public void notFound(HttpServletResponse response) throws IOException {
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
out.write("
404 Not Found! 找不到服务器
");
out.flush();
out.close();
}
}
```
404需要配置:
```properties
spring.mvc.throw-exception-if-no-handler-found=true
```
## 跨域
1. 跨域注解可以写在方法或类上,也可以写在全局配置中
```java
package com.a.bootweb.config;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import java.text.SimpleDateFormat;
/**
* @author Corgile
* @date 2022-02-26
*/
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Bean
public ObjectMapper mapper() {
ObjectMapper om = new ObjectMapper();
om.setDateFormat(new SimpleDateFormat("MM-dd-yyyy"));
return om;
}
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/user/**")
.allowedOrigins("http://localhost:8081")
.allowedHeaders("*")
.allowedMethods("*") //.allowedMethods("/getuser", "/setuser")
.maxAge(30 * 1000);
}
}
```
## AOP
定义切点:在service所有方法执行时
```java
@Pointcut(value = "execution(* com.a.bootweb.service.*.*(..))")
public void pointCutForServices() { }
```
各种通知类型
```java
@Before(value = "pointCutForServices()")
public void before(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();
System.out.println("before-----" + name);
}
@After(value = "pointCutForServices()")
public void after(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();
System.out.println("after-----" + name);
}
@AfterReturning(value = "pointCutForServices()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
String name = joinPoint.getSignature().getName();
System.out.println("afterReturning----" + name + "---" + result);
}
@AfterThrowing(value = "pointCutForServices()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {
String name = joinPoint.getSignature().getName();
System.out.println("afterThrowing---" + name + "----" + e.getMessage());
}
@Around(value = "pointCutForServices()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
```
完整
```java
package com.a.bootweb.aop;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;
/**
* @author Corgile
* @date 2022-02-26
*/
@Component
@Aspect
public class MyLogger {
@Pointcut(value = "execution(* com.a.bootweb.service.*.*(..))")
public void pointCutForServices() { }
@Before(value = "pointCutForServices()")
public void before(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();
System.out.println("before-----" + name);
}
@After(value = "pointCutForServices()")
public void after(JoinPoint joinPoint) {
String name = joinPoint.getSignature().getName();
System.out.println("after-----" + name);
}
@AfterReturning(value = "pointCutForServices()", returning = "result")
public void afterReturning(JoinPoint joinPoint, Object result) {
String name = joinPoint.getSignature().getName();
System.out.println("afterReturning----" + name + "---" + result);
}
@AfterThrowing(value = "pointCutForServices()", throwing = "e")
public void afterThrowing(JoinPoint joinPoint, Exception e) {
String name = joinPoint.getSignature().getName();
System.out.println("afterThrowing---" + name + "----" + e.getMessage());
}
@Around(value = "pointCutForServices()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}
}
```
## 文件上传
1. 全局异常处理大小超过限制
```java
@ControllerAdvice
public class GlobalController {
@ExceptionHandler(FileSizeLimitExceededException.class)
public void maxSizeFile(FileSizeLimitExceededException e, HttpServletResponse resopnse) {
resopnse.setContentType("text/html;charset=utf-8");
try {
PrintWriter out = resopnse.getWriter();
out.write("上传文件大小超过限制
");
out.flush();
out.close();
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
}
```

2. 上传成功

```java
package com.a.bootweb.controller;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.UUID;
/**
* @author Corgile
* @date 2022-02-26
*/
@RestController
@RequestMapping(value = "file")
public class FileUploadController {
@PostMapping(value = "upload")
public String upload(MultipartFile file, HttpServletRequest request) throws IOException {
String format = new SimpleDateFormat("/yyyy/MM-dd/").format(new Date());
String realPath = request.getServletContext().getRealPath("/img") + format;
File folder = new File(realPath);
if (!folder.exists()) {
folder.mkdirs();
}
return getUrl(request, format, folder, file);
}
@PostMapping(value = "uploads")
public List uploads(MultipartFile[] files, HttpServletRequest request) throws IOException {
String format = new SimpleDateFormat("/yyyy/MM-dd/").format(new Date());
String realPath = request.getServletContext().getRealPath("/img") + format;
File folder = new File(realPath);
if (!folder.exists()) {
folder.mkdirs();
}
List urls = new ArrayList<>();
for (MultipartFile file : files) {
urls.add(getUrl(request, format, folder, file));
}
urls.forEach(System.out::println);
return urls;
}
private String getUrl(HttpServletRequest request, String format, File folder, MultipartFile file) throws IOException {
String oldName = file.getOriginalFilename();
assert oldName != null;
String newName = UUID.randomUUID() + oldName.substring(oldName.lastIndexOf("."));
file.transferTo(new File(folder, newName));
return request.getScheme() + "://" + request.getServerName() + ":"
+ request.getServerPort() + "/img" + format + newName;
}
}
```
3. 配合Ajax上传
```html
文件上传
```
## 整合持久层
### JDBCTemplate + 多数据源
1. 配置文件中说明要用到的数据库

2. 手动配置数据源

3. 数据源的操作类

4. 在Service中指明用的是哪一个数据源的操作类

5. 测试通过✅

### MyBatis + 多数据源
> 与Jdbc多数据源配置类似,`DataSourceConfig`类不变
1. properties文件

2. 添加各个数据源的配置类,这里只给出其一,要加`@Primary`

3. 创建数据访问接口和对应的xml文件

4. 测试✅

### JPA(Java Persistence API)
1. 配置JPA相关

2. 创建一个实体类

3. 启动项目,表已被自动创建

4. 随便弄几个函数查询

- Controller

- 测试通过✅

## Session共享
正向代理:Proxy向Client作出response,并隐藏Server袭击
反向代理:Proxy向Server发出request,并隐藏Client细节
负载均衡
```java
# 上有服务器配置
upstream some_server_name{
server 127.0.0.1:8080 weight=2;
server 127.0.0.1:8081 weight=1;
}
# 路由分发配置
server {
listen 80;
server_name localhost;
location / {
proxy_pass http://some_server_name;
proxy_redirect default;
}
}
```
## JdbcTemplate 构建 Restful