All Projects → TAKETODAY → today-web

TAKETODAY / today-web

Licence: GPL-3.0 license
😐 A Java library for building web applications

Programming Languages

java
68154 projects - #9 most used programming language
HTML
75241 projects

Projects that are alternatives of or similar to today-web

Katwebx
An extremely fast static web server and reverse proxy for the modern web.
Stars: ✭ 39 (+18.18%)
Mutual labels:  lightweight, high-performance
Cicada
🚀 Fast lightweight HTTP service framework.
Stars: ✭ 851 (+2478.79%)
Mutual labels:  lightweight, high-performance
Tarena Java Textbooks
达内 Java 全套教材
Stars: ✭ 75 (+127.27%)
Mutual labels:  servlet, springmvc
Flexml
🚀基于Litho的Android高性能动态业务容器。
Stars: ✭ 225 (+581.82%)
Mutual labels:  lightweight, high-performance
Smtpd
A Lightweight High Performance ESMTP email server
Stars: ✭ 175 (+430.3%)
Mutual labels:  lightweight, high-performance
Esa Restlight
ESA Restlight is a lightweight and rest-oriented web framework.
Stars: ✭ 67 (+103.03%)
Mutual labels:  lightweight, springmvc
webgui
Web Technologies based Crossplatform GUI Framework with Dark theme
Stars: ✭ 81 (+145.45%)
Mutual labels:  lightweight, high-performance
Easylogger
An ultra-lightweight(ROM<1.6K, RAM<0.3k), high-performance C/C++ log library. | 一款超轻量级(ROM<1.6K, RAM<0.3k)、高性能的 C/C++ 日志库
Stars: ✭ 1,968 (+5863.64%)
Mutual labels:  lightweight, high-performance
Cms
GleezCMS - A Light, Simple, Flexible Content Management System
Stars: ✭ 200 (+506.06%)
Mutual labels:  lightweight, high-performance
Libaco
A blazing fast and lightweight C asymmetric coroutine library 💎 ⛅🚀⛅🌞
Stars: ✭ 2,918 (+8742.42%)
Mutual labels:  lightweight, high-performance
cachegrand
cachegrand is an open-source fast, scalable and secure Key-Value store, also fully compatible with Redis protocol, designed from the ground up to take advantage of modern hardware vertical scalability, able to provide better performance and a larger cache at lower cost, without losing focus on distributed systems.
Stars: ✭ 87 (+163.64%)
Mutual labels:  high-performance
MatrixLib
Lightweight header-only matrix library (C++) for numerical optimization and machine learning. Contact me if there is an exciting opportunity.
Stars: ✭ 35 (+6.06%)
Mutual labels:  lightweight
workerman
An asynchronous event driven PHP socket framework. Supports HTTP, Websocket, SSL and other custom protocols. PHP>=5.4.
Stars: ✭ 10,005 (+30218.18%)
Mutual labels:  high-performance
quickstep
Quickstep project
Stars: ✭ 22 (-33.33%)
Mutual labels:  high-performance
rust-xoodyak
Xoodyak, a lightweight and versatile cryptographic scheme implemented in Rust.
Stars: ✭ 28 (-15.15%)
Mutual labels:  lightweight
Translucide
CMS efficient, léger, simple à prendre en main, customisable et écoconçu !
Stars: ✭ 31 (-6.06%)
Mutual labels:  lightweight
jeelizGlanceTracker
JavaScript/WebGL lib: detect if the user is looking at the screen or not from the webcam video feed. Lightweight and robust to all lighting conditions. Great for play/pause videos if the user is looking or not, or for person detection. Link to live demo.
Stars: ✭ 68 (+106.06%)
Mutual labels:  lightweight
sgo
A simple, light and fast Web framework written in Go.
Stars: ✭ 75 (+127.27%)
Mutual labels:  lightweight
query2report
Query2Report is a simple open source business intelligence platform that allows users to build report/dashboard for business analytics or enterprise reporting
Stars: ✭ 43 (+30.3%)
Mutual labels:  lightweight
cpython
Alternative StdLib for Nim for Python targets, hijacks Python StdLib for Nim
Stars: ✭ 75 (+127.27%)
Mutual labels:  high-performance

moved to https://github.com/TAKETODAY/today-framework/tree/master/src/main/java/cn/taketoday/web

TODAY Web

🍎 A Java library for building web applications

