SpringBoot学习笔记 汇总 : 异常,定时任务,支持jsp,运行JAR 等

此文包含:

1、新建项目Springboot项目

2、如何返回字符串/JSON

3、添加视图支持,可以返回数据,此处使用是velocity

4、把后台数据显示在前台页面上

5、前台显示后台传递的数据

6、使用日志Logger 添加依赖

7、使用JPA(Hibernate)操作数据库

8、使用JdbcTemplates保存数据

9、security安全机制

10、拦截器配置

11、定时任务(springboot自带)

12、定时任务,使用 ScheduledExecutorService

13、定时任务 使用Timer 可以指定时间点执行

14、返回JSP页面,亲测可用

15、JSON数据处理,返回/解析

16、异常处理

17、Springboot实现分页

18、多对一和一对多关系绑定和连接查询

19、如何发布/运行项目

1、新建项目Springboot项目

新建一个maven项目即可,然后修改pom文件,添加以下依赖,是做web必须的

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

2、如何返回字符串/JSON

新建一个Controller

@EnableAutoConfiguration //自动配置
@Controller
@RequestMapping(value = “/hi”)
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);//日志
@RequestMapping(value = “/hello”)
@ResponseBody //返回字符,JSON等
public String hi() {
System.out.print(“=============”);
return “我是一个字符串”;
}  public static void main(String[] args) {
SpringApplication.run(Application.class, args);//运行方式一//下面第二种运行方式  任选一种即可SpringApplication app = new SpringApplication(SpringbootMApplication.class);ApplicationContext atc = app.run(args);
}
}

此时运行localhost:8080/hi/hello即可看到 “我是一个字符串”,表示boot项目配置成功;

注:如需返回json数据,直接返回即可,会自动转化为JSON.例如:返回一个User对象,直接返回user.toString即可,返回User列表,返回类型为List<User>,直接返回list即可。Springboot会自动转化的。具体请看15,有更多演示。

3、添加视图支持,可以返回数据,此处使用是velocity

首先添加依赖;如需把数据显示在页面,使用map,model均可,下面4有具体介绍。

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

Controller中添加一个方法:此时会在resources/templates/文件夹下面找login.vm返回

@RequestMapping(value = “/login”, method = RequestMethod.GET)
public String loginGet(String username, String password) {
return “login”;
}

4、把后台数据显示在前台页面上

一般使用Map,或者Model

@RequestMapping(value = “/login”, method = RequestMethod.GET)
public String login(String username, String password, Map map) {
map.put(“username”, username);
Date d = new Date();
map.put(“time”, d.toLocaleString());
logger.info(“准备转发进去”);//打印日志在日志文件里
return “hi”;
}

5、前台显示后台传递的数据

此处使用是Velocity,具体可以参考其语法,如果是JSP,按jsp语法写

<body>
hello:${username},现在时间:${time}//也可以不带{}
</body>

 

6、使用日志Logger 添加依赖:

<properties> <<<在这个里面添加下面的2个<log4j.version>2.5</log4j.version>
<logback-classic>1.1.5</logback-classic>
</properties><!–依赖里面添加 log start –>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${logback-classic}</version>
</dependency>
<!– log end –>

application.properties里面配置

logging.file=SpringBoot/src/log/app.log   //我写的是项目名目录下
logging.level.org.springframework.web=DEBUG

具体Controller这样写

import org.slf4j.Logger; //是这2个包,不是阿帕奇的
import org.slf4j.LoggerFactory;private static final Logger logger = LoggerFactory.getLogger(MyApplication.class); @RequestMapping(value = “/login”, method = RequestMethod.GET)
public String login(String username, String password, Map map) {
map.put(“username”, username);
Date d = new Date();
map.put(“time”, d.toLocaleString());
logger.info(“准备转发进去”);//打印日志在日志文件里
return “hi”;
}

7、使用JPA(Hibernate)操作数据库

