搭建springboot+mybatis遇到的问题

11 篇文章 0 订阅
1 篇文章 0 订阅

使用markdown编写,可查看原文http://note.youdao.com/noteshare?id=1baeaa01dd018e4a3ad42b035f383d95&sub=CF4AF127D94742D7BD061634948113CB

目录

 

1 Autowired无法注入

2 启动时找不到mapper

3 编写单元测试用例时找不到启动类

4 静态页面加载顺序

5 在controller转发/重定向post请求

6 配置加载jsp页面,能访问controller,但是无法访问jsp页面

 7 MyBatis api

8 webjars使用

9 Bootstrap

10 引入bootstrap-table

 11 mybatis分页插件

 12 bootstrap-table相关示例

13 设置项目名,静态资源及controller请求配置

14 未设置项目名时,静态资源及controller请求配置



1 Autowired无法注入

  • service分为接口类和其实现类
  • controller层

注入的service类为接口类而不是实现类

例如

@RestController
@RequestMapping(value = "cert")
public class CertController {
    @Autowired
    private CertService certService;
}

 

  • service层

实现类使用注解`@service`

例如

/**
 * service接口类
 */
public interface CertService {
}
/**
 * service实现类
 */
@Service
public class CertServiceImpl implements CertService {
    @Autowired
    private CertificateMapper certificateMapper;
}
  • mapper层

使用注解`@Component(value = "")`

例如
 

@Component(value = "certificateMapper")
public interface CertificateMapper {
}


2 启动时找不到mapper

在启动类添加注解`@MapperScan("package")`

`package`为mapper接口类所在包,例如
 

@MapperScan("net.usechain.mapper")
@SpringBootApplication
public class CasvrSpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(CasvrSpringbootApplication.class, args);
    }
}

3 编写单元测试用例时找不到启动类

此处需要给启动类添加注解`@SpringBootTest`,其中注解参数`classes`的值为==测试启动类==,例如

@RunWith(SpringRunner.class)
//此处不是@SpringBootTest(classes = CasvrSpringbootApplication.class)
@SpringBootTest(classes = CasvrSpringbootApplicationTests.class)
public class UserControllerTests {

    private MockMvc mvc;

    @Before
    public void setUpMockMvc(){
        mvc = MockMvcBuilders.standaloneSetup(new UserController()).build();
    }

    @Test
    public void test() throws Exception {
        TestVO testVO = new TestVO();
        testVO.setId("123456");
        testVO.setName("lime");
        String body = JSONObject.toJSONString(testVO);
        System.out.println(body);
        mvc.perform(MockMvcRequestBuilders.post("/user/test").accept(MediaType.APPLICATION_JSON_UTF8).contentType(MediaType.APPLICATION_JSON_UTF8).content(body))
                .andExpect(MockMvcResultMatchers.status().isOk())   //返回的状态是200
                .andDo(MockMvcResultHandlers.print())   //打印出请求和相应的内容
                .andReturn();
    }
}


4 静态页面加载顺序


SpringBoot会自动加载`resources`下的静态页面,无需额外的配置,优先级由高到低为:
 

src/main/resources/META-INF/resources/index.html
src/main/resources/resources/index.html
src/main/resources/static/index.html
src/main/resources/public/index.html

5 在controller转发/重定向post请求

@RestController
@RequestMapping(value = "user")
public class UserController {
    private static Logger logger = LogManager.getLogger(UserController.class);
    /**
     * 重定向post请求
     */
    @ApiImplicitParam(required = true, dataType = "GenCertByCsrVO")
    @PostMapping(path = "auth2")
    public RedirectView genCertByCsr(@RequestBody GenCertByCsrVO reqVO) {
        System.out.println(reqVO.toString());
        System.out.println(reqVO.toJson());
        HashMap<String, Object> map = new HashMap<>();
        map.put(View.RESPONSE_STATUS_ATTRIBUTE, HttpStatus.TEMPORARY_REDIRECT);

        RedirectView view = new RedirectView();
        view.setUrl("/cert/genCertByCsr");
        view.setContextRelative(true);
        view.setHttp10Compatible(false);
        view.setExposeModelAttributes(true);
        view.setRequestContextAttribute(reqVO.toJson());
        //redirect post request
        view.setAttributesMap(map);
        view.setStatusCode(HttpStatus.TEMPORARY_REDIRECT);
        return view;
    }
    
