pom.xml添加下面定义
org.springframework.boot
spring-boot-starter-parent
1.5.2.RELEASE
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-web
在项目名中配置
application.properties文件中
spring.datasource.name=scott
spring.datasource.password=12345
application.yml文件中
spring:
datasource:
name: scott
password: 12345
案例:application.properties中的代码
server.port=8080
server.context-path=/boot01
@SpringBootApplication
public class MyBootApplication {
public static void main(String[] args){
SpringApplication.run(MyBootApplication.class, args);
}
}
@RestController //默认返回JSON格式 可以替换成@Controller和@ResponseBody
public class HelloController {
@RequestMapping("/hello/{name}")
public String say(@PathVariable("name")String name){
return "Hello World "+name;
}
}
或
@Controller
public class HelloController {
@RequestMapping("/hello/{name}")
@ResponseBody// @ResponseBody注解的作用就是把控制视图方法返回的内容返回到请求页面上
public String say(@PathVariable("name")String name){
return "Hello World "+name;
}
}
打开浏览器输入:http://localhost:8888/boot01/hello/scott
1.1 @Configuration+@Bean
作用:可以将程序中的Bean对象放入Spring容器中。
类似于:xml文件中
一般会使用@Configuration+@Bean组合。不加@Bean会提示找不到类
注解标记使用格式:
package cn.xdl;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import cn.xdl.dao.UserDao;
@EnableAutoConfiguration//配置类 如果不加@Bean会报错
//@Configuration+Bean要一起使用
public class DaoConfig {
@Bean(name="userDao")//将返回的UserDao对象加入Spring容器,默认id是方法名
public UserDao createUserDao(){
return new JdbcUserDao();
}
@Bean(name="bookDao")
public BookDao createBookDao(){
return new JdbcBookDao();
}
}
//接口和实现类
package cn.xdl.dao;
public interface BookDao {
void load();
}
package cn.xdl.dao;
public class BookDaoImpl implements BookDao {
@Override
public void load() {
System.out.println("load");
}
}
创建SpringBoot的Spring容器:
public static void main(String[] args){
ApplicationContext ac =
SpringApplication.run(DaoConfig.class, args);
UserDao userDao = ac.getBean("userDao",UserDao.class);
userDao.save();
BookDao bookDao = ac.getBean("bookDao",BookDao.class);
bookDao.load();
}
1.2 @Import @Scope(“prototype”)非单例
@Configuration//配置类
@Import(DataSourceConfig.class)//导入另一个配置类
//上面等于 @Import(value=cn.xdl.config.DataSourceConfig.class)
public class DaoConfig {
//... ...
}
提示:
package cn.xdl.config;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ComponentScan;
import cn.xdl.service.UserService;
@ComponentScan(basePackages="cn.xdl.service")//扫描 cn.xdl.service包下的代码
//@ComponentScan //什么都不加默认扫描
public class ComponentScanConfig {
public static void main(String[] args) {
ConfigurableApplicationContext ac = SpringApplication.run(ComponentScanConfig.class, args);
UserService bean = ac.getBean("UserService", UserService.class);
bean.register();
}
}
service组件 @Service
package cn.xdl.config.service;
import org.springframework.stereotype.Service;
@Service("userService") 等同于@Service(value="UserService")
public class UserServiceImpl implements UserService{
@Override
public void regist() {
System.out.println("用户注册处理");
}
}
创建SpringBoot的Spring容器:
ApplicationContext ac =
SpringApplication.run(ComponetScanConfig.class, args);
UserService service =
ac.getBean("userService",UserService.class);
service.regist();
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
使用方法:
#server
name=xielong #注意不要用username 否则跟系统用户变量有冲突
password=12345
server.port=8888
@Component("dbparams")//扫描
@ConfigurationProperties//注入properties参数
public class DB {
private String name;//自动注入name值 如果用${username}会取出系统账户报错
//因为跟application.properties文件的参数一致 不需要转换
@Value("${password}")
private String pass;//注入password值
//省略set和get方法
}
#server application.properties文件
db.username=xielong
db.password=12345
server.port=8888
DB的JAVA文件
package cn.xdl.bean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component("dB")
@ConfigurationProperties(prefix="db")//注入参数前缀 不带'.' //@ConfigurationProperties(prefix="db.") 如果加了'.',取到的数据为空
public class DB {
private String username;//不需要加"${username}" 会自动匹配 db.username
private String password;//不需要加"${password}"
public DB() {
super();
}
public DB(String username, String password) {
...
}
getter/setter;
}
@ComponentScan
@Configuration
@EnableAutoConfiguration
public class MyBootApplication {
public static void main(String[] args){
//@ComponentScan加载扫描配置
ApplicationContext ac =
SpringApplication.run(MyBootApplication.class, args);
//省略...
DB db = ac.getBean("dB", DB.class);
System.out.println(db.getUsername());
System.out.println(db.getPassword());
}
}
或
@SpringBootApplication//一个标记顶前面3个
public class MyBootApplication {
public static void main(String[] args){
//@ComponentScan加载扫描配置
ApplicationContext ac =
SpringApplication.run(MyBootApplication.class, args);
//省略...
DB db = ac.getBean("dB", DB.class);
System.out.println(db.getUser());
System.out.println(db.getName());
}
}
使用JdbcTemplate:
直接注入就行
1.SpringBoot默认连接池
SpringBoot可以默认创建连接池对象,创建出的对象id名为dataSource.创建机制如下:
优先创建tomcat-jdbc连接池对象。
(需要引入spring-boot-starter-jdbc.jar包支持)
没有tomcat-jdbc,会创建HikariCP连接池对象
(需要引入hikaricp.jar支持)
没有HikariCP,会创建dbcp连接池对象
(需要引入dbcp.jar支持)
没有dbcp,会创建dbcp2连接池对象
(需要引入dbcp2.jar支持)
SpringBoot默认连接池参数定义如下:
#application.properties
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.url=xxx
spring.datasource.driver-class-name=xxx
#default datasource
spring.datasource.username=system
spring.datasource.password=123456
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
可以通过spring.datasource.type参数指定创建连接池对象类型。
手动创建连接池代码:
@Configuration
public class DataSourceConfig {
@Bean(name="dbcp2")
@ConfigurationProperties(prefix="db.datasource2")
public DataSource createDbcp2(){
// BasicDataSource ds = new BasicDataSource();
// return ds;
DataSource ds = DataSourceBuilder.create()
.type(BasicDataSource.class).build();
return ds;
}
@Bean(name="dbcp1")
@Primary//默认采用该连接池
@ConfigurationProperties(prefix="db.datasource1")
public DataSource createDbcp1(){
DataSource ds = DataSourceBuilder.create()
.type(BasicDataSource.class).build();
return ds;
}
}
#datasource1
db.datasource1.username=SCOTT
db.datasource1.password=TIGER
db.datasource1.url=jdbc:oracle:thin:@localhost:1521:XE
#datasource2
db.datasource2.username=SCOTT
db.datasource2.password=TIGER
db.datasource2.url=jdbc:oracle:thin:@localhost:1521:XE
db.datasource2.driverClassName=oracle.jdbc.OracleDriver
4.0.0
cn.xdl
boot-dao
0.0.1-SNAPSHOT
war
org.springframework.boot
spring-boot-starter-parent
1.4.7.RELEASE
UTF-8
UTF-8
1.7
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-jdbc
org.apache.tomcat
tomcat-jdbc
org.apache.commons
commons-dbcp2
org.springframework.boot
spring-boot-starter-test
test
@SpringBootApplication
public class MyBootApplication {
public static void main(String[] args) throws SQLException {
ApplicationContext ac = SpringApplication.run(MyBootApplication.class, args);
// DataSource dataSource = ac.getBean("dataSource", DataSource.class);
// System.out.println(dataSource.getConnection());
// DataSource bean = ac.getBean("dbcp1", DataSource.class);
// System.out.println(bean);
DataSourceConfig bean = ac.getBean("dataSourceConfig", DataSourceConfig.class);
DataSource createDbcp1 = bean.createDbcp1();
System.out.println(createDbcp1.getConnection());
}
}
示例代码:https://github.com/CNxielong/SpringBoot/boot-day03
示例:DeptDao java文件
package cn.xdl.dao;
import java.util.List;
import org.apache.ibatis.annotations.Select;
import cn.xdl.entity.Dept;
public interface DeptDao {
@Select("SELECT * FROM XDL_DEPT")
List<Dept> queryAll();
}
引入pagehelper-spring-boot-starter工具包,然后在代码中直接使用PageHelper.startPage()方法就可以。(boot内部采用自动配置引入PageHelper对象)
MyBootApplication主启动类JAVA文件
@SpringBootApplication
@MapperScan(basePackages = "cn.xdl.dao")
public class MyBootApplication {
public static void main(String[] args) throws SQLException {
ConfigurableApplicationContext ac = SpringApplication.run(MyBootApplication.class, args);
DeptDao deptDao = ac.getBean("deptDao", DeptDao.class);
PageHelper.startPage(1, 2);//顺序放在 结果集前面
List<Dept> list = deptDao.queryAll();
for (Iterator iterator = list.iterator(); iterator.hasNext();) {
Dept dept = (Dept) iterator.next();
System.out.println(dept);
}
}
}
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.3
主要:引入spring-boot-starter-web工具包,内部集成tomcat服务器、spring mvc开发包。
- /hello.do-->DispatcherServlet-->HandlerMapping-->HelloController-->ModelAndView-->ViewResolver-->/hello.jsp
- 在boot中开发者只需要编写Controller和JSP,DispatcherServlet和HandlerMapping、ViewResolver都会采用自动配置。
1.在pom.xml中追加boot web和tomcat jasper两部分jar包
org.springframework.boot
spring-boot-starter-web
org.apache.tomcat.embed
tomcat-embed-jasper
2.在application.properties中定义server和viewresolver参数
#server
server.port=8888
#viewresolver
spring.mvc.view.prefix=/
spring.mvc.view.suffix=.jsp
3.编写HelloController,使用@Controller和@RequestMapping标记
@Controller
public class HelloController {
@RequestMapping("/hello.do")
public ModelAndView say(){
ModelAndView mav = new ModelAndView();
mav.setViewName("hello");//hello.jsp视图名为hello
mav.getModel().put("msg", "Hello Spring Boot MVC");
return mav;
}
}
4.在src/main/webapp编写hello.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
${msg}
5.运行启动类MyBootAppliation测试
@SpringBootApplication
@MapperScan(basePackages={"cn.xdl.boot.dao"})//扫描加载mapper接口
public class MyBootApplication {
public static void main(String[] args) {
//创建spring容器,启动tomcat服务器
SpringApplication.run(MyBootApplication.class, args);
}
}
打开浏览器输入: http://localhost:8888/hello.do
1.编写DeptController,注入DeptDao对象
@Controller
public class DeptController {
@Autowired
private DeptDao deptDao;
@RequestMapping("/dept/list.do")
public ModelAndView list(){
ModelAndView mav = new ModelAndView();
mav.setViewName("dept_list");//dept_list.jsp
List<Dept> list = deptDao.findAll();
mav.getModel().put("depts", list);
return mav;
}
}
2.编写dept_list.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
Insert title here
部门列表
${depts}
3.在pom.xml中追加jstl开发包定义
jstl
jstl
1.2
4.在dept_list.jsp添加taglib引入,使用jstl标签
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
${dept.deptno}
${dept.dname}
${dept.loc}
5.启动MyBootApplication测试
1.编写DeptController,添加delete方法
2. @Controller
3. @RequestMapping("/dept")//一下都是/dept下的“.do”
4. public class DeptController {
5.
6. @Autowired
7. private DeptDao deptDao;
8.
9. @RequestMapping("/list.do")
10. public ModelAndView list(){
11. ModelAndView mav = new ModelAndView();
12. mav.setViewName("dept_list");//dept_list.jsp
13. List<Dept> list = deptDao.findAll();
14. mav.getModel().put("depts", list);
15. return mav;
16. }
17.
18. @RequestMapping("/delete.do")
19. public String delete(@RequestParam("id") int deptno){
20. deptDao.delete(deptno);
21. return "redirect:/dept/list.do";
22. }
23.
24. }
@Autowired
DeptDao deptdao;
@RequestMapping("/dept/list.do")
public ModelAndView list(){
ModelAndView mav = new ModelAndView();
List<Dept> list = deptdao.queryAll();
mav.setViewName("deptList");
mav.getModel().put("deptList", list);
return mav;
}
@RequestMapping("/dept/delete.do")//最简洁的写法
public String deleteByDno(@RequestParam("dno") int dno){
deptdao.deleteDept(dno);
return "redirect:/dept/list.do";
}
// @RequestMapping("/dept/delete.do") //这种方式删除后展现为空结果的
// public ModelAndView deleteByDno(@RequestParam("dno") int dno){
// ModelAndView mav = new ModelAndView();
// deptdao.deleteDept(dno);
// mav.setViewName("deptList");
// return mav;
// }
// @RequestMapping("/dept/delete.do") //这种方式删除后重定向
// public ModelAndView deleteByDno(@RequestParam("dno") int dno){
// ModelAndView mav = new ModelAndView();
// deptdao.deleteDept(dno);
// RedirectView view = new RedirectView("/dept/list.do");
// mav.setView(view);
// return mav;
// }
2.编写dept_list.jsp追加删除按钮
${dept.deptno}
${dept.dname}
${dept.loc}
删除
4.1全局处理(BasicErrorController 继承 ErrorController)
@Controller //不能丢 否则默认采取原先的BasicErrorController
public class MyErrorController implements ErrorController {
@Override
public String getErrorPath() {
return "/error"; //这一行固定写法不能改
// return "/exception";//如果用这一行 启动报错
}
@RequestMapping("/error")//跟上面对应
public ModelAndView handlerException(){
ModelAndView mav = new ModelAndView();
mav.setViewName("exception");
mav.getModel().put("msg", "这是自定义的异常");
return mav;
}
}
4.2局部(@ExceptionHandler)
可以在某个Controller组件内部定义异常处理方法
@Controller //局部异常处理
public class LocalException {
@RequestMapping("/localException.do")
public String local(){
String[] s = null;
System.out.println(s.length);//抛出异常 下文接收
return "mav";//执行不到
}
@ExceptionHandler //这个只会处理本Controller内部的局部异常
public ModelAndView localException(Exception e){
ModelAndView mav = new ModelAndView();
mav.setViewName("error1");//异常页面不能用error命名 否则跟系统默认异常界面冲突
mav.getModel().put("exception", "异常信息是:"+e);
return mav;
}
}
//另一个Controller 要么继承 要么采用以下的标注
@ControllerAdvice//相当于所有Controller都继承了BasicController
public class BasicController {
@ExceptionHandler
public ModelAndView handlerException(Exception e){
ModelAndView mav = new ModelAndView();
mav.setViewName("exception");//exception.jsp
mav.getModel().put("error", "EmpController错误消息"+e);
return mav;
}
}
示例代码:https://github.com/CNxielong/SpringBoot/
boot-day04-deptClient boot-day04-deptServer
2.1URL设计规则
原有URL一般是按操作设计
http://localhost:8888/dept/list.do
http://localhost:8888/dept/load.do
http://localhost:8888/dept/add.do
http://localhost:8888/dept/delete.do
http://localhost:8888/dept/update.do
REST规则是按资源设计
http://localhost:8888/dept //部门资源
http://localhost:8888/dept/1 代表: //id=1的部门资源
2.2请求提交类型
原有URL提交类型
一般是GET(无中文、参数少)和POST(中文、参数多)
REST规则提交类型
查询 : GET
添加 : POST
更新 : PUT
删除 : DELETE
http://localhost:8888/dept/1
//GET表示查询id=1的dept信息,等价于load.do
//DELETE表示删除id=1的dept信息,等价于delete.do
//PUT表示更新id=1的dept信息,等价于update.do
http://localhost:8888/dept
//GET表示查询所有的dept信息,等价于list.do
//POST表示添加dept信息,等价于add.do
2.3请求参数提交
load.do?id=xx (get提交)或post提交
/dept/xx (将参数放置在请求URL路径中)
/dept?key=value (跟在URL后面使用key=value)
####### 2.4 post和get的区别
3.1 搭建SpringBoot环境
创建maven prject
在pom.xml添加jar包定义
4.0.0
cn.xdl
dept_server
0.0.1-SNAPSHT
war
rg.springframewrk.bt
spring-bt-starter-parent
1.4.7.RELEASE
UTF-8
UTF-8
1.7
rg.springframewrk.bt
spring-bt-starter
rg.springframewrk.bt
spring-bt-starter-jdbc
rg.mybatis.spring.bt
mybatis-spring-bt-starter
1.2.2
rg.springframewrk.bt
spring-bt-starter-web
rg.springframewrk.bt
spring-bt-starter-test
test
rg.springframewrk.bt
spring-bt-devtls
提示:ojdbc6驱动包build-path引入
添加application.properties
#server
server.port=8888
#datasource
spring.datasource.username=SCOTT
spring.datasource.password=TIGER
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
添加主启动类MyBootAppliation.java
@SpringBootApplication
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class, args);
}
}
3.2整合Mybatis实现DeptDao
编写实体类
public class Dept implements Serializable{
private Integer deptn;
private String dname;
private String lc;
public Integer getDeptn() {
return deptn;
}
public vid setDeptn(Integer deptn) {
this.deptn = deptn;
}
//... ...
}
编写Mapper接口
public interface DeptDao {
@Select("select * from dept")
public List<Dept> findAll();
@Select("select * from dept where deptno=#{id}")
public Dept findById(int id);
@Delete("delete from dept where deptno=#{id}")
public int delete(int id);
@Update("update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}")
public int update(Dept dept);
@Update("update dept set dname=#{dname} where deptno=#{deptno}")
//接口采用@Param import org.apache.ibatis.annotations.Param;
public int updateName(@Param("deptno")int id,@Param("dname")String name);
@Insert("insert into dept (deptno,dname,loc) values (#{deptno},#{dname},#{loc})")
@SelectKey(before=true,statement="select dept_seq.nextval from dual",
resultType=Integer.class,keyProperty="deptno")//提前提取序列
public int save(Dept dept);
}
在主启动类添加@MapperScan注解
@SpringBootApplication
@MapperScan(basePackages={"cn.xdl.boot.dao"})
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class, args);
}
}
3.3基于mvc编写DeptController
@RestController//搭配Rest
public class DeptController {
@Autowired
private DeptDao deptDao;
@RequestMapping(value="/dept",method=RequestMethod.GET)
public List loadAll(){
return deptDao.findAll();
}
@RequestMapping(value="/dept",method=RequestMethod.POST)
public int add(Dept dept){
return deptDao.save(dept);
}
@RequestMapping(value="/dept/{id}",method=RequestMethod.GET)
public Dept load(@PathVariable("id")int id){
//controller标注 org.springframework.web.bind.annotation.PathVariable;
return deptDao.findById(id);
}
@RequestMapping(value="/dept/{id}",method=RequestMethod.DELETE)
public int delete(@PathVariable("id")int id){
return deptDao.delete(id);
}
@RequestMapping(value="/dept/{id}",method=RequestMethod.PUT)
public int update(Dept dept){
return deptDao.update(dept);
}
}
3.4测试REST服务
浏览器输入http://localhost:8888/dept,测试/dept查询所有的部门信息
[{"deptno":10,"dname":"JAVA","loc":null},
{"deptno":20,"dname":"RESEARCH","loc":"DALLAS"},
{"deptno":30,"dname":"SALES","loc":"CHICAGO"},
{"deptno":40,"dname":"OPERATIONS","loc":"BOSTON"}]
浏览器输入http://localhost:8888/dept/10,测试查询id=10的部门信息(浏览器默认是GET)
{"deptno":10,"dname":"JAVA","loc":null}
4.0.0
cn.xdl
boot-day04-deptClient
0.0.1-SNAPSHOT
war
org.springframework.boot
spring-boot-starter-parent
1.4.7.RELEASE
UTF-8
UTF-8
1.7
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-devtools
<html>
<head>
<meta charset="UTF-8">
<title>Insert title heretitle>
<script type="text/javascript" src="js/jquery.min.js">
script>
<script type="text/javascript">
$(function() {
loadDept();
});
function loadDept() {//加载Dept的所有信息
var str = "";
$.ajax({
url : "http://localhost:8888/dept",
dataType : "json",
type : "get",
success : function(result) {
//result就是返回JSON格式的结果数据
for (var i = 0; i < result.length; i++) {
str += "" + result[i].dno + " "
+ result[i].dname + " " + result[i].dcity
+ " 删除 ";
//A标签 href可以变成蓝灰色超链接 点击不跳转链接
//).append(str);
},
error : function() {
alert("数据加载失败,AJAX跨域问题");
}
})
}
function del(id) {//对应后端Controller @Param("DNO")
alert(id);
alert("del方法");
$.ajax({
url : "http://localhost:8888/dept/" + id,
type : "delete",
dataType : "json",
success : function(result) {
alert("删除成功");
},
error : function() {
alert("删除失败");
}
});
};
script>
head>
<body>
<h1>部门管理h1>
<table id="dept_table">
table>
body>
html>
server:
port: 9999
context-path: /client
1.域名不同,Ajax会存在跨域问题
localhost:9999不允许访问localhost:8888,域名不同,json结果被限制返回。
解决方法分两种:
方法一: 如下2.和3.都要实现
2.在后台server端编写一个拦截器或过滤器
拦截器示例:implements HandlerInterceptor
package cn.xdl.boot.interceptor;
public class AjaxDomainInterceptor implements HandlerInterceptor{
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//设置允许跨域响应的参数
response.setHeader("Access-Control-Allow-Origin", "*");
response.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}
配置拦截器示例:
package cn.xdl.boot.interceptor;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
@Configuration//拦截器配置,配置AjaxDomainInterceptor拦截器
public class InterceptorConfig extends WebMvcConfigurerAdapter{
@Override
public void addInterceptors(InterceptorRegistry registry) {
AjaxDomainInterceptor ajaxDomain = new AjaxDomainInterceptor();//自定义的拦截器
registry.addInterceptor(ajaxDomain).addPathPatterns("/**");//拦截所有请求
}
}
package cn.xdl.ovls.course.util;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
@WebFilter(servletNames={"dispatcherServlet"})
//@WebFilter(urlPatterns="/*");//报错
public class AjaxDomainFilter implements Filter{
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
System.out.println("--------AjaxDomainFilter-----------");
//设置允许跨域响应的参数
HttpServletResponse httpRresponse = (HttpServletResponse)response;
httpRresponse.setHeader("Access-Control-Allow-Origin", "*");
httpRresponse.setHeader("Access-Control-Allow-Methods", "GET,POST,DELETE,PUT");
//放过请求处理
chain.doFilter(request, response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
}
@SpringBootApplication
@ServletComponentScan //引入组件扫描
@MapperScan(basePackages="cn.xdl.ovls.user.dao")
public class UserServiceBootApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceBootApplication.class, args);
}
}
1.application.yml文件 注意空格
server:
port: 9999
context-path: /client
2.layer插件
layer是一款近年来备受青睐的web弹层组件(jQuery弹出层插件)
链接:http://layer.layui.com/
文件名:deptLayer.html
Insert title here
部门管理
1.public (优先级最低)
2.static
3.resources
4.META-INF/resources(优先级最高)
5.自定义目录优先级最高(不过需要添加配置类 见下文2.)
每次浏览器访问静态资源,Boot会从优先级高的文件夹开始寻找。
访问方式:其中1.2.3.4 localhost:port/静态资源名(lcoal:8888/1.html不用输入public等文件名,按照加载优先级加载,新建自定义目录,也是这个执行顺序)
其中5 localhost:port/自定义目录/静态资源名(lcoal:8888/myresources/1.html)
在启动类子包下,添加配置类
@Configuration
public class ResourcesConfig extends WebMvcConfigurerAdapter{
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/myresources/**")
.addResourceLocations("classpath:/myresources/");
}
}
自定义目录优先级最高;如果请求是/**( /自定义文件名/** 不算),会将默认4个目录取消(但是可以访问默认目录)。建议不要映射/**请求
模板技术=模板文件+数据对象==》HTML响应界面输出
velocity=.vm模板文件(VTL表达式)+数据对象
freemark=.ftl模板文件(FTL表达式)+数据对象
thymeleaf=*.html模板文件(th表达式)+数据对象
JSP-->Servlet(EL+JSTL)-->HTML响应界面
SpringBoot对thymeleaf模板技术提供了支持,在html模板文件中可以使用th表达式直接访问ModelAndView中的Model数据。
- 流程:/hello.do-->DispatcherServlet-->HandlerMapping-->HelloController- ->ModelAndView-->thymeleaf引擎-->/templates/hello.html(th表达式)
1.在pom.xml中引入spring-boot-starter-thymeleaf工具包、需要spring-boot-starter-web作支持
org.springframework.boot
spring-boot-starter-thymeleaf
2.编写HelloController
@Controller
public class HelloController {
@RequestMapping("/hello.do")
public ModelAndView say(){
ModelAndView mav = new ModelAndView();
mav.setViewName("hello");//默认/templates/hello.html模板文件
mav.getModel().put("msg", "Hello Thymeleaf");
return mav;
}
}
3.在src/main/resources下创建templates/hello.html模板文件
<html xmlns:th="http://www.thymeleaf.org"> //提示:xmlns:th命名空间引入;html语法严格要求,标记有开始要有结束
<head>
<meta charset="UTF-8"/>
<title>Insert title heretitle>
head>
<body>
<h1>Thymeleaf 模板技术h1>
<h2 th:text="${msg}">h2>
body>
html>
4.配置application.properties
提示:thymeleaf模板文件默认位置为/templates;扩展名为.html,如果需要修改可以在application.properties中指定
spring.thymeleaf.prefix=classpath:/xxx/
spring.thymeleaf.suffix=.xxx
例如:
spring.thymeleaf.prefix=classpath:/template/ ##默认是templates
spring.thymeleaf.suffix=.html
1.采用HttpURLConnection
URL restURL = new URL(url);
HttpURLConnection conn = (HttpURLConnection) restURL.openConnection();
conn.setRequestMethod("POST");
conn.setDoOutput(true);
conn.getInputStream();
... ...
2.采用HttpClient工具
提前下载apache的httpclient工具包,然后代码如下:
参考链接: https://blog.csdn.net/ZhuangM_888/article/details/51535549
HttpClient httpClient = new DefaultHttpClient();
HttpGet req = new HttpGet(url);
HttpResponse resp = httpClient.execute(req);
HttpEntity entity = resp.getEntity();
InputStream input = entity.getContent();
3.采用Spring提供的RestTemplate对象
package cn.xdl.boot.controller;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.servlet.ModelAndView;
import cn.xdl.boot.entity.Dept;
@Controller
//@RestController
public class RestControllerA {//起名不能跟JAR包要引入的名称一致
@Autowired//自动配置已经创建了该对象
private RestTemplateBuilder templateBuilder;
@RequestMapping("/dept")
public String dept(ModelMap model){
RestTemplate restTemplate = templateBuilder.build();
List<Dept> list = new ArrayList<Dept>();
// 调用服务器端 http://localhost:8888/deptList获取部门服务信息
List<LinkedHashMap<String,Object>> forObject = restTemplate.getForObject("http://localhost:8888/dept", List.class);
// get请求对应get 返回的是对象对应Object post请求对应post 返回的是链接对应url restTemplate.postForLocation(url, request);
// System.out.println("forObject类型:"+forObject.getClass());
// Object obj = forObject.get(0);
// System.out.println(obj);
// System.out.println("obj类型:"+obj.getClass());
// System.out.println("obj类型:"+obj.getClass().getName());//LinkedHashMap类型
for (LinkedHashMap<String,Object> map : forObject) {
list.add(new Dept((Integer)map.get("dno"), (String)map.get("dname"), (String)map.get("dcity")));
}
model.put("deptList", list);
return "hello";//找到 application.properties下的 配置prefix suffix
}
@RequestMapping("/dept/beanUtils")//需要在MAVEN中引入beanUtils组件
public String showDeptList(ModelMap model){
System.out.println("进入了/dept");
RestTemplate restTemplate = templateBuilder.build();
System.out.println("restTemplate");
List<Dept> list = new ArrayList<Dept>();
//调用服务器端 http://localhost:8888/deptList获取部门服务信息
List<LinkedHashMap<String,Object>> forObject = restTemplate.getForObject("http://localhost:8888/dept", List.class);
//get请求对应get 返回的是对象对应Object post请求对应post 返回的是链接对应url restTemplate.postForLocation(url, request);
for (LinkedHashMap<String,Object> map : forObject) {
Dept dept = new Dept();
//将map对象信息封装成Dept对象
try {
BeanUtils.populate(dept, map);
} catch (IllegalAccessException | InvocationTargetException e) {
e.printStackTrace();
}//map中的key和dept中的属性名一致
list.add(dept);
}
model.put("deptList", list);
return "hello";//找到 application.properties下的 配置prefix suffix
}
}
commons-beanutils
commons-beanutils
1.1 编写Servlet组件,然后追加@WebServlet标记
package cn.xdl.boot.sservice;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;//pom.xml导入
/**
*
* @Title: MyServlet
* @Description: TODO(SpringBoot对JavaWeb支持 @WebServlet)
* @author X-Dragon
* @date 2018年10月31日 下午6:01:49
* @version V1.0
*
*/
//@WebServlet(name="webServlet")//可以 不规范
//@WebServlet(urlPatterns={"/myservlet.do"})//区分大小写
@WebServlet(urlPatterns="/myservlet.do",name="myservlet")//与下文拦截器匹配
public class MyServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO 不设置编码格式中文乱码
request.setCharacterEncoding("utf-8");//请求编码
response.setCharacterEncoding("utf-8");//响应编码
response.setContentType("text/html;charset=utf-8");//设置响应编码类型
String name = request.getParameter("name");
PrintWriter out = response.getWriter();
//pom.xml文件 引入了Apache Commons Lang » 3.4
if(StringUtils.isNotBlank(name)){//非空
out.println("Hello "+name);
}else{//为空
out.println("Hello 空字符串");
}
out.close();
}
}
1.2在主启动类前添加@ServletComponentScan
@SpringBootApplication
@ServletComponentScan//扫描servlet组件
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class, args);
}
}
package cn.xdl.boot.service;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
//@WebFilter(servletNames={"myservlet"})//指定要拦截的请求名称
@WebFilter(urlPatterns={"/myservlet.do"})//制定拦截器请求路径 这两种都行
public class MyFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
// TODO Auto-generated method stub
System.out.println("初始化过滤器");
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
response.setCharacterEncoding("UTF-8");
chain.doFilter(request, response);
System.out.println("--执行Filter--");
}
@Override
public void destroy() {
// TODO Auto-generated method stub
System.out.println("Filter destory");
}
}
2.主入口类添加@ServletComponentScan
@WebListener
public class MyListener
implements ServletContextListener,HttpSessionListener{//监听Servlet和Session
ServletContext application;//
// 执行顺序application contextInitialized sessionCreated
@Override
public void contextInitialized(ServletContextEvent arg0) {
application = arg0.getServletContext();
application.setAttribute("count", 0);
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
application.removeAttribute("count");
}
@Override
public void sessionCreated(HttpSessionEvent arg0) {
Integer count = (Integer)application.getAttribute("count");
count++;
application.setAttribute("count", count);
}
@Override
public void sessionDestroyed(HttpSessionEvent arg0) {
Integer count = (Integer)application.getAttribute("count");
count--;
application.setAttribute("count", count);
}
}
新建Servlet,URL输入http://localhost:9999/myservlet1 调用Session显示用户数
@WebServlet(urlPatterns={"/myservlet1"})//区分大小写
public class MyServlet1 extends HttpServlet {
@Override
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// TODO 不设置编码格式中文乱码
request.setCharacterEncoding("utf-8");//请求编码
response.setCharacterEncoding("utf-8");//响应编码
response.setContentType("text/html;charset=utf-8");//设置响应编码类型
String name = request.getParameter("name");
PrintWriter out = response.getWriter();
//pom.xml文件 引入了Apache Commons Lang » 3.4
if(StringUtils.isNotBlank(name)){//非空
out.println("Hello "+name);
}else{//为空
out.println("Hello 空字符串");
}
Integer count = (Integer)request.getServletContext().getAttribute("count");//只写这一行不会触发
request.getSession();//获取一下Session
out.println("在线用户数"+count);
out.close();
}
}
主入口类添加@ServletComponentScan
代码路径:/SpringBoot/boot-dayo4-static
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-aopartifactId>
dependency>
package cn.xdl.boot.aspect;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
import org.springframework.util.StopWatch;
@Component
@Aspect
public class WatchBean {
// @Around("within(cn.xdl.boot.controller..*)")
@Around(value="within(cn.xdl.boot.controller..*)")//标记要切入的Controller类
public Object watch(ProceedingJoinPoint pjp) throws Throwable {//ProceedingJoinPoint pjp封装切入方法的信息
System.out.println("前置通知执行");
StopWatch sw = new StopWatch();//记录服务调用时间
sw.start();
Object obj = pjp.proceed();//执行调用目标组件方法(Controller的方法) obj封装方法返回值
sw.stop();
long time = sw.getTotalTimeMillis();//记录服务调用时间 第一次时间久
Object target = pjp.getTarget();
//记录服务调用时间、处理时间、服务组件名、方法名等信息
System.out.println("pjp.getTarget():"+target);//输出 pjp.getTarget():cn.xdl.boot.controller.DeptController@58fd1503
String targetName = pjp.getTarget().getClass().getName();//目标组件名 cn.xdl.boot.controller.DeptController
String methodName = pjp.getSignature().getName();//目标方法名 loadAll
System.out.println("执行的组件为:"+targetName+" 方法为:"+methodName+" 返回结果:"+obj+" 处理时长:"+time);
return obj;//返回的结果就是请求返回的结果 此处是DEPT集合
}
}
1.启动立刻执行的任务
1.1 编写任务实现类,实现CommandLineRunner接口
2. @Component
3. public class MyTask1 implements CommandLineRunner{
4.
5. @Override
6. public void run(String... args) throws Exception {
7. System.out.println("开始执行任务1");
8. }
9.
10. }
1.2 编写任务实现类,实现ApplicationRunner接口
@Component
@Order(2)
public class MyTask2 implements ApplicationRunner{
@Override
public void run(ApplicationArguments args) throws Exception {
System.out.println("开始执行任务2");
}
}
提示:多个任务时,可以使用@Order(2)指定任务调用顺序,1、2、3…。
2.定时周期性调用任务
1.编写任务类,追加@EnableScheduling和@Scheduled标记
@Component
@EnableScheduling//启用定时计划
public class MyTask3 {
@Scheduled(cron="0/5 * * * * ?")//每隔5秒中调用一次。
public void run(){
System.out.println("定时执行任务3:"+new Date());
}
}
2.corn表达式
参考下面资料
Corn表达式:https://www.cnblogs.com/javahr/p/8318728.html
org.springframework.boot
spring-boot-starter-actuator
2.0.4.RELEASE
http://localhost:8888/mappings 显示出系统映射信息
http://localhost:8888/health 显示出系统健康信息
org.springframework.boot
spring-boot-starter-actuator
2.0.4.RELEASE
#server
server.port=8888
#datasource
spring.datasource.username=system
spring.datasource.password=123456
spring.datasource.url=jdbc:oracle:thin:@localhost:1521:XE
spring.datasource.driver-class-name=oracle.jdbc.OracleDriver
#druid
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
package cn.xdl.boot.druid;
import javax.servlet.annotation.WebInitParam;
import javax.servlet.annotation.WebServlet;
import com.alibaba.druid.support.http.StatViewServlet;
@WebServlet( urlPatterns = "/druid/*", initParams = {
@WebInitParam(name = "exclusions", value = "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"), // 忽略资源
@WebInitParam(name = "loginUsername", value = "system"), //用户名大小写敏感 如果写错了会直接登录 不需要密码
@WebInitParam(name = "loginPassword", value = "123456") })//密码
public class DruidStatViewServlet extends StatViewServlet {
/**
* serialVersionUID
*/
private static final long serialVersionUID = 1L;
}
package cn.xdl.boot.druid;
import javax.servlet.annotation.WebFilter;
import javax.servlet.annotation.WebInitParam;
import com.alibaba.druid.support.http.WebStatFilter;
@WebFilter(filterName = "druidFilter", urlPatterns = "/*", initParams = {
@WebInitParam(name = "exclusion", value = "*.js,*.gif,*.jpg,*.bmp,*.css,*.png,*.ico,/druid/*") }) // 忽略资源
public class DruidStatFilter extends WebStatFilter {
}
@Configuration
public class DruidConfig {
@Value("${spring.datasource.url}")
private String dbUrl;
@Value("${spring.datasource.username}")
private String username;
@Value("${spring.datasource.password}")
private String password;
@Value("${spring.datasource.driver-class-name}")
private String driverClassName;
@Bean
public DataSource createDruid(){
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(dbUrl);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setDriverClassName(driverClassName);
try {
datasource.setFilters("stat");//启动sql监控
} catch (SQLException e) {
e.printStackTrace();
}
return datasource;
}
}
package cn.xdl.boot;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@MapperScan(basePackages={"cn.xdl.boot.dao"})//接口文件类没有标注需要制定包名
@ServletComponentScan//带@标记组件的不需要指定包名
public class MyBootApplication {
public static void main(String[] args) {
SpringApplication.run(MyBootApplication.class, args);
System.out.println("服务器端:8888启动");
}
}
补充:Maven 中央仓库地址
1、http://www.sonatype.org/nexus/ 私服nexus工具使用
2、http://mvnrepository.com/ (推荐)
3、http://repo1.maven.org/maven2
4、http://maven.aliyun.com/nexus/content/groups/public/ 阿里云 (强力推荐)
5、http://repo2.maven.org/maven2/ 私服nexus工具使用
6、http://uk.maven.org/maven2/
7、http://repository.jboss.org/nexus/content/groups/public
8、http://maven.oschina.net/content/groups/public/ oschina可惜啦,以前一直用这个,不过现在有阿里云来擦屁股啦
9、http://mirrors.ibiblio.org/maven2/
10、http://maven.antelink.com/content/ repositories/central/
11、http://nexus.openkoala.org/nexus/content/groups/Koala-release/
12、http://maven.tmatesoft.com/content/groups/public/
其实,国内maven镜像虽然快,但是更新比较慢,国外的仓库由于国内网络的原因,下载简直不能忍,但是更新很快,可以根据自身的情况选择,有些人会花些钱开代理访问外网比较快,建议使用原装。下面是maven库配置
oschina-repo 开源中国镜像 central 可以根据自己的网络情况选填上面的url
1.pom.xml文件配置信息
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
2.Junit测试类代码
package cn.xdl.boot.user.test;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import cn.xdl.ovls.user.UserServerBootApplicaiton;
import cn.xdl.ovls.user.dao.UserMapper;
import cn.xdl.ovls.user.entity.User;
@RunWith(SpringRunner.class)
@SpringBootTest(classes=UserServerBootApplicaiton.class)
public class TestUserDao {
@Autowired
private UserMapper userDao;
@Test// run as Junit test
public void TestSelect(){
User user = userDao.selectByPrimaryKey(1);
if(user != null){
System.out.println(user);
}else{
System.out.println("查询结果为空");
}
}
}
3、主入口类加@MapperScanner标注
package cn.xdl.ovls.user;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
@SpringBootApplication
@ServletComponentScan //引入组件扫描
@MapperScan(basePackages="cn.xdl.ovls.user.dao")//指定DAO 接口位置
public class UserServerBootApplicaiton {
public static void main(String[] args) {
SpringApplication.run(UserServerBootApplicaiton.class, args);
}
}
package cn.xdl.ovls.user.controller.test;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.RequestBuilder;
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import cn.xdl.ovls.user.UserServiceBootApplication;
import cn.xdl.ovls.user.controller.UserController;
/**
*
* @Title: TestUserController
* @Description: TODO(MockMVC测试)
* @author X-Dragon [email protected]
* @version V1.0
*
*/
@RunWith(SpringRunner.class) //固定写法
@SpringBootTest(classes={UserServiceBootApplication.class})
public class TestUserController {
@Autowired
private UserController userController;
private MockMvc mockmvc;
@Before
public void init(){
//创建MockMVC对象
mockmvc = MockMvcBuilders.standaloneSetup(userController).build();
}
@Test
public void test1() throws Exception{
MockHttpServletRequestBuilder postRequest = MockMvcRequestBuilders.post("/user/token") //设置提交方式
.param("name", "xielong") //设置变量
.param("password", "123456");
//执行请求,获取返回结果
MvcResult mvcResult = mockmvc.perform(postRequest).andReturn();
//获取返回结果内容打印输出
String body = mvcResult.getResponse().getContentAsString();
System.out.println("查询结果是"+body);
}
}
1、@RequestParam和@PathVariable和@PathParam
区分标注: https://blog.csdn.net/u011410529/article/details/66974974
https://blog.csdn.net/a67474506/article/details/46361195
代码:https://github.com/CNxielong/SpringBoot/tree/master/boot
@PathVariable:变量 http://localhost:8888/boot/pathVariable/bigsea
@RequestMapping("/pathVariable/{name}")
public String pathVariable(@PathVariable("name")String name)
@RequestParam:参数 http://localhost:8888/boot/requestParam?firstName=big&lastName=sea
@RequestMapping("/requestParam")
public String requestParam(@RequestParam(value="firstName",required=false)String firstName,
@RequestParam( value="lastName" ,required = true) String lastName,
@RequestParam(value="age",required = false ,defaultValue="0")int age)
看下面一段代码:
@RestController
public class Controller {
/**
* http://localhost:8888/boot/pathVariable/bigsea
* http://localhost:8888/boot/pathVariable/sea
* http://localhost:8888/boot/pathVariable?name=xielong报错
* 这些URL 都会 执行此方法 并且将 bigsea、sea 作为参数 传递到name字段
* @param name
* @return
*/
@RequestMapping("/pathVariable/{name}")
public String pathVariable(@PathVariable("name")String name){
System.out.println("hello "+name); //在控制台打印
return "helloworld"+"/pathVariable/"+name;//在页面上打印出来
}
/**
* http://localhost:8888/boot/requestParam?firstName=big&lastName=sea
* http://localhost:8888/boot/requestParam?lastName=sea&age=23
* http://localhost:8888/boot/requestParam 报错400 Required String parameter 'lastName' is not present
* 如果 required = true 则表示请求参数对应的字段必须存在.如果不存在则会抛出异常
* @param firstName 可以为null
* @param lastName 不能为null .为null报异常
* @param age age字段表示如果没有 age 参数 则默认值为 0
* @return
*/
@RequestMapping("/requestParam")
public String requestParam(@RequestParam(value="firstName",required=false)String firstName,
@RequestParam( value="lastName" ,required = true) String lastName,
@RequestParam(value="age",required = false ,defaultValue="0")int age) {
System.out.println("hello my name is " + (firstName == null ? "" : firstName)
+ lastName + "," + age +" years old this year");
return "helloworld";
}
}
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
public String getDetails(
@RequestParam(value="param1", required=true) String param1,
@RequestParam(value="param2", required=false) String param2){
...
}
@RequestParam 支持下面四种参数
defaultValue 如果本次请求没有携带这个参数,或者参数为空,那么就会启用默认值
name 绑定本次参数的名称,要跟URL上面的一样
required 这个参数是不是必须的
value 跟name一样的作用,是name属性的一个别名
http://localhost:8888/boot/pathVariable/bigsea
http://localhost:8888/boot/pathVariable/bigsea
http://localhost:8888/boot/pathVariable/sea
/**
* http://localhost:8888/boot/pathVariable/bigsea
* http://localhost:8888/boot/pathVariable/sea
* http://localhost:8888/boot/pathVariable?name=xielong报错
* 这些URL 都会 执行此方法 并且将 bigsea、sea 作为参数 传递到name字段
* @param name
* @return
*/
@RequestMapping("/pathVariable/{name}")
public String pathVariable(@PathVariable("name")String name){
System.out.println("hello "+name); //在控制台打印
return "helloworld"+"/pathVariable/"+name;//在页面上打印出来
}
http://localhost:8080/springmvc/hello/101?param1=10¶m2=20
上面的一个url你可以这样写:
@RequestMapping("/hello/{id}")
public String getDetails(@PathVariable(value="id") String id,
@RequestParam(value="param1", required=true) String param1,
@RequestParam(value="param2", required=false) String param2){
.......
}
区别很明显了
@PathParam
@QueryParam
@ResponseBody
@RequestBody
比如:
/user/{userId} 可匹配user/123 user/abc
/company/{companyId}/user/{userId}/detail 可匹配/company/123/user/456/detail
– ?:匹配文件名中的一个字符
– *:匹配文件名中的任意字符
– **:** 匹配多层路径
实例:
URL : /user/*/create
-- /user/bigsea/create 、 /user/sea/create 等URL
URL : /user/**/create
-- /user/big/sea/create 、 /user/sea/big/create 等URL
URL : /user/create??
-- /user/createaa 、/user/createbb
4.0.0
cn.xdl
ovls_eureka_server
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
1.4.7.RELEASE
UTF-8
UTF-8
1.7
org.springframework.cloud
spring-cloud-starter-eureka-server
1.3.4.RELEASE
org.springframework.cloud
spring-cloud-starter-parent
Brixton.SR5
pom
#server
server.port=2222
#eureka spring.application.name推荐全英文字符、区分大小写。不要写"_ -"等非法字符
spring.application.name=EurekaServer
eureka.client.registerWithEureka=false
eureka.client.fetchRegistry=false
eureka.client.serviceUrl.defaultZone=http://localhost:2222/eureka
package cn.xdl.ovls;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer//启用eureka服务器
@SpringBootApplication
public class EurekaServerBootApplication {
public static void main(String[] args) {
// TODO Auto-generated method stub
SpringApplication.run(EurekaServerBootApplication.class, args);
}
}
1.在需要使用Cloud的子项目(ovls_user_server和ovls_user_paper)中的pom.xml中追加spring-cloud-eureka定义
org.springframework.cloud
spring-cloud-starter-parent
Brixton.SR5
pom
org.springframework.cloud
spring-cloud-starter-eureka-server
1.3.4.RELEASE
user_server和paper_server服务调用Cloud。user_server的POM.xml如下
4.0.0
cn.xdl
ovls_user_server
0.0.1-SNAPSHOT
war
org.springframework.boot
spring-boot-starter-parent
1.4.7.RELEASE
UTF-8
UTF-8
1.7
org.springframework.cloud
spring-cloud-starter-parent
Brixton.SR5
pom
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-jdbc
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.2.2
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
com.alibaba
druid
1.1.6
mysql
mysql-connector-java
org.springframework.cloud
spring-cloud-starter-eureka-server
1.3.4.RELEASE
2.在application.properties添加eureka注册参数
#Eureka spring.application.name不能写一些非法字符"- _"推荐纯字母 大小写敏感
spring.application.name=USERSERVER
eureka.client.serviceUrl.defaultZone=http://localhost:2222/eureka
user_server的如下
#server
server.port=8881
#dataSource
spring.datasource.username=root
spring.datasource.password=123123
spring.datasource.url=jdbc:mysql://localhost:3306/studyonline?useUnicode=true&characterEncoding=utf8
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#Eureka spring.application.name不能写一些非法字符"- _"推荐纯字母 大小写敏感
spring.application.name=USERSERVER
eureka.client.serviceUrl.defaultZone=http://localhost:2222/eureka
#是否将自己注册到Eureka Server上,默认为true
eureka.client.register-with-eureka=false
#是否从Eureka Server上获取注册信息,默认为true
eureka.client.fetch-registry=false
#Druid
#spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
3.在主启动类追加@EabledDiscoveryClient
@EnableEurekaServer
@SpringBootApplication
@ServletComponentScan //引入组件扫描
@MapperScan(basePackages="cn.xdl.ovls.user.dao")
public class UserServiceBootApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceBootApplication.class, args);
}
}
4.浏览器输入IP+Port访问注册中心.注意paper_server也要注册,图片没有显示。
1.在需要使用RestTemplate的项目(paper_Server)中pom.xml中定义ribbon开发包
org.springframework.cloud
spring-cloud-starter-ribbon
1.3.4.RELEASE
2.定义一个RestTemplate配置,启用ribbon负载
package cn.xdl.ovls.paper.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class RestTemplateConfig {
@Bean
@LoadBalanced//启用ribbon负载均衡调用策略
public RestTemplate createRestTemplate(){
return new RestTemplate();
}
}
3.在需要使用RestTemplate的类中用Autowired注入,调用eureka服务
@Component
public class CheckLoginInterceptor implements HandlerInterceptor{
@Autowired//找到config下的 RestTemplate
private RestTemplate restTemplate;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//获取请求带过来的token
String token = request.getParameter("token");
System.out.println("调用/user/token服务检查token是否合法"+token);
response.setContentType("application/json;charset=UTF-8");
if(token != null && !"".equals(token)){
//调用/user/token服务检查token是否合法,合法就返回true,不合法返回false
//调用ovls_course_server的服务查询所有学科信息 ovls_user_server替代原先的IP和端口号
ResponseResult userResult = restTemplate.getForObject(
"http://USERSERVER/user/token?token="+token, ResponseResult.class);
System.out.println(userResult);
if(userResult.getStatus()==1){//通过验证,表示token合法
return true;
}
}
//未通过验证
PrintWriter out = response.getWriter();
out.println("{\"stauts\":2,\"msg\":\"不合法用户\"}");
out.close();
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}
org.springframework.cloud
spring-cloud-starter-ribbon
1.3.4.RELEASE
org.springframework.cloud
spring-cloud-starter-feign
1.3.4.RELEASE
ovls_paper_server全部pom.xml
4.0.0
cn.xdl
ovls_paper_server
0.0.1-SNAPSHOT
org.springframework.boot
spring-boot-starter-parent
1.4.7.RELEASE
UTF-8
UTF-8
1.7
org.springframework.cloud
spring-cloud-starter-parent
Brixton.SR5
pom
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-aop
org.springframework.boot
spring-boot-starter-actuator
org.springframework.boot
spring-boot-starter-jdbc
org.mybatis.spring.boot
mybatis-spring-boot-starter
1.2.2
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-devtools
com.alibaba
druid
1.1.6
mysql
mysql-connector-java
com.github.pagehelper
pagehelper-spring-boot-starter
1.2.3
org.springframework.cloud
spring-cloud-starter-eureka-server
1.3.4.RELEASE
org.springframework.cloud
spring-cloud-starter-ribbon
1.3.4.RELEASE
org.springframework.cloud
spring-cloud-starter-feign
1.3.4.RELEASE
2.定义一个Fegin远程调用接口
package cn.xdl.ovls.paper.remote;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import cn.xdl.ovls.paper.util.ResponseResult;
/**
*
* @Title: UserServiceRemote
* @Description: TODO(FeignClient对应哪个服务实例)
* @author X-Dragon
* @version V1.0
*
*/
@FeignClient(name="USERSERVER")//对应微服务的 服务端名称
public interface UserServiceRemote {
//调用 http://USERSERVER/user/token?token=
//有参数需要用value
//method设置请求方式,不设置默认是GET
@RequestMapping(value="/user/token",method=RequestMethod.GET)
ResponseResult checkToken(String token);
}
3.在需要用Feign的Class文件中,远程接口对象,使用服务
@Autowired
private UserServiceRemote userRemote;
//利用Remote对象调用服务
ResponseResult userResult = userRemote.checkToken(token);
CheckLoginInterceptor中用到了Feign接口
@Component
public class CheckLoginInterceptor implements HandlerInterceptor{
@Autowired//找到remote包下的UserServiceRemote接口
private UserServiceRemote userServiceRemote;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
//获取请求带过来的token
String token = request.getParameter("token");
System.out.println("调用/user/token服务检查token是否合法"+token);
response.setContentType("application/json;charset=UTF-8");
if(token != null && !"".equals(token)){
//调用/user/token服务检查token是否合法,合法就返回true,不合法返回false
//调用figen接口的实现类 直接RPC调用方法
ResponseResult userResult = userServiceRemote.checkToken(token);
System.out.println(userResult);
if(userResult.getStatus()==1){//通过验证,表示token合法
return true;
}
}
//未通过验证
PrintWriter out = response.getWriter();
out.println("{\"stauts\":2,\"msg\":\"不合法用户\"}");
out.close();
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
// TODO Auto-generated method stub
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// TODO Auto-generated method stub
}
}
4.在主入口启动类前追加@EnableFeignClients标记
package cn.xdl.ovls.paper;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
@EnableFeignClients// 用到Feign
@EnableEurekaClient// @EnableEurekaClient包含@EnableDiscoveryClient 此处可以用EnableDiscoveryClient代替
//@EnableDiscoveryClient
@SpringBootApplication
@MapperScan(basePackages="cn.xdl.ovls.paper.dao")
@ServletComponentScan //引入组件扫描
public class PaperServiceBootApplication {
public static void main(String[] args) {
SpringApplication.run(PaperServiceBootApplication.class, args);
}
}
eureka.client.register-with-eureka=false #是否将自己注册到Eureka Server上,默认为true
eureka.client.fetch-registry=false #是否从Eureka Server上获取注册信息,默认为true
第一种写法:
原符号 < <= > >= & ' "
替换符号 < <= > >= & ' "
例如:sql如下:
create_date_time >= #{startTime} and create_date_time <= #{endTime}
第二种写法:
大于等于:= ]]>
小于等于:
例如:sql如下:
create_date_time = ]]> #{startTime} and create_date_time #{endTime}
Mybatis转义字符表
< < 小于
> > 大于
& & 与
' ' 单引号
" " 双引号
需要注意的是分号是必不可少的。 比如 a > b 我们就写成 a > b
当然啦, 我们也可以用另外一种,就是 符号。 在mybatis中这种符号将不会解析。 比如