Java8 GPLv3 Author Codacy Badge Java CI

背景

先不看

本人从2016年大一开始学Java,准确的说是高三最后的几周开始的. 果然兴趣是最好的老师, 在大一下学期自己独自一人从前端到后台写了我的个人网站:TODAY BLOG 。 从注册域名到备案再到网站成功上线,我遇到过的困难数不计其数。因为感兴趣所以我坚持了下来。第一个版本使用的纯Servlet写的。 后来了解到Java有很多开源框架可以简化我的开发。于是又投入到新一轮的学习之中...... 学了Struts2后自己学着写了一个小框架:TODAY Web 1.0 ,几百行搞定从解析xml定义的action到处理对应的请求。学了Spring MVC后,我写了此项目:TODAY Web 2.0

安装

<dependency>
    <groupId>cn.taketoday</groupId>
    <artifactId>today-web</artifactId>
    <version>3.0.2.RELEASE</version>
</dependency>

案例

文档

使用说明

函数式路由

@Component
@ResponseBody
public class FunctionController {

    public String function(RequestContext request) {
        return "body:" + request.method() + " requestURI -> " + request.requestURI();
    }

    public String test(RequestContext request) {
        return "body:" + request.method() + " test -> " + request.requestURI();
    }

    public void script(RequestContext request) throws IOException {

        ModelAndView modelAndView = new ModelAndView();
        request.modelAndView(modelAndView);

        modelAndView.setContentType("text/html;charset=UTF-8");
        modelAndView.setView(new StringBuilder("<script>alert('HELLO, 你好 script');</script>"));
    }
}

@Configuration
//@EnableDefaultMybatis
//@EnableRedissonCaching
public class WebMvcConfig implements WebMvcConfiguration {

    @Autowired
    private FunctionController functionController;

    @Override
    public void configureFunctionHandler(FunctionHandlerRegistry registry) {

        registry.get("/function", functionController::function);
        registry.get("/function/test", functionController::test);
        registry.get("/function/script", functionController::script);

        registry.get("/function/error/500", (context) -> {
            context.sendError(500);
        });
    }
}

注解路由

//@Controller
@RestController
@RequestMapping("/users")
public class UserController {
    

    @GET("index")
    @POST("post")
    @PUT("articles/{id}")
    ......
    @RequestMapping("/users/{id}")
    @RequestMapping(value = "/**", method = {RequestMethod.GET})
    @RequestMapping(value = "/*.html", method = {RequestMethod.GET})
    @RequestMapping(value = {"/index.action", "/index.do", "/index"}, method = RequestMethod.GET)
    @Interceptor({LoginInterceptor.class, ...})
    public (String|List<?>|Set<?>|Map<?>|void|File|Image|...) \\w+ (request, request, session,servletContext, str, int, long , byte, short, boolean, @Session("loginUser"), @Header("User-Agent"), @Cookie("JSESSIONID"), @PathVariable("id"), @RequestBody("users"), @Multipart("uploadFiles") MultipartFile[]) {
        service...
        return </>;
    }
}

ViewController

@Configuration
public class WebMvcConfig implements WebMvcConfiguration {

    @Override
    public void configureViewController(ViewControllerHandlerRegistry registry) {
        registry.addViewController("/github", "redirect:https://github.com");
        registry.addRedirectViewController("/login.do", "/login");
        registry.addViewController("/login.action")
                .setAssetsPath("redirect:/login");
    }
}

静态资源

@Singleton
@Profile("dev")
public ResourceHandlerRegistry devRsourceMappingRegistry(@Env("site.uploadPath") String upload,
                                                         @Env("site.assetsPath") String assetsPath) //
{
    final ResourceHandlerRegistry registry = new ResourceHandlerRegistry();

    registry.addResourceMapping("/assets/**")//
            .addLocations(assetsPath);

    registry.addResourceMapping("/upload/**")//
            .addLocations(upload);

    registry.addResourceMapping("/logo.png")//
            .addLocations("file:///D:/dev/www.yhj.com/webapps/assets/images/logo.png");

    registry.addResourceMapping("/favicon.ico")//
            .addLocations("classpath:/favicon.ico");

    return registry;
}

@Singleton
@Profile("prod")
public ResourceHandlerRegistry prodResourceMappingRegistry() {

    final ResourceHandlerRegistry registry = new ResourceHandlerRegistry();

    registry.addResourceMapping(LoginInterceptor.class)//
            .setPathPatterns("/assets/admin/**")//
            .setOrder(Ordered.HIGHEST_PRECEDENCE)//
            .addLocations("/assets/admin/");

    return registry;
}

