您的位置:首页 > 运维架构 > Linux

Spring Boot + Java爬虫 + 部署到Linux(六、后端Controller实现、下载文件以及登录验证拦截器)

2018-06-30 20:02 791 查看

Controller就是控制层,就是mvc模式里面的c。控制前端页面的显示,以及向前端传递一些数据。这个就随便设置吧,没什么通用性。由于这个项目只有一个业务,所以主要界面也就一个,叫index。对应的Controller如下:

import java.net.InetAddress;
import java.net.UnknownHostException;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
public class IndexController {

private static final String MEMBER = "ipb_member_id";
private static final String PASS = "ipb_pass_hash";
@RequestMapping("/index")
public ModelAndView showIndexPage(HttpServletRequest req){

ModelAndView mav = new ModelAndView("index");
Cookie mCookie = CookieUtil.get(req, MEMBER);
Cookie pCookie = CookieUtil.get(req, PASS);
String cookie1 = mCookie.getValue();
String cookie2 = pCookie.getValue();
String localhost = null;
try {
InetAddress myIp = InetAddress.getLocalHost();
localhost = myIp.getHostAddress();  //获得你机器的ip,如果是169.254..,就修改host文件,加上一行
                 //“你的IP    myIp.getHostName()返回的你的名字”,如果只自己用,直接就直接设127.0.0.1
} catch (UnknownHostException e) {
e.printStackTrace();
}
if(localhost==null){
localhost = "127.0.0.1";
}
mav.getModel().put("cookie", "ipb_member_id:"+cookie1+";ipb_pass_hash:"+cookie2 ); //向前端传cookie数据。。。
mav.getModel().put("localhost", localhost);//传服务器ip地址数据。。。。
return mav;
}
@RequestMapping("/")
public String jump(){
return "redirect:index";  // 直接重定向到/index
}
@RequestMapping("/login")
public String login(){
return "login"; //像这种直接返回字符串的,其实应该是返回new Model("login"),再加上默认后缀.html就是login.html
}
        //登出
@RequestMapping("/logout")
public String logout(HttpServletRequest req, HttpServletResponse res){
Cookie member = CookieUtil.get(req, MEMBER);
Cookie pass = CookieUtil.get(req, PASS);
if(member!=null){
CookieUtil.set(res, MEMBER, null, 0);   //maxAge设成0,浏览器会直接删除该cookie
}
if(pass!=null){
CookieUtil.set(res, PASS, null, 0);
}

return "redirect:login";
}
@RequestMapping("/loginVerify")
public String loginVerify(String username, String password, HttpServletResponse res){
if(username==null || password==null){
return "redirect:login";
}
String[] info = eloginVerify(username, password);
final int maxAge = 3600*24*365; //cookie直接设一年,一劳永逸
if(info[0].equals("true")){

CookieUtil.set(res, MEMBER, info[1], maxAge);
CookieUtil.set(res, PASS, info[2], maxAge);

return "redirect:success";
}
return "redirect:login";
}
@RequestMapping("/success")
public String success(){
return "success";
}
public String[] eloginVerify(String name, String password){
return Login.eLogin(name, password); //这个就是第三节中的登录函数
}
}
CookieUtil就是对cookie的一些操作的封装,注意这个Cookie和httpclient的Cookie不一样。import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class CookieUtil {
/**
* 设置cookie
* @param response
* @param name
* @param value
* @param maxAge
*/
public static void set(HttpServletResponse response,
String name,
String value,
int maxAge){
Cookie cookie = new Cookie(name, value); //设置cookie的key和value值
cookie.setPath("/");        //路径
cookie.setMaxAge(maxAge);   //过期时间
response.addCookie(cookie); //添加cookie
}

/**
* 获取cookie
* @param request
* @param name
* @return
*/
public static Cookie get(HttpServletRequest request,
String name){
Map<String, Cookie> cookieMap = readCookieMap(request);
if(cookieMap.containsKey(name)){  //判断cookieMap是否含有该key
return cookieMap.get(name);
}else{
return null;
}

}

/**
* 将cookie封装成map
* @param request
* @return
*/
private static Map<String, Cookie> readCookieMap(HttpServletRequest request){
Map<String, Cookie> cookieMap = new HashMap<>();
Cookie[] cookies = request.getCookies();        //获取所有的cookie值
if(cookies != null){
for (Cookie cookie : cookies){
cookieMap.put(cookie.getName(),cookie);
}
}
return cookieMap;
}
}[/code]Controller下载文件的实现
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class DownloadController {
private static final String PATH = "images/zips/";
@RequestMapping("/download")
public void download(HttpServletResponse res, String title){  //传过来的参数名字和这个一定要一样,否则就注入不上了,title就是null了
String trueFileName = title + ".zip";
File f = new File(PATH+trueFileName);
if(!f.exists()){
try {
res.sendRedirect("/index");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}

res.setContentType("application/octet-stream");    // 设定内容类型为字节流,这样会触发浏览器的下载操作
res.setHeader("Content-Disposition", "attachment;filename=" + trueFileName);//这个就是下载的时候显示的名字
res.setContentLengthLong(f.length());
byte[] buff = new byte[2048];
BufferedInputStream bis = null;
OutputStream os = null;
try {
os = res.getOutputStream();
bis = new BufferedInputStream(new FileInputStream(f));
int i = bis.read(buff);
while (i != -1) {
os.write(buff, 0, buff.length);
os.flush();
i = bis.read(buff);
}
} catch (IOException e) {
//e.printStackTrace();浏览器强行关闭连接(打开下载工具等)
System.out.println("打开了下载工具!");
} finally {
if (bis != null) {
try {
bis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//System.out.println("success");

}

}
登录验证拦截器

拦截器是基于切面编程(AOP)的一个很好的例子。下面是如何在Spring boot里使用拦截器,来验证登录(根据请求的Cookie)。我们先定义一个拦截器的处理类,验证一下cookie:由于是验证操作,所以只需要在访问到目标前验证一下就完事了。所以只实现了preHandle方法。其实还有俩方法,可以点开父接口看看,这里不说了。

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

@Component
public class LoginInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
Cookie member = CookieUtil.get(request, "ipb_member_id");
Cookie pass = CookieUtil.get(request, "ipb_pass_hash");

if(member == null || pass == null){  //检查一下有没有这俩cookie
response.sendRedirect("/login"); //没有就跳转到登录页面
return false;  //false表示直接终止这个流程,就是说到此为止,不能访问目标。
}
return true; //true表示继续执行下一个拦截器或者目标
}

}
然后我们就直接配置一下我们的拦截器,把它添加到链上去。
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class MyWebMvcConfigurerAdapter implements WebMvcConfigurer {

@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new LoginInterceptor()).addPathPatterns("/index").addPathPatterns("/download");
//        .excludePathPatterns("/hlladmin/login") //登录页   这是排除方式
//        .excludePathPatterns("/hlladmin/user/sendEmail") //发送邮箱
//        .excludePathPatterns("/hlladmin/user/register") //用户注册
//        .excludePathPatterns("/hlladmin/user/login"); //用户登录

WebMvcConfigurer.super.addInterceptors(registry);
}

}
添加的时候,可以有两种方式,一种是添加你想拦截的,一种是去除你想不拦截的剩下的全都拦截。也可以搭配使用。像上述代码,就直接拦截了/index和/download,剩下的都不拦截。而第二种,一般是先add("/**")全拦截,再排除excludePathPatterns("/login")等。

    注意,使用第二种的时候,spring boot会拦截静态资源,所以要把静态资源拦截掉。

    千万不要出现死循环,比如把/login加到拦截的地址里,然而/login通不过验证,就自动跳转到/login,然后又被拦截,无限循环。


阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