1.添加依赖,和Mysql依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-jdbc</artifactId>

</dependency>

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

2.application.properties这样配置

#数据库信息

spring.datasource.url = jdbc:mysql://localhost:3306/test

spring.datasource.username = root

spring.datasource.password = root

spring.datasource.driverClassName = com.mysql.jdbc.Driver

#数据库类型

spring.jpa.database = MYSQL

#格式化sql语句

spring.jpa.show-sql = true

#每次启动是更新表还是创建表 (create, create-drop, update)2个都可以用,个人感觉第二个好用

spring.jpa.hibernate.ddl-auto = update

spring.jpa.properties.hibernate.hbm2ddl.auto=update

spring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy

#数据库方言

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

3.直接写一个接口,UserDao继承 JpaRepository,不需要实现类,不需要service层,此类即可操作数据库,自带很多方法,也能够支持解析方法名称进行查询。在需要使用的时间直接@Autowired即可

@Transactional

public interface UserDao extends JpaRepository<User, Long> {

User findByName(String name); //解析方法名称查询 .注意JPA命名规范

@Query(“from User u where u.name=:name”) //支持自定义查询

User findUser(@Param(“name”) String name);

}

4.具体Controller中这样用

@Autowired

private UserDao userServiceImpl;

List<User> users = new ArrayList<User>();

users = userServiceImpl.findAll();

5.这个JpaRepository提供了很多方法,如截图:

8、使用JdbcTemplates保存数据

无需添加依赖,有上面的依赖即可。具体使用如下:

     @Autowired

private JdbcTemplate JdbcTemplate;

/**

* 使用JdbcTemplates保存

* @param u

*/

public void JdbcTests(User u) {

String sql = “insert into User(id,name) values(?,?)”;

JdbcTemplate.update(sql, u.getId(), u.getName());

}

 

9、security安全机制

1.pom文件添加依赖

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-security</artifactId>

</dependency>

2.application.properties配置用户名密码(打开网站的时候需要输入)

#安全控制

security.user.name=admin

security.user.password=admin

10、拦截器配置

1.自定义一个拦截器  写一个类继承HandlerInterceptorAdapter类,重写preHandle(请求发生前执行)和postHandle(请求完成后执行)

public class inteceptor extends HandlerInterceptorAdapter {

private static Set<String> path = new HashSet<String>();

static { // 不拦截的路径

path.add(“/login.vm”);

path.add(“/home”);  }

/**

* 拦截请求前,此处可设置session,characterEncoding

*/

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)

throws Exception {

long start = System.currentTimeMillis();

request.setAttribute(“start”, start);

if (path.contains(request.getRequestURI())) {

System.out.println(“URL:” + request.getRequestURI());

return true;

}

System.out.println(“—-redirect”);

response.sendRedirect(“login.vm”);

return false;

}

/**

* 拦截请求完成后执行的操作

*/

@Override

public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,

ModelAndView modelAndView) throws Exception {

long start = (long) request.getAttribute(“start”);

long now = System.currentTimeMillis();

System.out.println(“—–:” + (now – start));

request.setAttribute(“time”, new Date().toLocaleString());

}

2.注册拦截器 写一个类继承WebMvcConfigurerAdapter ,重写addInterceptors方法,把自定义的拦截器add进去即可

@Configuration

public class WebConfig extends WebMvcConfigurerAdapter {

/**

* 注册拦截器,方法是不能改名字的,因为是重写的

*/

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new inteceptor());//inteceptor类是我自定义的拦截器类

System.out.println(“拦截器注册完成…..”);

}

}

11、定时任务(springboot自带)

还有是java内的。只需要写一个定时任务的类,然后在方法里面启动需要执行的任务即可,一个类可以定多个定时任务

@Configuration

@EnableScheduling // 标注启动定时任务