@Override
public void configureResourceHandler(ResourceHandlerRegistry registry) {

    registry.addResourceMapping(LoginInterceptor.class)//
            .setPathPatterns("/assets/admin/**")//
            .setOrder(Ordered.HIGHEST_PRECEDENCE)//
            .addLocations("/assets/admin/");
}

自定义参数转换器

@Singleton
public class UserSessionParameterResolver implements OrderedParameterResolver {
  private final WebSessionManager sessionManager;

  public UserSessionParameterResolver(WebSessionManager sessionManager) {
    this.sessionManager = sessionManager;
  }

  @Override
  public boolean supports(MethodParameter parameter) {
    return parameter.isAnnotationPresent(UserSession.class);
  }

  @Override
  public Object resolveParameter(final RequestContext context, final MethodParameter parameter) throws Throwable {
    final WebSession session = sessionManager.getSession(context, false);
    if (session != null) {
      final Object attribute = session.getAttribute(Constant.USER_INFO);
      if (attribute != null) {
        return attribute;
      }
    }
    throw new UnauthorizedException();
  }

  @Override
  public int getOrder() {
    return HIGHEST_PRECEDENCE;
  }

}

@Singleton
@Order(Ordered.HIGHEST_PRECEDENCE)
public class PageableMethodArgumentResolver implements ParameterResolver {

  private static final String PARAMETER_SIZE = "size";
  private static final String PARAMETER_CURRENT = "page";

  private int maxListSize;
  private int defaultListSize;

  @Override
  public boolean supports(MethodParameter parameter) {
    return parameter.isAssignableTo(Pageable.class);
  }

  @Override
  public Object resolveParameter(RequestContext request, MethodParameter parameter) throws Throwable {
    return new RequestContextPageable(request, defaultListSize, maxListSize);
  }

  public int getMaxListSize() {
    return maxListSize;
  }

  public void setMaxListSize(int maxListSize) {
    this.maxListSize = maxListSize;
  }

  public int getDefaultListSize() {
    return defaultListSize;
  }

  public void setDefaultListSize(int listSize) {
    this.defaultListSize = listSize;
  }

  public final static class RequestContextPageable implements Pageable {

    private final int maxListSize;
    private final int defaultListSize;

    private Integer size;
    private Integer current;
    private final RequestContext request;

    public RequestContextPageable(RequestContext request, int listSize, int maxListSize) {
      this.request = request;
      this.defaultListSize = listSize;
      this.maxListSize = maxListSize;
    }

    @Override
    public int getCurrent() {

      if (current == null) {
        final String parameter = request.getParameter(PARAMETER_CURRENT);
        if (StringUtils.isEmpty(parameter)) {
          current = 1;
        }
        else if ((current = Integer.valueOf(parameter)) <= 0) {
          throw new IllegalArgumentException("only 'page > 0'");
        }
      }
      return current.intValue();
    }

    @Override
    public int getSize() {
      if (size == null) {
        int s;
        final String parameter = request.getParameter(PARAMETER_SIZE);
        if (StringUtils.isEmpty(parameter)) {
          s = defaultListSize;
        }
        else {
          s = Integer.parseInt(parameter);
          if (s <= 0) {
            throw new IllegalArgumentException("only 'size > 0'");
          }
          if (s > maxListSize) {
            throw DemoUtils.accessForbidden();
          }
        }
        return size = s;
      }
      return size.intValue();
    }

  }

}

@Component
public class DateConverter implements Converter<String, Date> {
    @Override
    public Date convert(String source) throws ConversionException {
        ...
    }
}


也可以通过xml文件配置简单视图

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE Web-Configuration PUBLIC 
		"-//TODAY BLOG//Web - Configuration DTD 2.0//CN"
			"https://taketoday.cn/framework/web/dtd/web-configuration-2.3.7.dtd">