    /**
     * 转发get请求
     */
    @ApiImplicitParam(required = true)
    @GetMapping(path = "cerauth")
    public ModelAndView getCertByCertId(@RequestParam(value = "idKey", required = true) String idKey) {
        logger.debug(idKey);
        return new ModelAndView("forward:/cert/getCertByCertId");
    }
}


接受post请求及get请求
 

@RestController
@RequestMapping(value = "cert")
public class CertController {
    private static Logger logger = LogManager.getLogger(CertController.class);
    
    @ApiImplicitParam(required = true, dataType = "GenCertByCsrVO")
    @PostMapping(path = "genCertByCsr")
    public String genCertByCsr(@RequestBody GenCertByCsrVO reqVO) {
        return "received post request";
    }

    @ApiImplicitParam(required = true)
    @GetMapping(path = "getCertByCertId")
    public String getCertByCertId(@RequestParam(value = "idKey") String idKey) {
        return "received get request";
    }
}

6 配置加载jsp页面,能访问controller,但是无法访问jsp页面

IDEA中运行SpringBoot+JSP项目,JSP页面无法访问问题

TomcatEmbeddedServletContainerFactory is now TomcatServletWebServerFactory

Stack Overflow

 7 MyBatis api

MyBatis

MyBatis Generator

MyBatis Generator中文

8 webjars使用

webjars

9 Bootstrap

bootstrap中文

bootstrap-table中文

10 引入bootstrap-table

  • 1 gradle的`build.gradle`文件中添加webjars依赖(需要引入jquery及bootstrap)
dependencies {
    compile 'org.webjars:jquery:3.1.1'
    compile 'org.webjars:bootstrap:3.3.7'
    compile 'org.webjars:bootstrap-table:1.9.1'
}

 

  • 2 在页面引入css、js,并实现一个从后端动态获取数据的table
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>title</title>
    <!-- css -->
    <link rel="stylesheet" href="webjars/bootstrap/3.3.7/css/bootstrap.min.css">
    <link rel="stylesheet" href="webjars/bootstrap-table/1.9.1/bootstrap-table.min.css">

    <!-- js -->
    <script src="webjars/jquery/3.1.1/jquery.min.js"></script>
    <script src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script>
    <script src="webjars/bootstrap-table/1.9.1/bootstrap-table.min.js"></script>
    <script src="webjars/bootstrap-table/1.9.1/locale/bootstrap-table-zh-CN.min.js"></script>
</head>
<body>
<div class="panel-body" style="padding-bottom:0px;">
    <div id="toolbar" class="btn-group">
        <button type="button" class="btn btn-default" data-toggle="modal" id="queryBtn">
            <i class="glyphicon glyphicon-eye-open"></i> 查看
        </button>
        <button type="button" class="btn btn-default" data-toggle="modal" id="apprBtn">
            <i class="glyphicon glyphicon-eye-open"></i> 审核
        </button>
    </div>
    <table id="table"
           data-toggle="table"
           data-toolbar="#toolbar"
           data-url="/user/testExampleAndPage"
           data-method="post"
           data-content-type="application/x-www-form-urlencoded"
           data-data-type="json"
           data-search="true"
           data-trim-on-search="true"
           data-show-refresh="true"
           data-show-toggle="true"
           data-show-columns="true"
           data-show-export="true"
           data-striped="true"
           data-click-to-select="true"
           data-side-pagination="server"
           data-pagination="true"
           data-page-list="[10, 20, 50, 100, 200]"
           data-id-field="id">
        <thead>
        <tr>
            <th data-field="id">id</th>
            <th data-field="code">code</th>
            <th data-field="name">name</th>
        </tr>
        </thead>
    </table>
</div>
</body>
<script type="text/javascript">
</body>
</html>

