SpringBoot结合FreeMarker开发

SpringBoot

1 定义

基于spring的做了二次开发的快速开发框架。

//javaweb项目从开始到运行有哪些步骤

1.创建Web项目2.导入依赖 3.编写代码 4.项目编译成war包 5. 配置Web应用服务器(Tomcat) 6.将war包,发布到tomcat上 7.启动tomcat 8.浏览器访问tomcat端口

常见的Web应用服务器:Tomcat 、JBoss、WebLogic、IBM WebSphere

2 常见的核心注解

@SpringBootApplication 用于Spring主类上最最最核心的注解,自动化配置文件,表示这是一个SpringBoot项目,用于开启SpringBoot的各项能力。相当于@SpringBootConfigryation、@EnableAutoConfiguration、@ComponentScan三个注解的组合保持SpringBootApplication文件最最外层目录,不然扫描不到外层的类

@SpringBootConfiguration 所有的主键类都会被该注解给监测到

@EnableAutoConfiguration 自动加载我们整个项目Configuratio类与Component类

3 MVC

在处理一个request请求的时候分为三个层次。

V 视图层------->JSP,Html(超文本标记语言),ftl

在springboot搭配mvc的时候V层用FreeMarker

C 控制层------->Servlet

C层使用DispatchServlet从而转化注解为@Controller

M 模型层------>业务逻辑处理与持久化(即数据模型处理->保存在数据库等)javabean

M层上由Service和Repository Mybatis延伸的@Mapper

4.初次配置尝试(不连接数据库)

1.创建项目(略)

2.添加依赖(这一步其实在创建项目时就可以完成)

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

3.前端界面简写

<form action="/sign" method="post">
    <table align="center" style="margin-top: 20px">
        <tr><td colspan="2" align="center"></td><td>用户登录</td></tr>
        <tr><td>用户名:</td><td><input type="text" name="username"></td></tr>
        <tr><td>密码:</td><td><input type="text" name="password"></td></tr>
        <tr><td><input type="submit" value="登录"></td><td><input type="submit" value="注册"></td></tr>
    </table>
</form>

4.配置配置文件application.properties

#更改访问端口,可以解决端口被占用问题
server.port=9999
#模板能够被支持,开启freemarker对html的支持
spring.freemarker.suffix=.html
#打开静态文件的权限
#在springboot2.3以前是没有带web,即spring.resources.static-locations
spring.web.resources.static-locations=classpath:/templates

5.控制类创建controller

//Controller是一个springMVC中接受并处理请求的实现类,可以通过该类型的类去做请求的调度与分发,通常称为控制器类,它是SpringMVC的具体实现
@Controller//该注解声明此类是一个控制器类
public class LoginController{   
    @RequestMapping("/sign")
    //处理所有http所有请求类型的请求
    //@GetMapping、@PostMapping、@DeleteMapping、@PutMapping等 处理具体http请求类型 ,类型不匹配将报405
    //get与post是http协议中提交数据的方式,
    //@ResponseBody//将处理结果转化成json的形式转换出去{key:value}
    public String sign(@RequestParam("username")String name, @RequestParam("password")String password){
        if("admin".equals(name)&&"123456".equals(password)){return "index";}
        else {return "login";}}}

http八种提交请求的方式:OPTIONS、HEAD、GET、POST、PUT、DELETE、TRACE、CONNECT

6.启动tomcat,访问 http://localhost:9999/login.html

5.SpringBoot配置文件

优点:更改配置参数时,不需要重新修改逻辑代码 需要重启tomcat

1.Application.properties默认级 参数形式为key-vlaue 键值对形式

2.Application.yml

3.自定义名的properties、yml 不会默认加载,需要手工指定

@PropertySource("classpath:/***.properties")

加载顺序—四个位置寻找配置文件

一.查看项目一级子目录是否有config文件夹

二.查看整个项目中是否有配置文件

三.查看resources中是否有config文件夹

四.查看resources中是否有配置文件

