怎么设置httpservletrequest对象中的参数

怎么设置httpservletrequest对象中的参数,第1张

request之所以不想让你修改parameter的值,就是因为这个东西一般不然

改,有人问我为什么不让改,表面上说我只能说这属于篡改数据,因为这个使用户的请求数据,如果被篡改就相当于篡改消息,如果你一天给别人发消息发的是:你

好,而对方收到的是:fuck you!,你会怎么想,呵呵!当然它主要是怕不安全把参数数据该乱了,因为程序员

毕竟是自己写程序,尤其是在公共程序里面写,后台程序员发现自己的数据不对,也找不到原因;一般WEB应用会提供一个attribute来提供自己的参数

设置,这样就OK了,但是有些人就是那么变态说为啥就不能改呢,面向对象不是相互的么,有get应该有set的呀,我只能说,面向对象来自于生活现实,生

活现实中每天逛大街,街上有很多形形色色如花似玉的,但是又可能你只能看,不能摸,更不能XX,呵呵,否则一个异常就出来了:臭流氓!

呵呵,不过就技术的角度来讲,能实现吗,当然可以,没有不可以实现的,源码之下,了无秘密,这是一个大牛说的,那么我们先来思考下有那些实现的方式:

1、我自己new一个request,然后放到容器里头,放那呢?等会来说,先记录下。

2、如果我能改掉request里面的值,那就好了呗,好的,先记录下,等会来想怎么改。

先说第一种方式,我自己new一个,呵呵,怎么new,怎么让其他的程序知道。

new的两种方式之一(开始思考的起源):

先说new的方式,在不知道具体的容器怎么实现HttpSevletRequest的时候,很简单,我自己写个类,implements HttpServletRequest呵呵,这个貌似很简单,OK,继承下试一试:

public class HttpServletRequestExtend implements HttpServletRequest {

.......实现代码

}

此时提示需要有N多方法需要被实现,例如:

getParameter、getAttribute、getAttributeNames、getCharacterEncoding、getContentLength、getContentType。。。。。。

等等几十个方法,呵呵;

当然,你可以再构造方法里面将实际的request对象传递进来,如果是相同的方法,就这个request来实现,如果需要自己处理的方法,就按照自己的方式来处理,这种包装貌似简单

自己定义parameter,就用一个

private Map<String , String[]>paramterMap = new HashMap<String , String[]>()

就可以简单搞定,自己再搞个addParameter方法等等,就可以实现自己的功能。

不过写起来挺费劲的,因为意味着你所有的方法都要去实现下,除非你其他的方法都不用,只用其中几个方法而已,这就体现出一些接口的不足了。

但是这种方式是可行的,至少可以这样说,只是很费劲而已,因为感觉冗余很厉害,也体现出接口的不足,和抽象类的价值,我们想要的只是重载那些我们想要重载的,原有的还是按照它原有的处理思路,此时,有一个叫HttpServletRequestWrapper的出现了;

new方式2:

继承HttpServletRequestWrapper,其实就是上面那种方法多了一层继承,将你的重复工作交予了它,你也可以这样做,

全名

为:javax.servlet.http.HttpServletRequestWrapper,看来也是一个扩展的通用接口,也就是会对

request做一次包装,OK;跟着进去发现它可以处理类似request一样的差不多的内容,在这个基础上做了一次包装,你可以认为他就是对你自己

new的那个,多了一层简单扩展实现,而你再这个基础上,可以继续继承和重写。

OK,此时你要重写如何重写呢,比如我们要重写一个getParameter方法和

getParameterValues方法,其余的方法保持和原来一致,我们在子类中,自己定义一个Map用来放参数,结合request本身的参数,加

上外部其他自定义的参数,做成一个新的参数表。

如下所示:

import javax.servlet.http.HttpServletRequest

import javax.servlet.http.HttpServletRequestWrapper

import java.util.HashMap

import java.util.Map