通过webjars引入的依赖会自动放入`resourses/webjars`下,`webjars`目录无需创建,gradle会自动指向该目录,如下图所示

 11 mybatis分页插件

  • 在gradle的`build.gradle`文件中添加分页插件依赖
dependencies {
    compile 'com.github.pagehelper:pagehelper:4.1.6'
}

若使用的是maven,则在`pom.xml`文件中添加分页插件依赖

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
</dependency>
  • 2 springboot集成分页插件PageHelper
@Configuration
public class PageHelperConfig {
    @Bean
    public PageHelper pageHelper(){
        PageHelper pageHelper = new PageHelper();
        Properties properties = new Properties();
        properties.setProperty("offsetAsPageNum","true");
        properties.setProperty("rowBoundsWithCount","true");
        properties.setProperty("reasonable","true");
        properties.setProperty("dialect","mysql");    //配置mysql数据库
        pageHelper.setProperties(properties);
        return pageHelper;
    }
}
  • 3 定义分页实体类
  • 此处需要注意的是前端表格使用的是`bootstrap-table`,其table属性中的`data-query-params-type="limit"`为默认值时,分页所用的属性值为`limit`和`offset`,其中`limit`表示每页的行数(数据数量),`offset`为总数据的偏移量,根据这两个数值可得到当前页为第`offset/limit+1`页(默认起始页为1);另外`total`为查询出的数据总数,`rows`中存放当前页的数据。
  • 若`data-query-params-type=""`,即`data-query-params-type`不为默认值`limit`时,分页所用的属性值则变为`pageSize`和`pageNumber`,`pageSize`与`limit`意义相同,表示每页的行数(数据数量),`pageNumber`则为第多少页(默认起始页为1)。
import java.util.List;

/**
 * @Auther: lime
 * @Date: 2018/9/20 19:49
 */
public class PageVO<T> {
    /**
     * the number of rows per page
     */
    private Integer limit;
    /**
     * offset / limit = the index of page
     */
    private Integer offset;
    /**
     * total number
     */
    private Integer total;
    /**
     * the data of current page
     */
    private List<T> rows;

    public PageVO(Integer limit, Integer offset, Integer total) {
        this.limit = limit;
        this.offset = offset;
        this.total = total;
    }
    public Integer getLimit() {
        return limit;
    }
    public void setLimit(Integer limit) {
        this.limit = limit;
    }
    public Integer getOffset() {
        return offset;
    }
    public void setOffset(Integer offset) {
        this.offset = offset;
    }
    public Integer getTotal() {
        return total;
    }
    public void setTotal(Integer total) {
        this.total = total;
    }
    public List<T> getRows() {
        return rows;
    }
    public void setRows(List<T> rows) {
        this.rows = rows;
    }
}
  •  4 controller
@RestController
@RequestMapping(value = "user")
public class UserController {
    private static Logger logger = LogManager.getLogger(UserController.class);

    @Autowired
    private CertificateTypeService certificateTypeService;

    @ApiImplicitParam(required = false)
    @PostMapping(path = "testExampleAndPage")
    public String testExampleAndPage(@RequestParam(value = "name", required = false) String name,
                                                        @RequestParam(value = "limit",required = false) int limit,
                                                        @RequestParam(value = "offset",required = false) int offset){
        CertificateTypeExample example = new CertificateTypeExample();
        if (StringUtils.isBlank(name)) {
            logger.debug("param name is null");
            name = "";
        }
        example.createCriteria().andNameLike(name + "%");
        PageVO<CertificateType> page = certificateTypeService.selectByExampleAndPage(example, limit, offset);
        return JSONObject.toJSONString(page);
    }
}
  • 5 service接口
public interface CertificateTypeService {
    public PageVO<CertificateType> selectByExampleAndPage(CertificateTypeExample example, int limit, int offset);
}
  • 6 service实现类
@Service
public class CertificateTypeServiceImpl implements CertificateTypeService {

    @Autowired
    private CertificateTypeMapper certificateTypeMapper;

