SpringMVC
1、文件上传
jar包
pom.xml
<!--commons-fileupload -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.1</version>
</dependency>
SpringMVC配置
<!--文件上传解析器-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<!--上传文件最大字节-->
<property name="maxUploadSize" value="100000"/>
</bean>
不需经过controller直接跳转的配置
<!--其他映射-->
<mvc:view-controller path="/file" view-name="file"/>
Controller层
package com.hisoft.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.IOException;
@Controller
@RequestMapping("/file")
public class FileController {
@RequestMapping("/upload")
public String fileUpload(String desc,MultipartFile file){
try {
file.transferTo(new File("e:/img/",file.getOriginalFilename()));
} catch (IOException e) {
e.printStackTrace();
}
/* try {
InputStream is = file.getInputStream();
OutputStream os = new FileOutputStream(new File("e:/img/1.jpg"));
int len = -1;
while ((len = is.read()) != -1){
os.write(len);
}
os.flush();
os.close();
is.close();
} catch (IOException e) {
e.printStackTrace();
}*/
System.out.println(desc);
System.out.println(file.getContentType()); //图片类型
System.out.println(file.getName()); //name属性值
System.out.println(file.getOriginalFilename()); //获取文件名
System.out.println(file.getSize());//文件大小
return "file";
}
}
2、邮件发送email
jar包
pom.xml:
<!--javax.mail/mail -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.7</version>
</dependency>
<!--spring-context-support -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>5.2.9.RELEASE</version>
</dependency>
配置xml
spring配置
<!--Email配置-->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="smtp.163.com"/>
<property name="username" value="xxx@163.com"/>
<property name="password" value="xxx"/>
<property name="defaultEncoding" value="UTF-8"/>
</bean>
Controller层
package com.hisoft.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
public class EmailController {
@Autowired
private JavaMailSender javaMailSender;
@GetMapping("/email/send")
public String sendEmail(){
Thread thread = new Thread(new Runnable() {
public void run() {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom("xxx@163.com");
mailMessage.setSubject("Hi");
mailMessage.setTo("xxx@qq.com");
mailMessage.setText("hello");
javaMailSender.send(mailMessage);
}
});
thread.start(); //启动线程
return "";
}
}
线程池
-
线程池的概念:
线程池就是首先创建一些线程,它们的集合称为线程池。使用线程池可以很好地提高性能,线程池在系统启动时即创建大量空闲的线程,程序将一个任务传给线程池,线程池就会启动一条线程来执行这个任务,执行结束以后,该线程并不会死亡,而是再次返回线程池中成为空闲状态,等待执行下一个任务。
-
线程池的工作机制
2.1 在线程池的编程模式下,任务是提交给整个线程池,而不是直接提交给某个线程,线程池在拿到任务后,就在内部寻找是否有空闲的线程,如果有,则将任务交给某个空闲的线程。 2.1 一个线程同时只能执行一个任务,但可以同时向一个线程池提交多个任务。
-
使用线程池的原因:
多线程运行时间,系统不断的启动和关闭新线程,成本非常高,会过渡消耗系统资源,以及过渡切换线程的危险,从而可能导致系统资源的崩溃。这时,线程池就是最好的选择了。
3、拦截器
mvc配置
<!--拦截器-->
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/**"/>
<bean class="com.hisoft.interceptor.LoginInterceptor">
<property name="uris">
<list>
<value>/user/msg</value>
<value>/user/login</value>
</list>
</property>
</bean>
</mvc:interceptor>
</mvc:interceptors>
LoginInterceptor继承HandlerInterceptorAdapter
package com.hisoft.interceptor;
import com.hisoft.entity.User;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
public class LoginInterceptor extends HandlerInterceptorAdapter {
private List<String> uris;
public void setUris(List<String> uris) {
this.uris = uris;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
User currUser = (User) session.getAttribute("currUser");
String uri = request.getRequestURI();
if(uris.contains(uri)){
return true;
}else {
if (currUser != null) {
return true;
}else {
response.sendRedirect("/user/msg");
return false;
}
}
}
}
Controller层
@Controller
@RequestMapping("/user")
public class LoginController {
@PostMapping("/login")
public String login(User user, HttpSession session){
user = new User();
session.setAttribute("currUser",user);
return "redirect:/book/find/1";
}
@GetMapping("/msg")
public String msg(){
return "/user/msg";
}
@GetMapping("/login")
public String login(){
return "/user/login";
}
}
自定义异常
异常解析器
<!--异常解析器-->
<bean id="handlerExceptionResolver" class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<prop key="com.hisoft.exception.MyException">redirect:/user/msg</prop>
</props>
</property>
</bean>
拦截抛异常
package com.hisoft.interceptor;
import com.hisoft.entity.User;
import com.hisoft.exception.MyException;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.List;
public class LoginInterceptor extends HandlerInterceptorAdapter {
private List<String> uris;
public void setUris(List<String> uris) {
this.uris = uris;
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession();
User currUser = (User) session.getAttribute("currUser");
String uri = request.getRequestURI();
if(uris.contains(uri)){
return true;
}else {
if (currUser != null) {
return true;
}else {
throw new MyException();
}
}
}
}
4、日志log4j
jar包
<!--log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
日志级别
debug→info→warn→error→fatal(致命)
Logger log = Logger.getLogger(Log4jTest.class);
log.debug("debug message");
log.info("info message");
log.warn("warn message");
log.error("error message");
log.fatal("fatal message");
//例子
Logger logger = Logger.getLogger(Test.class);
logger.debug("日志....");
//console
[DEBUG](2021-09-22 16:57:25,523)---Test.main(Test.java:6)--日志....
log4j.properties
1、输出到控制台
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%p](%d)---%l--%m\r\n
log4j.rootLogger=DEBUG, A1
2、输出到指定文件
log4j.appender.fout=org.apache.log4j.FileAppender
log4j.appender.fout.layout=org.apache.log4j.PatternLayout
log4j.appender.fout.layout.ConversionPattern=[%p](%d)---%l--%m\r\n
log4j.appender.fout.file=F:/logs/system.log
log4j.appender.A1=org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout=org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern=[%p](%d)---%l--%m\r\n
log4j.rootLogger=DEBUG, A1,fout
3、以天为单位生成日志文件
log4j.appender.B=org.apache.log4j.DailyRollingFileAppender
log4j.appender.B.layout=org.apache.log4j.PatternLayout
log4j.appender.B.layout.ConversionPattern=[%p](%d)---%l--%m\r\n
log4j.appender.B.DatePattern='.'yyyy-MM-dd
log4j.appender.B.file=F:/logs/x.log
log4j.rootLogger=DEBUG,A1,fout,B
4、根据日志级别存放不同位置
log4j.appender.fout.Threshold=INFO
5、根据包输出日志信息
log4j.logger.com.google=ERROR,fout
信息
%m 输出代码中指定的消息
%p 输出优先级,即DEBUG,INFO,WARN,ERROR,FATAL
%r 输出自应用启动到输出该log信息耗费的毫秒数
%c 输出所属的类目,通常就是所在类的全名
%t 输出产生该日志事件的线程名
%n 输出一个回车换行符,Windows平台为“/r/n”,Unix平台为“/n”
%d 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,
比如: %d{yyy MMM dd HH:mm:ss , SSS}
%l 输出日志事件的发生位置,包括类目名、发生的线程,以及在代码中的行数。