配置文件示例为教师类的id与name属性 以及复杂属性map,list

对对象进行传参时有两种方式

a.通过@Value注解在每个属性上逐个传

public class Teacher {
    @Value("${tch.id}")
        private int id;
    @Value("${tch.name}")
        private String name;}

b.通过@Configuration注解在类上统一传

@ConfigurationProperties(prefix ="tch")//添加依赖spring-boot-configuration-processor
public class Teacher {
    private int id;
    private String name;}

1).properties

tch.id=1001
tch.name=Mike
tch.hashmap.key1=key1
tch.hashmap.value1=value1
tch.hashmap.key2=key2
tch.hashmap.value2=value2
tch.list=q,w,e,r,t,y,u,i,o,p

2).yml

#缩进代表同不同级
#书写方式 名字+":"+空格+赋值名
tch:
  id: 2020
  name: mike
  langurage: yml
  hashmap:
    k1: k1
    val1: val1
    k2: k2
    val2: val2
  list:
    - 123
    - 456
    - 789

注意:当发生参数没有发生优先级顺数的时候则会将所有配置文件中的参数储存进来

yml文件与peoperties冲突时,会优先选择peoperties中的配置

6.配置文件实现尝试

1.创建自定义注解@PropertyLoad

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface PropertyLoad{String name() default "";}

2.创建BeanFactory

public class BeanFactory {
    Properties properties = new Properties();
    public Object getBean(String classname){
		 Object obj =  null;
        try{
            Class clss =  Class.forName(classname);
            obj=clss.newInstance();
            PropertyLoad annotation =  (PropertyLoad)clss.getAnnotation(PropertyLoad.class);
            if(annotation != null)
            {	String properyUrl =  annotation.name();
                FileInputStream fis = new FileInputStream(properyUrl);
                properties.load(fis);}
			Field[] propery =  clss.getDeclaredFields();
            for (Field field : propery)
            {	String value = properties.getProperty("game."+field.getName());
                field.setAccessible(true);
                field.set(obj,transfor(field.getGenericType(),value));}
		} catch (Exception e) {e.printStackTrace();
        }finally {return obj;}}
	public Object transfor(Object o,Object value)
    {	System.out.println(o);
        if(o.toString().equals("int")){return Integer.parseInt(value+"");}
        else{return  String.valueOf(value);}}}

3.创建对象类Games,使用注解

@PropertyLoad(name="D:\\路径\\src\\main\\resources\\games.properties")
public class Games
{	private int id;
    private String name;
	public int getId() {return id;}
	public void setId(int id) {this.id = id;}
	public String getName() {return name;}
	public void setName(String name) {this.name = name;}
}

4.配置参数

game.id=666
game.name=timi

5.测试类,尝试读取peoperties文件获取game的值

public class RunTest{
    public static void main(String[] args) {
        BeanFactory beanFactory = new BeanFactory();
        Games games = (Games)beanFactory.getBean("sunjob.springboots880930.vo.Games");
        System.out.println(games.getId());
        System.out.println(games.getName());}}

7.SpringBootMVC

springmvc只保留了以前jsp内置对象中的四个作用域对象:Request,Response,Session,application

springmvc四大作用域:

PageContext对象: 作用域范围:当前jsp页面内有效

request对象: 作用域范围:一次请求内。 作用: 解决了一次请求内的资源的数据共享问题

*session对象: 作用域范围:一次会话内有效。 说明:浏览器不关闭,并且后台的session不失效,在任意请求中都可以获取到同一个session对象,**作用:*解决了一个用户不同请求的数据共享问题。

application(ServletContext)对象: 作用域范围:整个项目内有效。 特点:一个项目只有一个,在服务器启动的时候即完成初始化创建无论如何获取都是同一个项目。

jsp内置对象:request、response、session、application、out、pagecontext、config、page、exception