public class SchudelTime {

/**

* cron内容分别是:秒,分,时,天,月,星期,年(可以省略年)

*/

@Scheduled(cron = “0/20 * * * * ?”) // 每隔20秒执行一次

public void doTask() {

System.out.println(“—–每隔20秒执行一次 at:” + new Date().toLocaleString());

}

@Scheduled(fixedRate = 1000 * 30) // 每隔30秒执行一次

public void reportCurrentTime() {

System.out.println(“每隔30秒执行一次: The time is now ” + new Date().toLocaleString());

}

@Scheduled(fixedRate = 1000 * 60, initialDelay = 1000) // 每隔1分钟执行一次,延迟1秒执行

public void updatePayRecords() {

System.out.println(“每隔1分钟执行一次,延迟1秒执行: The time is now ” + new     Date().toLocaleString());

}

}

12、定时任务,使用 ScheduledExecutorService

思路:新建一个类,在这个类的方法里创建定时任务调度器,然后使用调度器自带的方法执行具体的任务(是类,不是方法),这个类需要实现Runable接口

  /**
*
链接服务端接口的定时任务
* Created by server on 2016/9/2.
*/
public class LinkServerScheduled {
public static void scheduleWithFixedDelay() {
ScheduledExecutorService schedule = Executors.newScheduledThreadPool(5);
//延迟10秒,以后每隔30秒执行一次 .
schedule.scheduleWithFixedDelay(new UpdateTask(), 10, 30, TimeUnit.SECONDS);
}  // schedule不止scheduleWithFixedDelay一个方法,很多种
}下面是UpdateTask类public class UpdateTask implements Runnable {
private static final Logger logger = LoggerFactory.getLogger(UpdateTask.class);
@Override
public void run() {
System.out.println(“======begin do something:–” + new Date().toLocaleString());}

13、定时任务 使用Timer 可以指定时间点执行

比如10点10分  写一个普通类,里面有具体执行定时任务的方法,在这个方法中new定时任务管理器,启动定时任务,设置时间。

public class TimerDemo {

public void dosomething() {

Calendar calendar = Calendar.getInstance();

calendar.set(Calendar.HOUR_OF_DAY, 16); // 时

calendar.set(Calendar.MINUTE, 17);// 分

calendar.set(Calendar.SECOND, 00); // 秒

Date date = calendar.getTime(); // 第一次执行定时任务的时间

// 如果第一次执行定时任务的时间 小于当前的时间

// 此时要在 第一次执行定时任务的时间加一天,以便此任务在下个时间点执行。如果不加一天,任务会立即执行。

if (date.before(new Date())) {

calendar.add(Calendar.DAY_OF_MONTH, 1);

date = this.addDay(date, 1);

}

System.out.println(“exe Time:” + date.toLocaleString());

Timer timer = new Timer(); /、执行任务的调度类

TimerTask task = new TimerTask();// 具体的任务类

timer.schedule(task, date, 10000);// 任务类,第一次执行时间点,延迟时间

//timer.cancel();//取消任务

}

// 增加或减少天数

public static Date addDay(Date date, int num) {

Calendar startDT = Calendar.getInstance();

startDT.setTime(date);

startDT.add(Calendar.DAY_OF_MONTH, num);

return startDT.getTime();

}

}

具体执行的类,继承TimerTask类,在其run方法里进行操作,写具体的定时逻辑

public class AllFullTask extends TimerTask {
private static final Logger logger = LogManager.getLogger(QueryTaskServiceImpl.class);
@Override
public void run() {//在这里写具体的执行逻辑
}

14、返回JSP页面,亲测可用

注意:不能添加volecity等其他模板,把其他模板依赖去掉,1.需要在src>main目录下新建webapp>WEB-INF>jsp文件夹。注意webapp和java,resources是同一级别。2.在application.properties文件夹定义前后缀。3.添加具体的依赖

application.properties文件这样配置:

# 页面默认前缀目录

spring.mvc.view.prefix=/WEB-INF/jsp/

# 响应页面默认后缀

spring.mvc.view.suffix=.jsp

pom文件添加依赖

       <dependency> <!–JSTL支持,非必须–>

<groupId>javax.servlet</groupId>

<artifactId>jstl</artifactId>

</dependency>

<dependency> <!–必须–>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-tomcat</artifactId>

<scope>provided</scope>

</dependency>

<dependency>  <!–必须–>

<groupId>org.apache.tomcat.embed</groupId>

<artifactId>tomcat-embed-jasper</artifactId>

<scope>provided</scope>

</dependency>

注意目录结构图如下:红色表示在main目录下目录等级

 

15、JSON数据处理,返回/解析

注意此处使用了net.sf.json包,需要添加依赖:需要这样写:

<dependency>

<groupId>net.sf.json-lib</groupId>

<artifactId>json-lib</artifactId>

<version>2.4</version>

<classifier>jdk15</classifier>

</dependency>

下面是具体演示:

package com.sbm.wll.controller;

import java.util.List;

import java.util.Map;

import org.json.JSONArray;

import org.json.JSONObject;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.ResponseBody;

import java.util.ArrayList;

import java.util.HashMap;

import com.sbm.wll.dao.UserDao;

import com.sbm.wll.entity.User;

/**

* 常用JSON数据处理demo

* @author server

*/

@Controller

public class Json {

@Autowired

private UserDao userServiceImpl;

/**

* json格式字符串转json

* @return

*/

@RequestMapping(value = “/json1”)

@ResponseBody

public String getJson1() {

String str = “{\”a\”:\”b\”, \”c\”:\”d\”}”;

JSONObject obj = new JSONObject(str);// org.json

System.out.println(“json字符串转json:” + obj);

return str;

}

/**

* List<User>转JSON Springboot自动转化 返回值类型为List 注释掉的为使用net.sf.json工具做的 ,是正确的

* @return

*/

@RequestMapping(value = “/json2”)

@ResponseBody

public List<User> getJson2() {

List<User> users = null;

users = userServiceImpl.findAll();

// net.sf.json.JSONArray array = new

// net.sf.json.JSONArray().fromObject(users);

// System.out.println(“—–使用.net.sf.json:”+array);

net.sf.json.JSONArray as=new net.sf.json.JSONArray().fromObject(“”);

return users;

}

/**

* List<User>转JSON 返回值类型为String

* @return

*/

@RequestMapping(value = “/json3”)

@ResponseBody

public String getJson3() {

List<User> users = null;

users = userServiceImpl.findAll();

JSONArray array = new JSONArray(); // org.json包

for (int i = 0; i < users.size(); i++) {

User u = users.get(i);

System.out.println(“u:”+u.toString());

JSONObject object = new JSONObject(u);

System.out.println(“object:” + object);

array.put(object);

}

System.out.println(“org.json.Array:to json:” + array);

return array.toString();

}

/**

* Map<String,String>转JSON 返回值类型为String 使用.net.sf.json

* @return

*/

@RequestMapping(value = “/json4”)

@ResponseBody

public String getJson4() {

Map<String, String> map = new HashMap<>();

map.put(“1”, “c100”);

map.put(“2”, “c233”);

map.put(“4”, “c556”);

net.sf.json.JSONArray array = new net.sf.json.JSONArray().fromObject(map);

System.out.println(“—–使用.net.sf.json:” + array);

return array.toString();

}

/**

* 解析json字符串 json中 包含json数组

* @param request

* @return

*/

@RequestMapping(“/jx1”)

@ResponseBody

public String jxJSON1() {

String jsonString = “{‘id’:’1′,’corpcode’:’10147′,’msg’:{‘time’:’16-35′,’pp’:’ddd’}}”;

JSONObject obj = new JSONObject(jsonString); // org.json

System.out.println(“corpcode:” + obj.getString(“corpcode”));

JSONObject msg = new JSONObject(obj.get(“msg”).toString());// msg不是String,要么get,要么getJSONObj

System.out.println(“msg:” + msg); // 获取msg 里面的json内容

String time = msg.getString(“time”);

System.out.println(“msg—time:” + time);

System.out.println(“全部json:” + obj);

return obj.toString();

}

/**

* 把JSON数组里面的对象,解析到实体中

* @return

*/

@RequestMapping(“/jx2”)

@ResponseBody

public String jsJSON2() {

String jString = “[{‘id’:’111′,’name’:’小明’},{‘id’:’22’,’name’:’小花’},{‘id’:’402′,’name’:’小红’}]”;

com.alibaba.fastjson.JSONArray array = new com.alibaba.fastjson.JSONArray().parseArray(jString);

List<User> users = new ArrayList<>();

for (int i = 0; i < array.size(); i++) {

User user = new User();

com.alibaba.fastjson.JSONObject object = array.getJSONObject(i);

user.setId(Integer.valueOf(object.getString(“id”)));

user.setName(object.getString(“name”));

System.out.println(“U:” + user.toString());

users.add(user);

}

for (User u : users) {

System.out.println(“—-” + u.toString());

}

return “”;

}

}

16、异常处理

import javax.servlet.http.HttpServletRequest;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.web.bind.annotation.ControllerAdvice;

import org.springframework.web.bind.annotation.ExceptionHandler;

import org.springframework.web.servlet.ModelAndView;

 

/**

* @ControllerAdvice 用来标志一个类,用来增强controller. 被注解的类,能够被<context

*      component-scan>自动扫描到

*        它通常被用于定义 @ExceptionHandler、@InitBinder和ModelAttribute

*       调用所有的被@RequestMapping标记的类之前,注解类中方法会被先执行(相当于spring的aop,

*      一个过滤器) 如果没有定义需要支援的controller的范围,则默认支援所有能扫描controller

*/

@ControllerAdvice

public class GeneraException {

private static final Logger logger = LoggerFactory.getLogger(GeneraException.class);

 

@ExceptionHandler(value = Exception.class)

public String defaultErrorHandler(HttpServletRequest req, Exception ex) {

System.out.println(“异常类启动…..”);

ModelAndView mav = new ModelAndView();

mav.addObject(“exception”, ex);

mav.addObject(“url”, req.getRequestURL());

mav.setViewName(“error”);

logger.error(“================错误位置:” + req.getRequestURI() + ”   \n 错误信息:” + ex);

return “error”;

}

}

17、Springboot实现分页

先在实现JPA接口的接口里面写下面方法: plan 是需要分页的实体类对象

Page<Plan> findAll(Specification<Plan> specification, Pageable pageable);

然后在 具体Controller中这样写:

public String findall(int pageNumber, int pageSize) {
// PageAble 接口通常用的是PageRequest实现类,其中封装了需要分页的信息
// 排序相关的,sor封装了排序的信息
Order order1 = new Order(Direction.ASC, “id”);//升序还是降序,根据的字段
Sort sort = new Sort(order1);
Pageable pageable = new PageRequest(pageNumber – 1, pageSize, sort);
DataBean dataBean = new DataBean();
Specification<Plan> specification = new Specification<Plan>() {
/* Plan是实体类
* @param root:代表的查询的实体类
* @param query:可以从中得到Root对象,即告知JPA Criteria查询要查询哪一个实体类,
* 还可以来添加查询条件,还可以结合EntityManager对象得到最终查询的TypedQuery 对象
* cb:criteriabuildre对象,用于创建Criteria相关的对象工程,当然可以从中获取到  predicate类型
* @return:代表一个查询条件
*/
@Override
public Predicate toPredicate(Root<Plan> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate p1 = cb.equal(root.get(“isexist”).as(String.class), “Y”);
Predicate p2 = cb.equal(root.get(“corp_code”).as(String.class), corp_code);
// 构建组合的Predicate示例:
Predicate p = cb.and(p1, p2);//查询条件
return p;
}
};
Page<Plan> page = planService.findAll(specification, pageable);//单独写的方法
return JSON.toJSONString(page); //直接转化为JSON返回

18、多对一和一对多关系绑定和连接查询

1、实体类如何绑定:例子:书和读者,一个读者读多本书,一本书可能有多个读者

//读者实体类

import java.util.HashSet;

import java.util.Set;

import javax.persistence.*;

@Entity

@Table(name = “reader”)

public class Reader {

@Id

@Column(name = “ID”)

@GeneratedValue(strategy = GenerationType.AUTO)//int类型自增策略

private int id;

//mappedBy表示拥有方  cascade维护所有,fetch为懒加载

@OneToMany(mappedBy=”reader”,cascade=CascadeType.ALL,fetch=FetchType.LAZY)

private Set<Book> books = new HashSet<Book>();

public Set getBooks() {

return books;

}

public void setBooks(Set books) {

this.books = books;

}

下面是Book实体类:

import javax.persistence.*;

@Entity

@Table(name = “book”)

public class Book {

@Id

@Column(name = “ID”)

@GeneratedValue(strategy = GenerationType.AUTO)//主键生成策略 int类型

private int id;

@ManyToOne(cascade = CascadeType.ALL, optional = false)

@JoinColumn(name = “rea_id”) // 就是在book表显示的字段名称

private Reader reader;

public Reader getReader() {

return reader;

}

public void setReader(Reader reader) {

this.reader = reader;

}

这样绑定后,启动项目,就会自动建立表,建立主外键。

具体Controller中这样写保存方法:

@Autowired

private ReaderDao readerDaoImpl; //使用JPA的

@Autowired

private BookDao bookDaoImpl;//使用JPA

public String addTest(HttpServletRequest request) {

Reader r = new Reader();//一个读者多本书

r.setName(“LIMING”);

r.setMeno(“man”);

Book b1 = new Book();

b1.setTitle(“Java”);

Book b2 = new Book();

b2.setTitle(“C++”);

b1.setReader(r);

b2.setReader(r);

Set<Book> bs = new HashSet<Book>();

bs.add(b1);

bs.add(b2);

r.setBooks(bs);

// r.getBooks().add(b1);  另一种绑定方式

// r.getBooks().add(b2);另一种绑定方式

// bookDaoImpl.save(b1);

// bookDaoImpl.save(b2);

// readerDaoImpl.save(r);

// System.out.println(“添加完成”);

Book bbBook = bookDaoImpl.findById(1);

request.setAttribute(“b1”, bbBook);//放在request中

return “book”;

}

具体book.jsp中这样写:

<body>

<%

Book b = (Book) request.getAttribute(“b1”);

%>

title:<%=b.getTitle()%> —-reader:<%=b.getReader().getName() %>

</body>

 

19、如何发布/运行项目

如果是Velocity模板直接 mvn clean package -DskipTests 然后运行jar包即可。如果是jsp支持,在Eclipse编辑后发布项目 1.改pom文件中jar为war, cmd 进入项目目录,执行命令:mvn clean package即可生成war文件。然后直接在cmd :java -jar xxx.war即可,也可以编辑一个bat批处理,如: java -jar .\demo-0.0.1-SNAPSHOT.war 即可

 

 

 

 

 

本站的文章多是老王开发工作中问题的记录,一个字一个字敲的,切实可行,可以分享,需要留个原文链接,至少也意思意思吧!
阿里云服务器怎么购买划算-vsalw技术博客 » SpringBoot学习笔记 汇总 : 异常,定时任务,支持jsp,运行JAR 等

每个人都是以自己独特的方式体味生活,或许别人不理解,但自己知道:其中的酸甜苦辣就叫做幸福!

认同! 瞎扯淡!