Skip to content

Commit

Permalink
Dev (halo-dev#210)
Browse files Browse the repository at this point in the history
Dev

Co-authored-by: John Niang <[email protected]>
  • Loading branch information
ruibaby and JohnNiang authored Jun 19, 2019
2 parents 119e88c + 7908fed commit d4f3850
Show file tree
Hide file tree
Showing 28 changed files with 420 additions and 76 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ wget https://github.com/halo-dev/halo/releases/download/v1.0.2/halo-1.0.2.jar -O
nohup java -jar halo-latest.jar >/dev/null 2>&1&
```

详细文档请移步:<https://halo.run/docs>
详细文档请移步:<https://halo.run/guide>

## 博客示例

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,8 @@ private User createUser(InstallParam installParam) {
installParam.update(user);
// Set password manually
userService.setPassword(user, installParam.getPassword());
// Set default avatar
userService.setDefaultAvatar(user);
// Update user
return userService.update(user);
}).orElseGet(() -> userService.createBy(installParam));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package run.halo.app.controller.admin.api;

import io.swagger.annotations.ApiOperation;
import org.springframework.boot.actuate.trace.http.HttpTrace;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import run.halo.app.service.TraceService;

import java.util.List;

/**
* Trace controller.
*
* @author johnniang
* @date 19-6-18
*/
@RestController
@RequestMapping("/api/admin/traces")
public class TraceController {

private final TraceService traceService;

public TraceController(TraceService traceService) {
this.traceService = traceService;
}

@GetMapping
@ApiOperation("Lists http traces")
public List<HttpTrace> listHttpTraces() {
return traceService.listHttpTraces();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ public BaseResponse<Object> getBy(@PathVariable("key") String key) {
@ApiOperation("Options for comment")
public Map<String, Object> comment() {
List<String> keys = new ArrayList<>();
keys.add("comment_gavatar_default");
keys.add("comment_gravatar_default");
keys.add("comment_content_placeholder");
return optionService.listOptions(keys);
}
Expand Down
167 changes: 132 additions & 35 deletions src/main/java/run/halo/app/controller/core/CommonController.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,28 @@
package run.halo.app.controller.core;

import cn.hutool.core.text.StrBuilder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.web.servlet.error.ErrorController;
import org.springframework.boot.autoconfigure.web.ErrorProperties;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.autoconfigure.web.servlet.error.AbstractErrorController;
import org.springframework.boot.web.servlet.error.ErrorAttributes;
import org.springframework.http.HttpStatus;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.util.NestedServletException;
import run.halo.app.exception.HaloException;
import run.halo.app.exception.NotFoundException;
import run.halo.app.service.ThemeService;
import run.halo.app.utils.FilenameUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Collections;
import java.util.Map;

/**
* Error page Controller
Expand All @@ -18,18 +32,30 @@
*/
@Slf4j
@Controller
public class CommonController implements ErrorController {
@RequestMapping("${server.error.path:${error.path:/error}}")
public class CommonController extends AbstractErrorController {

private static final String ERROR_PATH = "/error";

private static final String NOT_FROUND_TEMPLATE = "404.ftl";
private static final String NOT_FOUND_TEMPLATE = "404.ftl";

private static final String INTERNAL_ERROR_TEMPLATE = "500.ftl";

private static final String ERROR_TEMPLATE = "error.ftl";

private static final String DEFAULT_ERROR_PATH = "common/error/error";

private final ThemeService themeService;

public CommonController(ThemeService themeService) {
private final ErrorProperties errorProperties;

private final ErrorAttributes errorAttributes;

public CommonController(ThemeService themeService,
ErrorAttributes errorAttributes,
ServerProperties serverProperties) {
super(errorAttributes);
this.themeService = themeService;
this.errorAttributes = errorAttributes;
this.errorProperties = serverProperties.getError();
}

/**
Expand All @@ -38,26 +64,26 @@ public CommonController(ThemeService themeService) {
* @param request request
* @return String
*/
@GetMapping(value = ERROR_PATH)
public String handleError(HttpServletRequest request) {
final Integer statusCode = (Integer) request.getAttribute("javax.servlet.error.status_code");
@GetMapping
public String handleError(HttpServletRequest request, HttpServletResponse response, Model model) {
HttpStatus status = getStatus(request);

log.error("Error path: [{}], status: [{}]", getErrorPath(), statusCode);
log.error("Error path: [{}], status: [{}]", getErrorPath(), status);

// Get the exception
Throwable throwable = (Throwable) request.getAttribute("javax.servlet.error.exception");
handleCustomException(request);

if (throwable != null) {
log.error("Captured an exception", throwable);
Map<String, Object> errorDetail = Collections.unmodifiableMap(getErrorAttributes(request, isIncludeStackTrace(request)));
model.addAttribute("error", errorDetail);

if (StringUtils.startsWithIgnoreCase(throwable.getMessage(), "Could not resolve view with name '")) {
// TODO May cause unknown-reason problem
// if Ftl was not found then redirect to /404
return contentNotFround();
}
}
log.debug("Error detail: [{}]", errorDetail);

return statusCode == 500 ? contentInternalError() : contentNotFround();
if (status.equals(HttpStatus.INTERNAL_SERVER_ERROR)) {
return contentInternalError();
} else if (status.equals(HttpStatus.NOT_FOUND)) {
return contentNotFound();
} else {
return defaultErrorHandler();
}
}

/**
Expand All @@ -66,14 +92,16 @@ public String handleError(HttpServletRequest request) {
* @return String
*/
@GetMapping(value = "/404")
public String contentNotFround() {
if (!themeService.templateExists(NOT_FROUND_TEMPLATE)) {
return "common/error/404";
public String contentNotFound() {
if (themeService.templateExists(ERROR_TEMPLATE)) {
return getActualTemplatePath(ERROR_TEMPLATE);
}
StrBuilder path = new StrBuilder("themes/");
path.append(themeService.getActivatedTheme().getFolderName());
path.append("/404");
return path.toString();

if (themeService.templateExists(NOT_FOUND_TEMPLATE)) {
return getActualTemplatePath(NOT_FOUND_TEMPLATE);
}

return defaultErrorHandler();
}

/**
Expand All @@ -83,22 +111,91 @@ public String contentNotFround() {
*/
@GetMapping(value = "/500")
public String contentInternalError() {
if (!themeService.templateExists(INTERNAL_ERROR_TEMPLATE)) {
return "common/error/500";
if (themeService.templateExists(ERROR_TEMPLATE)) {
return getActualTemplatePath(ERROR_TEMPLATE);
}

if (themeService.templateExists(INTERNAL_ERROR_TEMPLATE)) {
return getActualTemplatePath(INTERNAL_ERROR_TEMPLATE);
}
StrBuilder path = new StrBuilder("themes/");
path.append(themeService.getActivatedTheme().getFolderName());
path.append("/500");

return defaultErrorHandler();
}

private String defaultErrorHandler() {
return DEFAULT_ERROR_PATH;
}

private String getActualTemplatePath(@NonNull String template) {
Assert.hasText(template, "FTL template must not be blank");

StringBuilder path = new StringBuilder();
path.append("themes/")
.append(themeService.getActivatedTheme().getFolderName())
.append('/')
.append(FilenameUtils.getBasename(template));

return path.toString();
}

/**
* Handles custom exception, like HaloException.
*
* @param request http servlet request must not be null
*/
private void handleCustomException(@NonNull HttpServletRequest request) {
Assert.notNull(request, "Http servlet request must not be null");

Object throwableObject = request.getAttribute("javax.servlet.error.exception");
if (throwableObject == null) {
return;
}

Throwable throwable = (Throwable) throwableObject;
log.error("Captured an exception", throwable);

if (throwable instanceof NestedServletException) {
Throwable rootCause = ((NestedServletException) throwable).getRootCause();
if (rootCause instanceof HaloException) {
HaloException haloException = (HaloException) rootCause;
request.setAttribute("javax.servlet.error.status_code", haloException.getStatus().value());
request.setAttribute("javax.servlet.error.exception", rootCause);
request.setAttribute("javax.servlet.error.message", haloException.getMessage());
}
} else if (StringUtils.startsWithIgnoreCase(throwable.getMessage(), "Could not resolve view with name '")) {
request.setAttribute("javax.servlet.error.status_code", HttpStatus.NOT_FOUND.value());

NotFoundException viewNotFound = new NotFoundException("该路径没有对应的模板");
request.setAttribute("javax.servlet.error.exception", viewNotFound);
request.setAttribute("javax.servlet.error.message", viewNotFound.getMessage());
}

}

/**
* Returns the path of the error page.
*
* @return the error path
*/
@Override
public String getErrorPath() {
return ERROR_PATH;
return this.errorProperties.getPath();
}

/**
* Determine if the stacktrace attribute should be included.
*
* @param request the source request
* @return if the stacktrace attribute should be included
*/
protected boolean isIncludeStackTrace(HttpServletRequest request) {
ErrorProperties.IncludeStacktrace include = errorProperties.getIncludeStacktrace();
if (include == ErrorProperties.IncludeStacktrace.ALWAYS) {
return true;
}
if (include == ErrorProperties.IncludeStacktrace.ON_TRACE_PARAM) {
return getTraceParameter(request);
}
return false;
}
}
2 changes: 1 addition & 1 deletion src/main/java/run/halo/app/model/dto/BaseCommentDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ public class BaseCommentDTO implements OutputConverter<BaseCommentDTO, BaseComme

private String authorUrl;

private String gavatarMd5;
private String gravatarMd5;

private String content;

Expand Down
20 changes: 20 additions & 0 deletions src/main/java/run/halo/app/model/dto/HttpTraceDTO.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package run.halo.app.model.dto;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.util.Date;

/**
* Http trace dto.
*
* @author johnniang
* @date 19-6-18
*/
@Data
@ToString
@EqualsAndHashCode
public class HttpTraceDTO {

}
10 changes: 5 additions & 5 deletions src/main/java/run/halo/app/model/entity/BaseComment.java
Original file line number Diff line number Diff line change
Expand Up @@ -50,10 +50,10 @@ public class BaseComment extends BaseEntity {
private String authorUrl;

/**
* Gavatar md5
* Gravatar md5
*/
@Column(name = "gavatar_md5", columnDefinition = "varchar(128) default ''")
private String gavatarMd5;
@Column(name = "gravatar_md5", columnDefinition = "varchar(128) default ''")
private String gravatarMd5;

/**
* Comment content.
Expand Down Expand Up @@ -117,8 +117,8 @@ public void prePersist() {
authorUrl = "";
}

if (gavatarMd5 == null) {
gavatarMd5 = "";
if (gravatarMd5 == null) {
gravatarMd5 = "";
}

if (status == null) {
Expand Down
12 changes: 2 additions & 10 deletions src/main/java/run/halo/app/model/params/PostParam.java
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,9 @@ public class PostParam implements InputConverter<Post> {
@Override
public Post convertTo() {
if (StringUtils.isBlank(url)) {
url = HaloUtils.normalizeUrl(title);
} else {
url = HaloUtils.normalizeUrl(url);
url = title;
}

url = HaloUtils.initializeUrlIfBlank(url);

Post post = InputConverter.super.convertTo();
// Crypt password
if (StringUtils.isNotBlank(password)) {
Expand All @@ -81,13 +77,9 @@ public Post convertTo() {
@Override
public void update(Post post) {
if (StringUtils.isBlank(url)) {
url = HaloUtils.normalizeUrl(title);
} else {
url = HaloUtils.normalizeUrl(url);
url = title;
}

url = HaloUtils.initializeUrlIfBlank(url);

InputConverter.super.update(post);

// Crypt password
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
*/
public enum CommentProperties implements PropertyEnum {

GAVATAR_DEFAULT("comment_gavatar_default", String.class, "mm"),
GRAVATAR_DEFAULT("comment_gravatar_default", String.class, "mm"),

NEW_NEED_CHECK("comment_new_need_check", Boolean.class, "true"),

Expand Down
Loading

0 comments on commit d4f3850

Please sign in to comment.