名称 类型 含义 获取方式
request HttpServletRequest 封装所有请求信息 方法参数
response HttpServletResponse 封装所有相应信息 方法参数
session HttpSession 封装所有会话信息 req.getSession()
application ServletContext 所有信息 req.getServletContext()
out PrintWriter 输出对象 rep.getWriter
pagecontext PageContext 获取其他对象
config ServletConfig 配置信息
page Object 当前页面对象
exception Exception 异常对象

8.Web项目传值实现

1.项目创建

2.依赖添加

3.前端页面简写,一个登陆界面(后面内容所需,创建两个表单,一个连接),一个首页(首页内容略写)

<form action="/index" method="post">
   <table align="center" style="margin-top: 20px">
       <tr><td colspan="2" align="center"></td><td>用户登录</td></tr>
       <tr><td>用户名:</td><td><input type="text" name="username"></td></tr>
       <tr><td>密码:</td><td><input type="password" name="password"></td></tr>
       <tr><td><input type="submit" value="登录"></td><td><input type="submit" value="注册"></td></tr>
   </table>
</form>

<a href="/pathvar/这里是传输到控制器类的值">路径传值..</a>

<form action="/modelandview" method="post">
   <table align="center" style="margin-top: 20px">
       <tr><td colspan="2" align="center"></td><td>用户登录</td></tr>
       <tr><td>用户名:</td><td><input type="text" name="username"></td></tr>
       <tr><td>密码:</td><td><input type="password" name="password"></td></tr>
       <tr><td><input type="submit" value="登录"></td><td><input type="submit" value="注册"></td></tr>
    </table>
</form>
  1. 创建控制器类

    1. 前往服务端传值的三种方式

      @Controller
      public class LoginController {
          //@RequestParam 参数注解,作用在参数之上
          @RequestMapping("/sign")
          @ResponseBody
          public String sign(@RequestParam(value = "username",required = false/*你可以带也可以不带这个参数*/) String name,@RequestParam(value = "password",required = false) String pwd){return "welcome";}
          
      	//@PathVariable
          @RequestMapping("/pathvar/{abc}")//{abc}占位作用 pathvar传值之后都会带上{abc}的内容 web接口传值使用pathvar 如果是前端视图层传值最好不适用pathvar
          @ResponseBody
          public String pathvar(@PathVariable("abc")String value){return value;}
      
          //@ModelAttribute
          @RequestMapping("/model")
          @ResponseBody
          //model对象会将form表单中带有name中所有值打包,注意点表单里面的name属性名字要保证一样  @ModelAttribute可以省略 默认使用该方式
          public User model(User user){return user;}}
      
    2. 服务端往视图层页面传值的三种常用方式

    @Controller
    public class ResponseController {
        //内置对象传值,四种作用域对象
        @RequestMapping("/index")
        public String returnToIndex(@RequestParam(value = "username",required = false/*你可以带也可以不带这个参数*/) String name,@RequestParam(value = "password",required = false) String pwd, HttpServletRequest request, Model model){
            request.setAttribute("user",name);
            request.setAttribute("pwd",pwd);
    
            request.getSession().setAttribute("usersession",name);
            request.getSession().setAttribute("pwdsession",pwd);
    
            ServletContext servletContext = request.getSession().getServletContext();//比Session保存时间更久,是要tomcat不停随时都可以取到
            servletContext.setAttribute("servletcontextuser",name);
            servletContext.setAttribute("servletcontextpwd",pwd);
            Enumeration enumeration = servletContext.getAttributeNames();
            while (enumeration.hasMoreElements()){
                System.out.println("key:"+enumeration.nextElement());
               System.out.println("vlaue"+servletContext.getAttribute(enumeration.nextElement().toString()));
            }
            System.out.println(request.getAttribute("user"));
            System.out.println(request.getSession().getAttribute("usersession"));
    
            User user =new User();
            user.setId(11);
            user.setUsername("Sandy");
            user.setPassword("12131");
    
            model.addAttribute(user);//默认的参数名为类名首字母小写
    
            model.addAttribute("modeluser",name);
            model.addAttribute("modelpwd",pwd);
            return "welcome";}
        
         //通过springmvc内置对象model
        @RequestMapping("/nextindex")
        public String returnToIndex(HttpServletRequest request,Model model){return "next";}
    
         //springmvc ModelAndView
        @RequestMapping("/modelandview")
        public ModelAndView modelAndView(@RequestParam(value = "username",required = false) String name,
                                         @RequestParam(value = "password",required = false) String pwd){
            ModelAndView modelAndView = new ModelAndView("modelandview");
            modelAndView.addObject("modelviewuser",name);
            modelAndView.addObject("modeviewpwd",pwd);
            return modelAndView;}}
    
  2. ResponseController需要一个实体类(省略了get与set方法)