<Web-Configuration>

    <controller prefix="/error/">
        <action resource="400" name="BadRequest" status="400" />
        <action resource="403" name="Forbidden" status="403" />
        <action resource="404" name="NotFound" status="404" />
        <action resource="500" name="ServerIsBusy" status="500" />
        <action resource="405" name="MethodNotAllowed" status="405" />
    </controller>

    <controller>
        <action resource="redirect:http://pipe.b3log.org/blogs/Today" name="today-blog-pipe" />
        <action resource="redirect:https://taketoday.cn" name="today" />
        <action resource="redirect:https://github.com" name="github" />
        <action resource="redirect:/login" name="login.do" />
    </controller>

    <controller class="cn.taketoday.web.demo.controller.XMLController" name="xmlController" prefix="/xml/">
        <action name="obj" method="obj" />
        <action name="test" resource="test" method="test"/>
    </controller>

</Web-Configuration>

登录实例

@Controller
public class UserController {

/* 
    <controller prefix="/WEB-INF/view/" suffix=".ftl">
        <action resource="login" name="login" />
        <action resource="register" name="register" />
    </controller> */
    
    // @GET("login")
    @RequestMapping(value = "/login" , method = RequestMethod.GET)
    public String login() {
        return "/login/login";//支持jsp,FreeMarker,Thymeleaf,自定义视图
    }
    
    @Logger("登录")
    //@POST("/login")
    //@RequestMapping(value = "/login" , method = RequestMethod.POST)
    @ActionMapping(value = "/login", method = RequestMethod.POST)
    public String login(HttpSession session, RedirectModel redirectModel, @Valid User user, Errors error) {
    
        if (error.hasErrors()) {
            System.err.println(error.getAllErrors());
            redirectModel.attribute("msg", error.getAllErrors().toString());
            return "redirect:/login";
        }
    
        User login = userService.login(user);
        if (login == null) {
            redirectModel.attribute("userId", user.getUserId());
            redirectModel.attribute("msg", "登录失败");
            return "redirect:/login";
        }
        redirectModel.attribute("msg", "登录成功");
        session.setAttribute(USER_INFO, login);
        return "redirect:/user/info";
    }
    
}

文件下载,支持直接返回给浏览器图片

@RequestMapping(value = {"/download"}, method = RequestMethod.GET)
public File download(String path) {
    return new File(path);
}
@GET("/display")
public final BufferedImage display(HttpServletResponse response) throws IOException {
    response.setContentType("image/jpeg");
    return ImageIO.read(new File("D:/taketoday.cn/webapps/upload/logo.png"));
}

@GET("captcha")
public final BufferedImage captcha(HttpServletRequest request) throws IOException {
    BufferedImage image = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, BufferedImage.TYPE_INT_RGB);
    Graphics graphics = image.getGraphics();
    graphics.setColor(Color.WHITE);
    graphics.fillRect(0, 0, IMG_WIDTH, IMG_HEIGHT);
    Graphics2D graphics2d = (Graphics2D) graphics;
    drawRandomNum(graphics2d, request);
    return image;
}

文件上传,支持多文件

@RequestMapping(value = { "/upload" }, method = RequestMethod.POST)
public final String upload(@Multipart MultipartFile uploadFile) throws IOException {

    String upload = "D:/www.yhj.com/webapps/upload/";
    String path = upload + uploadFile.getFileName();
    File file = new File(path);
    uploadFile.save(file);

    return "/upload/" + uploadFile.getFileName();
}

@POST({"/upload/multi"})
public final String multiUpload(HttpServletResponse response, @Multipart MultipartFile[] files) throws IOException {

    String upload = "D:/www.yhj.com/webapps/upload/";
    
    for (MultipartFile multipartFile : files) {
        String path = upload + multipartFile.getFileName();
        File file = new File(path);
        System.out.println(path);
        if (!multipartFile.save(file)) {
            return "<script>alert('upload error !')</script>";
            //response.getWriter().print("<script>alert('upload error !')</script>");
        }
    }
    //response.getWriter().print("<script>alert('upload success !')</script>");
    return "<script>alert('upload success !')</script>";
}

🙏 鸣谢

本项目的诞生离不开以下开源项目:

  • Freemarker: Apache Freemarker
  • Slf4j: Simple Logging Facade for Java
  • Spring: Spring Framework
  • EL: Java Unified Expression Language
  • FastJSON: A fast JSON parser/generator for Java
  • Lombok: Very spicy additions to the Java programming language
  • Today Context: A Java library for dependency injection and aspect oriented programing
  • Hibernate Validator: Hibernate Validator - Bean Validation 2.0 (JSR 380) Reference Implementation

📄 开源协议

请查看 GNU GENERAL PUBLIC LICENSE

Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].