    @Override
    public PageVO<CertificateType> selectByExampleAndPage(CertificateTypeExample example, int limit, int offset) {
        //设置分页信息
        PageHelper.startPage(offset/limit+1, limit);

        List<CertificateType> lists = certificateTypeMapper.selectByExample(example);
        int num = (int) certificateTypeMapper.countByExample(example);

        PageVO<CertificateType> pageVO = new PageVO<>(limit, offset, num);
        pageVO.setRows(lists);
        return pageVO;
    }
}
  • 7 mapper接口,使用mybatis generator自动生成
@Component(value = "certificateTypeMapper")
public interface CertificateTypeMapper {
    long countByExample(CertificateTypeExample example);

    int deleteByPrimaryKey(Integer id);

    int insert(CertificateType record);

    int insertSelective(CertificateType record);

    List<CertificateType> selectByExample(CertificateTypeExample example);

    CertificateType selectByPrimaryKey(Integer id);

    int updateByExampleSelective(@Param("record") CertificateType record, @Param("example") CertificateTypeExample example);

    int updateByExample(@Param("record") CertificateType record, @Param("example") CertificateTypeExample example);

    int updateByPrimaryKeySelective(CertificateType record);

    int updateByPrimaryKey(CertificateType record);
}
  • 8 实体类及example类,使用mybatis generator自动生成

example类可实现动态sql查询,灵活,而不需要在xml文件中手写mapper,也免去了每次生成新mapper时会覆盖掉之前写的sql

public class CertificateType implements Serializable {
    private Integer id;
    private String code;
    private String name;
    private Boolean isnecessary;
    private static final long serialVersionUID = 1L;

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code == null ? null : code.trim();
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name == null ? null : name.trim();
    }
    public Boolean getIsnecessary() {
        return isnecessary;
    }
    public void setIsnecessary(Boolean isnecessary) {
        this.isnecessary = isnecessary;
    }
}
public class CertificateTypeExample {
    protected String orderByClause;
    protected boolean distinct;
    protected List<Criteria> oredCriteria;
    