@Component
public class User {
    private String username;
    private String password;
    private int id;
    private String remark;}

9.视图模板技术(Freemarker)

视图模板技术有两种Themleaf , Freemarker

1.导入freemarker依赖

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

2.配置freemarker参数

spring.freemarker.suffix=.文件后缀

3.基本与复杂数据类型书写

字符串类型:${"this is string"}
数值类型:${123}
布尔类型:${true?c} or ${false?c}

利用标签的创建变量并给变量赋值:

<#assign str="string"/>					${str}   					<---string--->
<#assign str1>string1</#assign>			${str1}						<---string1-默认为字符串类型--->
<#assign intval=12/>					${intval}					<---12--->

列表类型索引获取:

<#assign listval=["abc","def","hij"]/>

${listval[0]}<br>
${listval[1]}<br>
${listval[2]}<br>
    
<#list listval as i><---遍历查询--->
${i}<br>
</#list>
    
<#list listval[1..2] as i>
${i}<br>
</#list>

String类型索引:

<#assign stringlist="abcdefghijklmn"/><br>

${stringlist[3]}<---单个查询--->
${stringlist[5]}
${stringlist[7]}<br>
    
${stringlist[2..5]}<br><---列表范围取值--->

Hash类型遍历:

<#assign mapval={"name":"mike","age":18}/><br>

<#list mapval?keys as key><---遍历查询--->
${key}==>${mapval[key]}<br>
</#list>
    
${mapval.age} <br><---单个查询--->

字符串拼接:

${str+str1}								<---stringstring1--->
string2${str}							<---stringstring--->

加减乘除:

${intval+intval}						<---24--->
${intval-intval}						<---0--->
${intval*intval}						<---144--->
${intval/intval}						<---1--->

控制流语句:

gt大于,lt小于,gte大于等于,lte小于等于

<#if mapval.age gte 18>成年</#if>

<#if user??></#if><---双问号为判断是否为空--->

<#if (mapval.age>=18)>成年
<#else>未成年
</#if>
    
<#if (mapval.age=20)>
<h3 style="color: greenyellow">正好20岁</h3>
<#elseif (mapval.age>=18)>
<h3 style="color:yellow">成年了</h3>
<#else>
<h3 style="color: red">未成年</h3>
</#if><br>
<#switch mapval.age>
<#case 10> <h1>10</h1>
<#break>
<#case 20> <h2>20</h2>
<#break>
<#case 18> <h3>18</h3>
<#break>
<#default>
</#switch><br>

创建一个5*5的表格

<table style="border:2px black solid">
    <#list 1..5 as i>
    <tr style="border:2px black solid">
        <#list 1..5 as j>
        <td style="border:2px black solid">sss</td>
        </#list>
    </tr>
    </#list><br>
</table>

方法

<#function addxy x y>
<#return x+y>
</#function>
    
调用方法运算${addxy(10,20)}<---30--->
<#function addxy x>
局部变量<#local sum=0>
<#list 1..x as i>
<#local sum = sum+i>
</#list>
<#return sum>
</#function>
    
${addxy(5)!}感叹号用来规避空值<---15--->
上一篇:java 根据freemarker模板导出word


下一篇:01-静态资源访问