前言 大学刚毕业,专业是电子信息工程。大一开始学 Java,准确的说是高三最后的几周开始的. 果然兴趣是最好的老师, 在大一下学期自己从前端到后台写了我的个人网站:TODAY BLOG 。 从注册域名到备案再到网站成功上线,我遇到过的困难不计其数。因为感兴趣所以我坚持了下来。第一个版本使用的纯 Servlet 写的。后 ..

大学写的一个 Java Web 框架

前言

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

简介

today web 是一个基于Servlet的高性能轻量级 Web 框架。

安装

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

快速入门

第一步: 新建项目

新建项目

2.png

3.png

项目结构

项目结构

第二步:引入依赖

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

<dependency>
    <groupId>cn.taketoday</groupId>
    <artifactId>today-context</artifactId>
    <version>2.1.5.RELEASE</version>
</dependency>

<dependency>
    <groupId>org.freemarker</groupId>
    <artifactId>freemarker</artifactId>
    <version>2.3.28</version>
</dependency>

到此项目建立完毕,并不需要去管 web.xml 文件

第三步:配置控制器

/**
 * @author Today <br>
 *         2018-12-02 22:30
 */
@RestController
@RequestMapping("index")
public class IndexController {

    @GET("{key}")
    public String index(@PathVariable int key) {
    	return key + "";
    }
	
    @GET
    @ResponseBody(false)
    public String index() {
    	return "index";
    }
}

Freemarker模板

Freemarker模板

第四步:部署项目到 Tomcat

部署项目到Tomcat

查看效果

@GET("{key}")

7.png

@GET

8.png

案例

使用说明

通过 @Controller @RestController 配置控制器

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

配置请求

@GET("index")
@POST("post")
@PUT("articles/{id}")
......
@RequestMapping("/users/{id}")
@RequestMapping(value = "/users/**", method = {RequestMethod.GET})
@RequestMapping(value = "/users/*.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 </>;
}

自定义参数转换器

@Singleton
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.3.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,自定义视图
    }
    
    // @POST("login")
    @ResponseBody
    @RequestMapping(value = "/login" , method = RequestMethod.POST)
    public String login(@RequestParam(required = true) String userId, @RequestParam(required = true) String passwd) {
        // service...
        if(userId.equals(passwd)) {
            return "{\"msg\":\"登录成功\"}";
        }
        return "{\"msg\":\"登录失败\"}";//支持pojo转json
    }
}

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

@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>";
}

最后

自己非常喜欢编程,觉得写代码很有意思。
我觉得检验一项技术是否掌握就看是否能写一个出来。

GitHub

疯狂暗示 😋 :-P

  • Java

    Java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由 Sun Microsystems 公司于 1995 年 5 月推出的。Java 技术具有卓越的通用性、高效性、平台移植性和安全性。

    2265 引用 • 7658 回帖 • 933 关注
  • 开源

    Open Source, Open Mind, Open Sight, Open Future!

    241 引用 • 2544 回帖 • 912 关注
  • 黑客派

    黑客派是 B3log 开源社区的线上论坛,这里主要汇聚了程序员和设计师。HacPai 分别取 Hacker / Painter 的头三个字母组成,源自《黑客与画家》。

    我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

    更多细节请浏览黑客派简介

    312 引用 • 6407 回帖 • 698 关注
       
Today 在 2019-07-16 20:17:01 更新了该帖
Today 在 2019-07-16 20:20:25 更新了该帖
Today 在 2019-07-16 20:43:18 更新了该帖
8 回帖   
请输入回帖内容...
  • qvo 1 赞同

    请用外链图片,本地图片部署到码云上不会显示的

    1 回复
  • Today        

    这是个意外😄

  • hjljy  

    很 6

    1 回复
  • Today        

    😄 记得 star 哦🙏

  • sml  

    加油

    1 回复
  • maixiaojie  

    nice 6666

    1 回复
  • Today        

    🙏

  • Today        

    加油咯

请输入回帖内容 ...