    //此处省略...
}
  • 9 xml文件 
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="net.usechain.mapper.CertificateTypeMapper">
  <resultMap id="BaseResultMap" type="net.usechain.model.CertificateType">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="code" jdbcType="VARCHAR" property="code" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    <result column="isnecessary" jdbcType="BIT" property="isnecessary" />
  </resultMap>
  <sql id="Example_Where_Clause">
    <where>
      <foreach collection="oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Update_By_Example_Where_Clause">
    <where>
      <foreach collection="example.oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List">
    id, code, name, isnecessary
  </sql>
  <select id="selectByExample" parameterType="net.usechain.model.CertificateTypeExample" resultMap="BaseResultMap">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="Base_Column_List" />
    from certificate_type
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by ${orderByClause}
    </if>
  </select>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from certificate_type
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from certificate_type
    where id = #{id,jdbcType=INTEGER}
  </delete>
  <insert id="insert" parameterType="net.usechain.model.CertificateType">
    insert into certificate_type (id, code, name, 
      isnecessary)
    values (#{id,jdbcType=INTEGER}, #{code,jdbcType=VARCHAR}, #{name,jdbcType=VARCHAR}, 
      #{isnecessary,jdbcType=BIT})
  </insert>
  <insert id="insertSelective" parameterType="net.usechain.model.CertificateType">
    insert into certificate_type
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="code != null">
        code,
      </if>
      <if test="name != null">
        name,
      </if>
      <if test="isnecessary != null">
        isnecessary,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="code != null">
        #{code,jdbcType=VARCHAR},
      </if>
      <if test="name != null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="isnecessary != null">
        #{isnecessary,jdbcType=BIT},
      </if>
    </trim>
  </insert>
  <select id="countByExample" parameterType="net.usechain.model.CertificateTypeExample" resultType="java.lang.Long">
    select count(*) from certificate_type
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
  </select>
  <update id="updateByExampleSelective" parameterType="map">
    update certificate_type
    <set>
      <if test="record.id != null">
        id = #{record.id,jdbcType=INTEGER},
      </if>
      <if test="record.code != null">
        code = #{record.code,jdbcType=VARCHAR},
      </if>
      <if test="record.name != null">
        name = #{record.name,jdbcType=VARCHAR},
      </if>
      <if test="record.isnecessary != null">
        isnecessary = #{record.isnecessary,jdbcType=BIT},
      </if>
    </set>
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByExample" parameterType="map">
    update certificate_type
    set id = #{record.id,jdbcType=INTEGER},
      code = #{record.code,jdbcType=VARCHAR},
      name = #{record.name,jdbcType=VARCHAR},
      isnecessary = #{record.isnecessary,jdbcType=BIT}
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <update id="updateByPrimaryKeySelective" parameterType="net.usechain.model.CertificateType">
    update certificate_type
    <set>
      <if test="code != null">
        code = #{code,jdbcType=VARCHAR},
      </if>
      <if test="name != null">
        name = #{name,jdbcType=VARCHAR},
      </if>
      <if test="isnecessary != null">
        isnecessary = #{isnecessary,jdbcType=BIT},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
  <update id="updateByPrimaryKey" parameterType="net.usechain.model.CertificateType">
    update certificate_type
    set code = #{code,jdbcType=VARCHAR},
      name = #{name,jdbcType=VARCHAR},
      isnecessary = #{isnecessary,jdbcType=BIT}
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>

 12 bootstrap-table相关示例

  • 1 实现自定义请求参数(此处为json格式)

html中table设置

<table id="table"
       data-toggle="table"
       data-toolbar="#toolbar"
       data-url="manage/search"
       data-method="post"
       data-content-type="application/json;charset=utf-8"
       data-data-type="json"
       data-query-params=queryParams
       data-search="true"
       data-trim-on-search="true"
       data-show-refresh="true"
       data-show-toggle="true"
       data-show-columns="true"
       data-show-export="true"
       data-striped="true"
       data-click-to-select="true"
       data-page-size="10"
       data-side-pagination="server"
       data-pagination="true"
       data-page-list="[10, 20, 50, 100]"
       data-id-field="id">
    <thead>
    <tr>
        <th data-field="id">id</th>
        <th data-field="code">code</th>
        <th data-field="name">name</th>
    </tr>
    </thead>
</table>

js代码

<script type="text/javascript">
    function queryParams(params) {
        var code = $("#qry_code").val();
        var name = $("#qry_name").val();
        var json = {
            "limit": params.limit,
            "offset": params.offset,
            "order": params.order,
            "code": code,
            "name": name
        };
        return JSON.stringify(json);
    }
</script>

 后端controller代码

@RestController
@RequestMapping(value = "manage")
public class ManageController {
    private static Logger logger = LogManager.getLogger(ManageController.class);

    @Autowired
    private ParamConstants paramConstants;

    @Autowired
    private CertTypeService certTypeService;

    @ApiImplicitParam(required = false)
    @PostMapping(path = "search")
    public String search(@RequestBody CertTypeVO certTypeVO){
        logger.debug(JSON.toJSON(certTypeVO));
        CertificateTypeExample example = new CertificateTypeExample();
        //若前端不上送limit参数或不合法,则设置为默认值
        int limit = certTypeVO.getLimit()<=0?paramConstants.PAGE_LIMIT:certTypeVO.getLimit();
        //若前端上送的offset参数不合法,则设置为默认值
        int offset = certTypeVO.getOffset()<0?paramConstants.PAGE_OFFSET:certTypeVO.getOffset();

        CertificateTypeExample.Criteria criteria = example.createCriteria();
        if (StringUtils.isNotBlank(certTypeVO.getCode())) {
            criteria.andCodeLike("%"+ certTypeVO.getCode() +"%");
        }
        if (StringUtils.isNotBlank(certTypeVO.getName())) {
            criteria.andNameLike("%"+ certTypeVO.getName() +"%");
        }
        example.setOrderByClause("id "+ certTypeVO.getOrder());
        PageVO<CertificateType> page = certTypeService.selectByExampleAndPage(example, limit, offset);
        System.out.println(JSONObject.toJSONString(page));

        return JSONObject.toJSONString(page);
    }
}
  • 2 获取table的相关分页属性,并请求后端controller

获取table的属性使用的是`getOptions`方法,刷新使用的是`refresh`方法,其他方法可以查看官方api文档

<script type="text/javascript">
    function search() {
        var code = $("#qry_code").val();
        var name = $("#qry_name").val();
        var tableOptions = $("#table").bootstrapTable("getOptions");
        var limit = tableOptions.pageSize === tableOptions.formatAllRows() ? tableOptions.totalRows : tableOptions.pageSize;
        var offset = tableOptions.pageSize === tableOptions.formatAllRows() ? 0 : tableOptions.pageSize * (tableOptions.pageNumber - 1);
        var params = {
            "code": code,
            "name": name,
            "limit": limit,
            "offset": offset
        };
        var jsonParams = JSON.stringify(params);
        $("#table").bootstrapTable("refresh",{
            url : "manage/search",
            query: {
                params : jsonParams
            }
        })
    }
</script>

13 设置项目名,静态资源及controller请求配置

  • 在`application.properties`里添加配置
server.port=8548
server.servlet.context-path=/myweb
  • css样式、js等静态资源引用配置,使用相对路径
<link rel="stylesheet" href="css/style.css">

此处引用的`style.css`位于`src/main/resources/static/css/style.css`

通过`http://localhost:8548/myweb/css/style.css`访问即可。

  • 引用页面
<a href="#" onclick="menuClick('page/search.html')"> Search</a>
<script type="text/javascript">
    var menuClick = function(menuUrl) {
        $("#myMenu").load(menuUrl);
    };
</script>
<div class="col-md-10" style="overflow-y:auto">
    <div class="my-menu" id="myMenu"></div>
</div>

此处页面`search.html`位于`src/main/resources/static/page/search.html`

  • 请求后端controller
<script type="text/javascript">
    $('#searchBtn').on('click', function (e) {
        var params = {
            "id": "123456"
        };
        var jsonParams = JSON.stringify(params);
        $.ajax({
            type: "POST",
            url: "manage/search",
            headers: {
                "Content-Type": "application/json;charset=utf-8"
            },
            contentType: 'application/json;charset=utf-8',
            data: jsonParams,
            dataType: "json",
            async: false,
            error: function (request) {
                Messenger().post("search failed.");
            },
            success: function (data) {
                Messenger().post("search success.");
            }
        });
    });
</script>

14 未设置项目名时,静态资源及controller请求配置

与上面说明的问题形成对比,这里介绍未设置`server.servlet.context-path`时,静态资源及controller请求的配置。

  • `application.properties`中的配置
server.port=8548
#不配置项目名
#server.servlet.context-path=/myweb
  • css样式、js等静态资源引用配置,可使用绝对路径
<link rel="stylesheet" href="/css/style.css">

此处引用的`style.css`位于`src/main/resources/static/css/style.css`

通过`http://localhost:8548/css/style.css`访问即可。

  • 引用页面
<a href="#" onclick="menuClick('/page/search.html')"> Search</a> 
<script type="text/javascript">
    var menuClick = function(menuUrl) {
        $("#myMenu").load(menuUrl);
    };
</script>
<div class="col-md-10" style="overflow-y:auto">
    <div class="my-menu" id="myMenu"></div>
</div>
  • 请求后端controller
<script type="text/javascript">
    $('#searchBtn').on('click', function (e) {
        var params = {
            "id": "123456"
        };
        var jsonParams = JSON.stringify(params);
        $.ajax({
            type: "POST",
            url: "/manage/search",
            headers: {
                "Content-Type": "application/json;charset=utf-8"
            },
            contentType: 'application/json;charset=utf-8',
            data: jsonParams,
            dataType: "json",
            async: false,
            error: function (request) {
                Messenger().post("search failed.");
            },
            success: function (data) {
                Messenger().post("search success.");
            }
        });
    });
</script>

使用绝对路径的问题是,在本地开发的时候是没有任何影响的,但是当部署到服务器上时,访问需要加上项目名(例如此处的`myweb`),这时,配置为绝对路径访问的就会报`404`错误。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值