化石原创文章,转载请注明来源并保留原文链接


做一个随浏览器大小始终居中的进度条,使用了下面的代码:

<div id="loadingContainer" style="position: absolute; width: 100%; height: 90%;" >
	<div class="row h-100 align-items-center justify-content-center">
		<div class="row">
			<div class="col">
				<p id="loadingProgress" style="color: red; font-size: 2rem;">0%</p>
			</div>
		</div>
	</div>
</div>

第3行开始的是进度条本身,第1行和第2行是关键。第1行的height百分比,可以用来调节在高度上的居中感觉。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


在mouted方法中,如果用了DOM的回调方法,而这个方法需要用到methods里定义的方法,那么this不能直接被使用。我们需要在mouted中,先把this赋值给一个变量,而后在这个回调中就能使用到方法。

比如下面的例子:

  methods : {
    
    changeFontSize () {
        var initBannerTitleFontSize = 80, initBannerTitleMarginTop = 70, initBannerTitleMarginBottom = 20;
        var initBannerDescFontSize = 30, initBannerDescLineHeight = 45;

        var height = document.getElementById('bannerbg').clientHeight;
        var percent = height / 300;

        var bannerTitle = document.getElementById('bannertitle');
        var bannerDesc = document.getElementById('bannerdesc');

        bannerTitle.style.fontSize = percent * initBannerTitleFontSize + "px";
        bannerTitle.style.marginTop = percent * initBannerTitleMarginTop + "px";
        bannerTitle.style.marginBottom = percent * initBannerTitleMarginBottom + "px";
        
        bannerDesc.style.fontSize = percent * initBannerDescFontSize + "px";
        bannerDesc.style.lineHeight  = percent * initBannerDescLineHeight + "px";
    },
  },
  mounted() {
    var that = this;
    
    if(document.body.clientWidth<800){
      this.isPC = false;
    }

    document.getElementById('bannerbg').addEventListener('load', function() {
      that.changeFontSize();
    });

    window.onresize = () => {
        return (() => {
          this.changeFontSize();
        })();
    };
  }

这里的that本地变量,就执行this对象,在回调中使用完全没有问题。在javascript中,这个是很常见的手法。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


1、使用Maven,pom文件中加入:

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

2、在需要的field上,比如某个类的一个变量不能为null或者empty

import javax.validation.constraints.NotBlank;

public class Article {
    @NotBlank(message = "title cannot be blank")
    private String title;
}

3、使用到Article实例的地方,用上@valid

import javax.validation.Valid;

public ResponseEntity<?> saveArticle(@Valid @RequestBody Article article) {
}

到此,如果不能通过验证(例子中title如果是null或者trim()后长度为零),那么底层就直接拦住了,saveArticle()不会得到调用。

但是用户收到的信息缺失一个404的错误。这里可以定制处理。

4、写一个继承ResponseEntityExceptionHandler的类

package API;

import java.util.ArrayList;
import java.util.List;

import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler;

@SuppressWarnings({"unchecked","rawtypes"})
@ControllerAdvice
public class CustomExceptionHandler extends ResponseEntityExceptionHandler
{
    @ExceptionHandler(Exception.class)
    public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) {
        List<String> details = new ArrayList<>();
        details.add(ex.getLocalizedMessage());
        ErrorResponse error = new ErrorResponse("Server Error", details);
        return new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    @Override
    protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {
        List<String> details = new ArrayList<>();
        for(ObjectError error : ex.getBindingResult().getAllErrors()) {
            details.add(error.getDefaultMessage());
        }
        ErrorResponse error = new ErrorResponse("Validation Failed", details);
        return new ResponseEntity<>(error, HttpStatus.BAD_REQUEST);
    }
}

其中的方法handleMethodArgumentNotValid,就是用来处理参数验证错误。

ErrorResponse是一个自定义的类:

package API;

import java.util.List;

public class ErrorResponse {
    private String message;
    private List<String> details;

    public ErrorResponse(String message, List<String> details) {
        super();
        this.message = message;
        this.details = details;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public List<String> getDetails() {
        return details;
    }

    public void setDetails(List<String> details) {
        this.details = details;
    }
}

注意getter一定要写,否则ajax的error回调,responseText是空的json。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


使用Ajax,我们可以指定Post的格式,比如json、uft-8

    var post = {"title": title, "content": content, "catalog": catalog};
    
    $.ajax({
        type: 'post',
        async: true,
        data: JSON.stringify(post),
        url: document.location.origin + '/api/savearticle',
        dataType:'json',
        contentType: 'application/json; charset=utf-8',
        success: function(data) {
            console.log("保存成功");
        },
        error: function () {
            console.log("Ajax 发生错误!");
        }
    });

上面例子上的post数据,可以在SpringBoot服务器端用这样的方式接收:

@RestController
public class ArticleApi {
    @RequestMapping(value = "/api/savearticle", method = RequestMethod.POST,  consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<?> saveArticle(@RequestBody Article article) {

    }
}

其中,Article是这样:

public class Article {
    private String title;
    private String content;
    private String catalog;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String getCatalog() {
        return catalog;
    }

    public void setCatalog(String catalog) {
        this.catalog = catalog;
    }
}

这样的方式,能让SpringBoot直接在底层就帮我们绑定好数据。如果加上@Valid,什么数据验证、取数据栏位等工作就方便多了,可以少些很多代码,提升开发效率。


化石原创文章,转载请注明来源并保留原文链接



化石原创文章,转载请注明来源并保留原文链接


一个网站,后台没有使用vue写界面,前端界面使用了Vue.js。

架设到IIS上后,发现大多正常,前台、后台都能访问。唯一的问题就是属于vue写的那块页面,只要F5刷新就出现404错误。


查了一下是IIS的安全机制引起,可以使用IIS的URL Rewrite工具解决。

URL Rewrite可以通过IIS管理器,找到Web 平台安装程序这个入口,然后“产品”页面,选中“服务器”,可以找到“URL重写工具 2.0”。如果没有安装,点后面的“安装”即可。

然后到IIS管理器,对应的网站选中后,找到“URL重写”按钮,加入规则。

这里假设我们遇到的F5刷新出问题的url都是hostname/CourseBase/xxx这样的,那么就加入如下规则(选空白规则创建):

1、名称:随便填

2、匹配url:默认状态下,模式填入:^CourseBase/*

3、条件:点击添加,加入“不是文件”

4、操作:重写。重写url中填根目录文件,比如/index.html。

如此操作好,IIS就会在我们的网站web.config.中写入下面内容:

<rewrite>
  <rules>
	  <rule name="F5">
		  <match url="^CourseBase/*" />
			<conditions>
				<add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
			</conditions>
			<action type="Rewrite" url="/Index.html" />
		</rule>
	</rules>
</rewrite>

应用后就能生效。


化石原创文章,转载请注明来源并保留原文链接