public class ParameterRequestWrapper extends HttpServletRequestWrapper {

private Map<String , String[]>params = new HashMap<String, String[]>()

@SuppressWarnings("unchecked")

public ParameterRequestWrapper(HttpServletRequest request) {

// 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似

super(request)

//将参数表,赋予给当前的Map以便于持有request中的参数

this.params.putAll(request.getParameterMap())

}

//重载一个构造方法

public ParameterRequestWrapper(HttpServletRequest request , Map<String , Object>extendParams) {

this(request)

addAllParameters(extendObject)//这里将扩展参数写入参数表

}

@Override

public String getParameter(String name) {//重写getParameter,代表参数从当前类中的map获取

String[]values = params.get(name)

if(values == null || values.length == 0) {

return null

}

return values[0]

}

public String[] getParameterValues(String name) {//同上

return params.get(name)

}

public void addAllParameters(Map<String , Object>otherParams) {//增加多个参数

for(Map.Entry<String , Object>entry : otherParams.entrySet()) {

addParameter(entry.getKey() , entry.getValue())

}

}

public void addParameter(String name , Object value) {//增加参数

if(value != null) {

if(value instanceof String[]) {

params.put(name , (String[])value)

}else if(value instanceof String) {

params.put(name , new String[] {(String)value})

}else {

params.put(name , new String[] {String.valueOf(value)})

回答不容易,希望能帮到您,满意请帮忙采纳一下,谢谢 !

思路:通过过滤器针对某一类接口链接进行拦截,并调用HttpServletRequestWrapper 修改入参参数。具体如下

1.第一步骤自定义过滤器对具体方法过滤

2.第二步骤  自定义ChannelRequest 类 

重写  getParameterNames 方法添加需要增加的参数 ,重写getParameterNames 方法 对增加的参数初始化赋值

/**

* 动态添加渠道信息

* @author songfz

* @date 2019/7/9 10:34

*/

public class ChannelRequest  extends HttpServletRequestWrapper {

private static final LoggerLOG = LoggerFactory.getLogger(ChannelRequest.class)

private Stringtoken

private StringchannelId

private final ConsulPropsconsulProps = ApplicationContextHolder.getBean(ConsulProps.class)

public ChannelRequest(HttpServletRequest request) {

super(request)

token = request.getHeader(consulProps.getHeaderToken())

channelId = request.getParameter("channelId")

}

/**

* 重写 getParameterNames 添加需要的变量名称

    * @return

    */

    @Override

    public Enumeration getParameterNames() {

            Enumeration parameterNames =super.getParameterNames()

            ArrayList list = Collections.list(parameterNames)

            list.add("channelId")

            return Collections.enumeration(list)

    }

/**

* 重写 getParameterValues 对添加的变量赋值

    * @param name

    * @return

    */

    @Override

    public String[] getParameterValues(String name) {

//        判断当前用户管理员还是渠道用户

        if("channelId".equalsIgnoreCase(name) &&StringUtils.isEmpty(channelId)){

        ManagerTypeDto managerTypeDto =         ApplicationContextHolder.getBean(AuthService.class).getManagerChannelIdByToken(token)

        if(managerTypeDto.getType().equals(Manager.ManagerType.CHANNEL.name())){

                channelId = managerTypeDto.getCode()

                LOG.info("获取的渠道值:"+channelId)

                 return new String[]{channelId}

        }

    }

    return super.getParameterValues(name)

    }

}

//1. 获取请求方式、处理乱码问题

String method = request.getMethod()

//servletRequest中的方法

request.setCharacterEncoding("utf-8")

//1. 获取请求体的编码方式

String characterEncoding = request.getCharacterEncoding()

println("getCharacterEncoding = " + characterEncoding)

//2. get body length

int contentLength = request.getContentLength()

println("getContentLength = " + contentLength)

//3. MIME type

String mimeType = request.getContentType()

println("getContentType = " + mimeType)

//4. 接收请求的接口的 Internet Protocol (IP) 地址

String ip = request.getLocalAddr()

println("getLocalAddr = " + ip)

//5. 基于 Accept-Language 头,返回客户端将用来接受内容的首选 Locale 客户端语言环境

Locale locale = request.getLocale()

println("getLocale = " + locale)

//6. 所有的语言环境

Enumeration<Locale> locales = request.getLocales()

while(locales.hasMoreElements()){

Locale temp = locales.nextElement()

println("\n Locales = " + temp)

}

//7. 接收请求的 Internet Protocol (IP) 接口的主机名

String localName = request.getLocalName()

println("localName = " + localName)

//8. 接收请求的接口的 Internet Protocol (IP) 端口号

int localPort = request.getLocalPort()

println("localPort = " + localPort)

//9. 返回请求使用的协议的名称和版本

String protocol = request.getProtocol()

println("protocol = " + protocol)

//10. 读取请求正文信息

BufferedReader reader = request.getReader()

println("getReader = " + reader.toString())

//11. 发送请求的客户端

String remoteAddr = request.getRemoteAddr()

println("RemoteAddr = " + remoteAddr)

//12. 发送请求的客户主机

String remoteHost = request.getRemoteHost()

println("RemoteHost = " + remoteHost)

//13. 发送请求的客户主机端口

int remotePort = request.getRemotePort()

println("RemotePort = " + remotePort)

//14. 返回用于发出此请求的方案名称,例如:http 、 https 、 ftp

String scheme = request.getScheme()

println("Scheme = " + scheme)

//15. 返回请求被发送到的服务器的主机名。它是Host头值":"(如果有)之前的那部分的值。 或者解析服务器名称或服务器的IP地址

String serverName = request.getServerName()

println("ServerName = " + serverName)

//16. 返回请求被发送到的端口。他是"Host"头值":" (如果有)之后的那部分的值,或者接受客户端连接的服务器端口。

int serverPort = request.getServerPort()

println("ServerPort = " + serverPort)

//17. 返回一个boolean值,指示此请求是否是使用安全通道(比如HTTPS) 发出的。

boolean secure = request.isSecure()

println("isSecure = " + secure)

//以上方法为 ServletRequest 接口提供的

//以下方法为 HttpServletRequest 接口提供的

/*

* 18. 返回用于保护servlet的验证方法名称。 所有的servlet容器都支持

* basic、 form和client certificate验证, 并且可能还支持digest验证

*/

String authType = request.getAuthType()

println("authType = " + authType)

//19. getDateHeader ??

request.getDateHeader("")

//20. 返回请求头包含的所有头名称的枚举。

Enumeration<String> headerNames = request.getHeaderNames()

println("<hr/>")

while(headerNames.hasMoreElements()){

String name = headerNames.nextElement()

println(" headerNmea = " + name + " getHeader = " + request.getHeader(name))

}

println("<hr/>")

//21. 以int的形式返回指定请求头的值。 ???

request.getIntHeader("123")

//22. 返回与客户端发出此请求时发送的URL相关联的额外路径信息。

String pathInfo = request.getPathInfo()

println("PathInfo = " + pathInfo)

//23. 返回包含在请求RUL中路径后面的查询字符串。如果没有查询字符串返回null

String remoteUser = request.getRemoteUser()

println("RemoteUser = " + remoteUser)

//24. 返回客户端制定的回话ID

String requestedSessionId = request.getRequestedSessionId()

println("requestSessionId = " + requestedSessionId)

//25. 返回请求调用servlet的URL部分

String servletPath = request.getServletPath()

println("servletPath = " + servletPath)

//26. 返回与此请求关联的当前HttpSession,如果没有当前会话并且参数为true,则返回一个新会话。

HttpSession session = request.getSession(true)

println("getSession(true) = " + session)

//27. 返回包含当前已经过验证的用户的名称的java.security.Principal对象。如果用户没有经过验证,则该方法返回null

Principal userPrincipal = request.getUserPrincipal()

println("userPrincipal = " + userPrincipal)

//28. 检查会话的id是否作为Cook进入的

boolean sessionIdFromCookie = request.isRequestedSessionIdFromCookie()

println("sessionIdFromCookie = " + sessionIdFromCookie)

//29. 检查请求的会话ID是否作为请求的URL的一部分进入的

boolean sessionIdFromURL = request.isRequestedSessionIdFromURL()

println("sessionIdFormURL = " + sessionIdFromURL)

//30.

println("</ol>")

out.flush()

out.close()


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/bake/11464198.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-16
下一篇2023-05-16

发表评论

登录后才能评论

评论列表(0条)

    保存